使用Spring-data-redis框架 注解 集成spring与redis

环境:项目采用springMvc+spring4.25+hibernate5.08+Mysql 

目的:将Redis作为缓存数据库,具体Redis的优势网上都有,就不在赘述了。

1.所需jar包 

除了spring以及与hibnenate 相关的依赖包外  spring-data-redis-1.7.2.RELEASE.jar     jedis-2.9.0.jar

commons-pool2-2.5.0.jar redis配置线程池

2.配置文件

springMVC.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:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 启用spring mvc 注解 -->
    <!-- 扫描注解 -->
    <context:component-scan base-package="com.fh.panghu.controller"/>
   
    <mvc:annotation-driven  />  

    <bean id="mappingJacksonHttpMessageConverter"
        class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
            </list>
        </property>
        
    </bean>
    
    <!-- 静态资源(js/image)的访问 ,可添加多个-->
    <mvc:resources location="/views/images/" mapping="/views/images/**"/>
      <mvc:resources location="/views/js/" mapping="/views/js/**"/>  
      <mvc:resources location="/views/css/" mapping="/views/css/**"/>
    <!-- 定义跳转的文件的前后缀 ,视图模式配置 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 这里的配置自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/views/" />
        <property name="suffix" value=".html" />
    </bean>
    
    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.Throwable">error</prop>
            </props>
        </property>
    </bean>    

    <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->
    <bean name="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 默认编码 -->
        <property name="defaultEncoding" value="utf-8" />
        <!-- 文件大小最大值 -->
        <property name="maxUploadSize" value="10485760000" />
        <!-- 内存中的最大值 -->
        <property name="maxInMemorySize" value="40960" />
    </bean>

</beans>

