ssm的简单实现以及配置ehcache

前两天没什么事重新搭建了一下ssm,报错报了好几个小时也是醉了,还好最终钻出死胡同出来了,一个小地方弄错了,所以现在看来最简单的原理一定要理解的最透,不然死都不知道怎么死的,然后配置了一下ehcache,又因为一个错误查了好久,前两天我一定是没吃饱饭。。。


对于ssm框架一定要理解其原理,spring,springmvc,mybatis分别的作用以及集体的运行原理,一半天也要总结一下,先来搭一下


先配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>ssm基本数据库查询</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>springMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:*-servlet.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springMVC</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
<!-- 监听器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
</web-app>

用户向服务器发送请求,请求被Spring前端控制器ServletDispatcherServlet捕获,对其进行解析,得到请求资源标识符(URI),然后调用映射处理器HandlerMapping获得所有相关的对象,包括拦截器等<param-value>classpath:*-servlet.xml</param-value>,最后以HandlerExecutionChain对象的形式返回
DispatcherServlet根据获得的Handler,选择一个合适的处理器适配器HandlerAdapter。执行相应的Controller,执行完向DispatcherServlet返回一个ModelAndView对象;根据返回的ModelAndView,选择一个适合的视图解析器 ViewResolver,ViewResolver结合Model和View,来渲染视图将渲染结果返回给客户端
这是springMVC-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                                                http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                                                http://www.springframework.org/schema/mvc
                                                http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
                                                http://www.springframework.org/schema/context
                                                http://www.springframework.org/schema/context/spring-context-3.2.xsd
                                                ">
        <!--注解扫描-->
        <context:component-scan base-package="com.game" />
        
        <!-- 视图解析器 -->
        <bean id="jspViewResolver"
                class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/jsp/" />
                <property name="suffix" value=".jsp" />
        </bean>
</beans>


这是controller

package com.game.mj.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.game.mj.service.AdminService;

@Controller
@RequestMapping("/admin")
public class AdminController {
        
        @RequestMapping("/login.do")
        public String login(){
                
                return "index";
        }
}

请求入口login.jsp,跳到index.jsp
<a href="../admin/login.do">login</a>
下面整合spring和mybatis,web.xml请求到classpath:applicationContext.xml ,见下面
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.2.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
       
  
        <!-- 数据源 -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
                <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
                <property name="url" value="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=" />
                <property name="username" value="" />
                <property name="password" value="" />
                <!-- 初始化连接大小 -->
                <property name="initialSize" value="0"></property>
                <!-- 连接池最大数量 -->
                <property name="maxActive" value="20"></property>
                <!-- 连接池最大空闲 -->
                <property name="maxIdle" value="20"></property>
                <!-- 连接池最小空闲 -->
                <property name="minIdle" value="1"></property>
                <!-- 获取连接最大等待时间 -->
                <property name="maxWait" value="60000"></property>
        </bean> 

        <!-- sessionFactory 将spring和mybatis整合 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
                <property name="dataSource" ref="dataSource" />
                <property name="configLocation" value="classpath:mybatis-config.xml" />
                <property name="mapperLocations" value="classpath:mapper/*.xml" />    <!-- 加载mapper文件 -->
        </bean>
        
        <!-- dao mapping接口扫描 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                <property name="basePackage" value="com.game.*.dao" />
                <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        </bean>        
        <!-- 事务 -->
        <bean id="txManager"
                class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource" />
        </bean>
        <tx:advice id="txAdvice" transaction-manager="txManager">
                <tx:attributes>
                        <tx:method name="insert*" propagation="REQUIRED" />
                        <tx:method name="update*" propagation="REQUIRED" />
                        <tx:method name="delete*" propagation="REQUIRED" />
                        <tx:method name="create*" propagation="REQUIRED" />
                        <tx:method name="find*" propagation="REQUIRED" read-only="true" />
                        <tx:method name="get*" propagation="REQUIRED" read-only="true" />
                </tx:attributes>
        </tx:advice>
        <aop:config>
                <aop:pointcut expression="execution(* com.game.*.service.*.*(..))"
                        id="pointCut" />
                <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut" />
        </aop:config>
