使用Spring-data-redis框架 註解 集成spring與redis

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/qq_35180232/article/details/79999978

環境:項目採用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視圖工具查看




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章