springCore2.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:cache="http://www.springframework.org/schema/cache"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/task  
        http://www.springframework.org/schema/task/spring-task-4.0.xsd
        http://www.springframework.org/schema/cache
        http://www.springframework.org/schema/cache/spring-cache-4.0.xsd">     
    
    <context:component-scan base-package="com.fh.panghu.service" />
    <cache:annotation-driven />  
    
    
    <task:annotation-driven/>
    
    <context:annotation-config/>  
        <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>  
    <context:component-scan base-package="com.fh.panghu.schedule"/>
    
    <!-- 属性文件位置 -->
    <!-- 公共配置文件信息 -->
    <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">  
    <property name="locations">  
        <list>  
            <value>classpath:public.properties</value>  
        </list>  
    </property>  
    </bean>
    <!-- 读取数据库信息 -->
    <bean id="annotationPropertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
                <value>classpath:redis.properties</value>
            </list>
        </property>
    </bean>    
    <!-- 配置线程池 -->
    <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="5" />
        <property name="keepAliveSeconds" value="200" />
        <property name="maxPoolSize" value="10" />
        <property name="queueCapacity" value="20" />
        <property name="rejectedExecutionHandler">
        <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
        </property>
    </bean>
    
    <!-- 配置数据源 c3p0 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${jdbc.driver}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 请求超时时间 -->
        <property name="checkoutTimeout" value="30000" />
        <!-- 每60秒检查所有连接池中的空闲连接。默认值: 0,不检查 -->
        <property name="idleConnectionTestPeriod" value="30" />
        <!-- 连接数据库连接池最大空闲时间 -->
        <property name="maxIdleTime" value="30" />
        <!-- 连接池初始化连接数 -->
        <property name="initialPoolSize" value="5" />
        <property name="minPoolSize" value="5" />
        <property name="maxPoolSize" value="20" />
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。默认值: 3 -->
        <property name="acquireIncrement" value="5" />
    </bean>
    <!-- 配置hibernate的SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!-- 注入数据源 相关信息看源码 -->
        <property name="dataSource" ref="dataSource" />
        <!-- hibernate配置信息 -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <!-- 开启二级缓存 ehcache -->
                <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
                <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
                <prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
                <prop key="hibernate.cache.provider_configuration_file_resource_path">${hibernate.cache.provider_configuration_file_resource_path}
                </prop>
                <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
            </props>
        </property>
        <!-- 扫描hibernate注解配置的entity -->
         <property name="packagesToScan" value="com.fh.panghu.entity" />
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <tx:annotation-driven transaction-manager="transactionManager" />
    
    <!-- Spring aop事务管理 -->
    <aop:config proxy-target-class="true">    
        <aop:advisor pointcut="execution(* com.fh.panghu.service.*.*(..))" advice-ref="transactionAdvice" />
    </aop:config>
    
    <!-- 配置事务增强处理Bean,指定事务管理器 -->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
        <!-- 配置详细事务处理语义 -->
        <tx:attributes>            
            <tx:method name="query*" read-only="true" />
            <tx:method name="find*" read-only="true" />
            <tx:method name="load*" read-only="true" />
            <tx:method name="list*" read-only="true" />
            <tx:method name="save*"  propagation="REQUIRED" read-only="false" isolation="DEFAULT"/>
            <tx:method name="update*" propagation="REQUIRED" read-only="false" isolation="DEFAULT"/>
            <tx:method name="del*" propagation="REQUIRED"  read-only="false" isolation="DEFAULT"/>
            <tx:method name="create*" propagation="REQUIRED" read-only="false" isolation="DEFAULT"/>
            <tx:method name="*" rollback-for="Exception"/>                
        </tx:attributes>
    </tx:advice>
     <bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
       <property name="dataSource" ref="dataSource" />
    </bean>

    <bean name="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <!-- redis连接池配置-->    
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" >    
        <!--最大空闲数-->    
        <property name="maxIdle" value="${redis.maxIdle}" />  
        <!--连接池的最大数据库连接数  -->  
        <property name="maxTotal" value="${redis.maxTotal}" />  
        <!--最大建立连接等待时间-->    
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />    
        <!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)-->  
        <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" />   
        <!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3-->  
        <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" />   
        <!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1-->  
        <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" />   
        <!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->    
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />    
        <!--在空闲时检查有效性, 默认false  -->  
        <property name="testWhileIdle" value="${redis.testWhileIdle}" />    
    </bean >  
      
    <!--redis连接工厂 -->  
  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">   
        <property name="poolConfig" ref="jedisPoolConfig"></property>   
        <!--IP地址 -->  
        <property name="hostName" value="${redis.hostName}"></property>   
        <!--端口号  -->  
        <property name="port" value="${redis.port}"></property>   
        <!--如果Redis设置有密码  -->  
        <property name="password" value="${redis.password}" />  
        <!--客户端超时时间单位是毫秒  -->  
        <property name="timeout" value="${redis.timeout}"></property>   
    </bean>    
      
    <!--redis操作模版,使用该对象可以操作redis  -->  
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >    
        <property name="connectionFactory" ref="jedisConnectionFactory" />    
        <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->    
        <property name="keySerializer" >    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />    
        </property>    
        <property name="valueSerializer" >    
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />    
        </property>    
        <property name="hashKeySerializer">    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>    
        </property>    
        <property name="hashValueSerializer">    
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>    
        </property>    
        <!--开启事务  -->  
        <property name="enableTransactionSupport" value="true"></property>  
    </bean >    
      
<!-- 配置缓存 -->  
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">  
    <constructor-arg ref="redisTemplate" />  
</bean>  
 

</beans> 

redis.properties

redis.hostName=127.0.0.1  
redis.port=6379  
redis.password=  
redis.timeout=10000  
redis.maxIdle=300  
redis.maxTotal=1000  
redis.maxWaitMillis=1000  
redis.minEvictableIdleTimeMillis=300000  
redis.numTestsPerEvictionRun=1024  
redis.timeBetweenEvictionRunsMillis=30000  
redis.testOnBorrow=true  

redis.testWhileIdle=true

3.实现代码

RedisCacheUser.java 实体类 对应Mysql字段

@Entity
@Table(name="rediscacheuser")
public class RedisCacheUser {


    //用户ID
    private String redisuserid;
    //名字
    private String  redisusername;
    //密码
    private String  redispassword;    
    //ID
    private String  redisddid;
    //用户电话
    private String  redismobile;
    
    public RedisCacheUser(){        
    }

    @Id    
    public String getUserid() {
        return  redisuserid;
    }

    public void setUserid(String userid) {
        this. redisuserid = userid;
    }