</beans>

通过sqlsessionfactory链接数据库,扫描接口,加载mybatis-config.xml和mapper/*.xml,
这是mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- mybatis配置 cacheEnabled若不配置ehcache则为false,这里为true-->
        <settings>
                <setting name="cacheEnabled" value="true" />
                <setting name="lazyLoadingEnabled" value="false" />
                <setting name="multipleResultSetsEnabled" value="true" />
                <setting name="useColumnLabel" value="true" />
                <setting name="useGeneratedKeys" value="true" />
                <setting name="defaultExecutorType" value="SIMPLE" />
        </settings>
        <!-- 配置别名 可用别名代替配置文件中parameterType resultType -->
        <typeAliases>
                <typeAlias type="com.game.mj.vo.Users" alias="Users"/>
        </typeAliases>

</configuration>

下面给出SpringMVC请求数据库,

public interface AdminService {
        String messageSelect(int userID);
}
@Service
public class AdminServiceImp implements AdminService{
        @Autowired private AdminMapper adminDao;
        
        @Override
        
        public String messageSelect(int userID) {
                System.out.println("service");
                return adminDao.messageSelect(userID);
        }

}
@SuppressWarnings("serial")
public class Users implements Serializable {
        private String username;
        private int userID;
        public String getUsername() {
                return username;
        }

        public void setUsername(String username) {
                this.username = username;
        }

        public int getUserID() {
                return userID;
        }

        public void setUserID(int userID) {
                this.userID = userID;
        }
        
}

mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.game.mj.dao.AdminMapper">

        <select id="messageSelect" resultType="java.lang.String" parameterType="java.lang.Integer">
                select Username from Base_Users where UserID=#{userID};
        </select>
</mapper>

上面呢,是纯正的ssm连接数据库,话说楼上装修吵的我脑袋疼。。。下面再说配置ehcache
首先配置ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="ehcache.xsd">
        <diskStore path="D:/cache" />
        <defaultCache maxElementsInMemory="10000"
                maxElementsOnDisk="1000" eternal="false" overflowToDisk="true"
                timeToIdleSeconds="300" timeToLiveSeconds="600" maxEntriesLocalHeap="10000"
                maxEntriesLocalDisk="10000000" />

        <!-- <cache name="tplCache" maxElementsInMemory="100" eternal="true"
                overflowToDisk="false" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
                diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
                memoryStoreEvictionPolicy="LRU" statistics="false" />
        <cache name="dataConfigCache" maxElementsInMemory="10000"
                timeToIdleSeconds="300" eternal="false" overflowToDisk="false"
                diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
                diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
                memoryStoreEvictionPolicy="LRU" statistics="false" />
        缓存3小时
        <cache name="threeHourCache" maxElementsInMemory="100"
                timeToLiveSeconds="10800" eternal="false" overflowToDisk="false"
                diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
                diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
                memoryStoreEvictionPolicy="LRU" statistics="false" clearOnFlush="true" />
        缓存1小时
        <cache name="oneHourCache" maxElementsInMemory="100"
                timeToLiveSeconds="3600" eternal="false" overflowToDisk="false"
                diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
                diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
                memoryStoreEvictionPolicy="LRU" statistics="false" clearOnFlush="true" />
        缓存5分钟 -->
        <cache name="fiveMinsCache" maxElementsInMemory="10000"
                timeToLiveSeconds="300" eternal="false" overflowToDisk="false"
                diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
                diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
                memoryStoreEvictionPolicy="LRU" statistics="false" clearOnFlush="true" />
                
        <!--
    <diskStore>==========当内存缓存中对象数量超过maxElementsInMemory时,将缓存对象写到磁盘缓存中(需对象实现序列化接口) 
    
    <diskStore path="">==用来配置磁盘缓存使用的物理路径,Ehcache磁盘缓存使用的文件后缀名是*.data和*.index name=================缓存名称,cache的唯一标识(ehcache会把这个cache放到HashMap里) 
    
    maxElementsOnDisk====磁盘缓存中最多可以存放的元素数量,0表示无穷大 maxElementsInMemory==内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两种情况 :
        1)若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中 
        2)若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素 
        
    eternal==============缓存中对象是否永久有效,即是否永驻内存,true时将忽略timeToIdleSeconds和timeToLiveSeconds 
    
    timeToIdleSeconds====缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,此为可选属性 
        即访问这个cache中元素的最大间隔时间,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除 
    
    timeToLiveSeconds====缓存数据在失效前的允许存活时间(单位:秒),仅当eternal=false时使用,默认值是0表示可存活时间无穷大 
        即Cache中的某元素从创建到清楚的生存时间,也就是说从创建开始计时,当超过这个时间时,此元素将从Cache中清除 
        
    overflowToDisk=======内存不足时,是否启用磁盘缓存(即内存中对象数量达到maxElementsInMemory时,Ehcache会将对象写到磁盘中) 
        会根据标签中path值查找对应的属性值,写入磁盘的文件会放在path文件夹下,文件的名称是cache的名称,后缀名是data 
        
    diskPersistent=======是否持久化磁盘缓存,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名为cache名称,后缀名为index的文件  
                     这个文件中存放了已经持久化在磁盘中的cache的index,找到后会把cache加载到内存  
                     要想把cache真正持久化到磁盘,写程序时注意执行net.sf.ehcache.Cache.put(Element element)后要调用flush()方法  
 
    diskExpiryThreadIntervalSeconds==磁盘缓存的清理线程运行间隔,默认是120秒  
    
    diskSpoolBufferSizeMB============设置DiskStore(磁盘缓存)的缓存区大小,默认是30MB  
    
    memoryStoreEvictionPolicy========内存存储与释放策略,即达到maxElementsInMemory限制时,Ehcache会根据指定策略清理内存  
                     共有三种策略,分别为LRU(最近最少使用)、LFU(最常用的)、FIFO(先进先出)  
-->
</ehcache>

这是applicationContext-ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="  
           http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
           http://www.springframework.org/schema/aop  
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/cache 
           http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">

<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:ehcache.xml" />
    <property name="shared" value="true"/>
</bean>

<!-- 开启spring缓存 -->
    <cache:annotation-driven cache-manager="cacheManager" />  
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">  
        <property name="cacheManager" ref="ehCacheManager"></property>  
    </bean>  
</beans>

**mybatis-config.xml中的配置<setting name="cacheEnabled" value="true" />
**然后把applicationContext-ehcache.xml注入到springMVC中<import resource="classpath:applicationContext-ehcache.xml"/>
**然后再AdminMapper.xml中加入<cache type="org.mybatis.caches.ehcache.LoggingEhcache" /> 可以输入日志,
或者<cache type="org.mybatis.caches.ehcache.EhcacheCache" />都可以
**最后注解一下,在AdminServiceImp中方法上面加入@Cacheable(value = { "fiveMinsCache" }),value中的值是ehcache.xml中的name名
这样就配置完了,我已经在AdminServiceImp中加入log看运行结果如下:


第一次运行时service和木头蝈蝈,第二次从注解中知道有缓存直接取出没有执行service说明成功了
此外还有@CacheEvict和@CachePut
@CacheEvict注解定义了相关方法负责从给定的缓存存储器中移除某些缓存值。虽然大多数的缓存框架都提供了缓存数据的有效时间,但是使用这个注解可以立即显式地从缓存存储器中删除过时的数据。这个注解通常用于在执行删除操作时使用
通俗来讲,@CachePut有两个功能:

如果缓存存储器中已经有某个key的缓存了,那么在执行完标注了@CachePut注解的方法后,将会更新缓存存储器中这个key的缓存
如果缓存存储器中没有某个key的缓存,那么在执行完标注了@CachePut注解的方法后,将会在缓存存储器中使用这个方法的返回值来添加上这个key的缓存

在配置期间我有一个疑问:就是本来传过去的是userID,java.lang.Integer,这样是好使的,但是如果我用实体类Users传userID,那么二级缓存本地显示的sql语句的userID是?,这样是无法从缓存中正确读取的你看下面,有哪位朋友知道这是哪的问题留言告知谢谢了


这是我的demo下载地址:ssm-ehcache-demo





发布了45 篇原创文章 · 获赞 44 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/Goligory/article/details/77837480