    @Column(name="USERNAME",nullable=false,length=32)
    public String getUsername() {
        return  redisusername;
    }

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

    @Column(name="PASSWORD",nullable=false,length=64)
    public String getPassword() {
        return  redispassword;
    }

    public void setPassword(String password) {
        this. redispassword = password;
    }

    @Column(name="DDID",nullable=false,length=128)
    public String getDdid() {
        return  redisddid;
    }

    public void setDdid(String ddid) {
        this.redisddid = ddid;
    }

    @Column(name="MOBILE",length=32)
    public String getMobile() {
        return  redismobile;
    }

    public void setMobile(String mobile) {
        this.redismobile = mobile;
    }

    @Override
    public String toString() {
        return "RedisCacheUser [redisuserid=" + redisuserid + ", redisusername=" + redisusername + ", redispassword="
                + redispassword + ", redisddid=" + redisddid + ", redismobile=" + redismobile + ", getUserid()="
                + getUserid() + ", getUsername()=" + getUsername() + ", getPassword()=" + getPassword() + ", getDdid()="
                + getDdid() + ", getMobile()=" + getMobile() + ", getClass()=" + getClass() + ", hashCode()="
                + hashCode() + ", toString()=" + super.toString() + "]";
    }
       
}

RedisCacheTestService.java  BaseTxService 里面封装了hibernate操作 可以通过hibernateTemplate操作Mysql


@Service
public class RedisCacheTestService extends BaseTxService {
    
    @CachePut(key="#redisCacheUser.getUserid()",value="RedisCacheUser")
    public String addRedisCacheTestUser(RedisCacheUser redisCacheUser) {
        this.hibernateTemplate.save(redisCacheUser);
        return JSONObject.fromObject(redisCacheUser).toString();
    }
    @CachePut(key="#redisCacheUser.getUserid()",value="RedisCacheUser")
    public RedisCacheUser addRedisCacheTestUser1(RedisCacheUser redisCacheUser) {
        this.hibernateTemplate.save(redisCacheUser);
        return redisCacheUser;
    }
    /**
     * 根据userId查询对象  先从缓存 没有则再数据库
     * @param userId
     * @return
     */
    @Cacheable(key="#userId",value="RedisCacheUser")
    @SuppressWarnings("unchecked")
    public String  getRedisCacheUserByuserId(String userId) {
        
            String string = getRedisCacheUserByuserIdDB(userId);
            return string;
    }
    public String getRedisCacheUserByuserIdDB(String userId) {
        List <RedisCacheUser>  redisCacheUsers = new ArrayList <RedisCacheUser>() ;
        RedisCacheUser  redisCacheUser = new RedisCacheUser() ;
        redisCacheUsers =   (List<RedisCacheUser>) this.hibernateTemplate.find("from RedisCacheUser where userid = '" + userId + "'");
        if(redisCacheUsers.size()>0) {
            redisCacheUser = redisCacheUsers.get(0);
            return JSONObject.fromObject(redisCacheUser).toString();
        }
        return null;
    }
    /**
     * 根据userName模糊查询多个对象  先从缓存 没有则再数据库
     * @param userId
     * @return
     */
    /*@Cacheable(key="#username",value="RedisCacheUser")
    @SuppressWarnings("unchecked")*/
    public String  getRedisCacheUsers(String username) {
        
            String string = getRedisCacheUsersDB(username);
            return string;
    }
    public String getRedisCacheUsersDB(String username) {
        List <RedisCacheUser>  redisCacheUsers = new ArrayList <RedisCacheUser>() ;
        RedisCacheUser  redisCacheUser = new RedisCacheUser() ;
        redisCacheUsers =   (List<RedisCacheUser>) this.hibernateTemplate.find("from RedisCacheUser where username like '%" + username + "%'");
        if(redisCacheUsers.size()>0) {
            System.out.println("redisCacheUsers:"+redisCacheUsers);
            return JSONObject.fromObject(redisCacheUsers).toString();
            
        }
        return null;
    }
    /**
     * 根据userName模糊查询多个对象  先从缓存 没有则再数据库
     * @param username
     * @return List
     */
    /*@Cacheable(key="#username",value="RedisCacheUser")
    @SuppressWarnings("unchecked")*/
    public List<RedisCacheUser>  getRedisCacheUsers1(String username) {
        List <RedisCacheUser>  redisCacheUsers = new ArrayList <RedisCacheUser>() ;
        redisCacheUsers =   (List<RedisCacheUser>) this.hibernateTemplate.find("from RedisCacheUser where username like '%" + username + "%'");
        return redisCacheUsers;
    }
    /**
     * 根据userId删除对象
     * @param userId
     * @return
     */
    @CacheEvict(key="#redisCacheUser.getUserid()",value="RedisCacheUser")
    public Boolean deleteRedisCacheUserByuserId(RedisCacheUser redisCacheUser) {
        
        this.hibernateTemplate.delete(redisCacheUser);
        // TODO Auto-generated method stub
        return true;

    }

/**
     * 清空所有缓存  只是清除了Redis中的RedisCacheUser 但要删除数据库的需自己实现
     * @return
     */
    @CacheEvict(value="RedisCacheUser",allEntries=true)
    public void deleteRedisCacheUsers() {
        // TODO Auto-generated method stub
        
    }


}

RedisCacheTest.java  使用Junit4测试

/**
 * 测试redis缓存和Mysql的增删查改DEMO JUnit测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:springCore2.xml", "classpath:springMVC.xml" })
public class RedisCacheTest {
    
    @Autowired
    private RedisCacheTestService redisCacheTestService;
    /**
     * 新增一条对象 缓存Redis为String的
     */

    public void saveUser() {
        RedisCacheUser user= new RedisCacheUser();                    
        //构造数据
        user.setUserid("2");
        user.setDdid("1111");
        user.setMobile("183213123");
        user.setPassword("root");
        user.setUsername("root");    
        redisCacheTestService.addRedisCacheTestUser(user);
    }
    /**
     *根据ID获取String的
     */
    public void getUserById() {    
        RedisCacheUser user= new RedisCacheUser();    
        String string  = redisCacheTestService.getRedisCacheUserByuserId("13");
        if(Objects.equals(string, null)) {
            System.out.println("空空");
        }else {
            System.out.println(string);
        }
    }
    /**
     * 根据name 获取多个user string的
     */
    public void getUsers() {    
        RedisCacheUser user= new RedisCacheUser();    
        String string  = redisCacheTestService.getRedisCacheUsers("root");
        if(Objects.equals(string, null)) {
            System.out.println("空空");
        }else {
            System.out.println(string);
        }
    }
    /**
     * 新增一个缓存对象
     */
    public void saveUser1() {
        RedisCacheUser user= new RedisCacheUser();                    
        //构造数据
        user.setUserid("3");
        user.setDdid("1111");
        user.setMobile("183213123");
        user.setPassword("root");
        user.setUsername("root");
        
        redisCacheTestService.addRedisCacheTestUser1(user);
    }
    /**
     * 根据name返回对象List的
     */
    public void getUsers1() {    
        RedisCacheUser user= new RedisCacheUser();    
        List<RedisCacheUser>  redisCacheUsers= new ArrayList <RedisCacheUser>();
        redisCacheUsers  = redisCacheTestService.getRedisCacheUsers1("root");
    
        if(redisCacheUsers.size()>0) {
            System.out.println(JSONArray.fromObject(redisCacheUsers));
        }else {
            System.out.println("空空");
            
        }
    }
    /**
     * 删除Mysql数据库和Redis一个User对象
     */
    
    public void deleteUser() {    
        //ArrayList<Object>  redisCacheUsersObj = new ArrayList <Object>();
        RedisCacheUser user= new RedisCacheUser();            
    
        //构造数据
        user.setUserid("2");
        user.setDdid("1111");
        user.setMobile("183213123");
        user.setPassword("root");
        user.setUsername("root");
                
        redisCacheTestService.deleteRedisCacheUserByuserId(user);
    }
    /**
     * 清空Redis中所有的RedisCacheUser
     */
    @Test
    public void deleteUsers() {    
                
        redisCacheTestService.deleteRedisCacheUsers();
    }

}

使用Redis视图工具查看




猜你喜欢

转载自blog.csdn.net/qq_35180232/article/details/79999978