SSM(Spring + Spring MVC +Mybatis)的Redis快取,JedisPool配置
阿新 • • 發佈:2019-02-05
在SSM(Spring + Spring MVC +Mybatis)專案中使用到Redis快取,在網上查找了一些方法和文件後總結出自己可用的一些配置如下:
1、pom.xml檔案中引入需要的依賴
2、在spring配置檔案中配置新增如下配置,配置檔案中配置<!-- redis客戶端:jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.3</version> </dependency> <!-- 物件序列化依賴 --> <dependency> <groupId>com.dyuproject.protostuff</groupId> <artifactId>protostuff-core</artifactId> <version>1.0.8</version> </dependency> <dependency> <groupId>com.dyuproject.protostuff</groupId> <artifactId>protostuff-runtime </artifactId> <version>1.0.8</version> </dependency>
<!-- redis資料來源 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxTotal" value="${redis.maxActive}" /> <property name="maxWaitMillis" value="${redis.maxWait}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <!-- redis連線池 --> <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy" depends-on="poolConfig"> <constructor-arg name="poolConfig" ref="poolConfig" /> <!-- 載入jedisPool配置資訊 --> <constructor-arg name="host" value="${redis.host}" /><!-- redis主機地址 --> <constructor-arg name="port" value="${redis.port}"/> <!-- redis連線埠 --> <!-- <constructor-arg name="password" value="${redis.pass}"/> 密碼 --> <!--<constructor-arg name="database" value="${redis.database}"/> 資料庫 --> <!--<constructor-arg name="timeout" value="${redis.timeout}"/> 連線超時 --> </bean>
#redis快取配置
redis.host=你的地址
redis.port=你的埠
redis.pass=你的密碼
redis.database=2
redis.timeout=2000
#redis連線池配置
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
3、在DAO層中新建redis包,新建RedisApplicationsDao.java(需要快取的物件)
4、在對應spring配置檔案中加入該檔案的依賴package com.mvc.dao.redis; import com.dyuproject.protostuff.LinkedBuffer; import com.dyuproject.protostuff.ProtobufIOUtil; import com.dyuproject.protostuff.runtime.RuntimeSchema; import com.mvc.common.Config; import com.mvc.entity.Applications; import com.mvc.enums.SSOEnum; import com.mvc.exception.RedisException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import java.util.ArrayList; import java.util.List; /** * Created by yuyu on 2017/4/17. * 使用者快取使用者可作業系統的redis */ public class RedisApplicationsDao { //日誌記錄物件 private Logger logger = LoggerFactory.getLogger(this.getClass()); //redis連線池 @Autowired public JedisPool jedisPool; //將要序列化的類轉換成圖 private RuntimeSchema<Applications> schema = RuntimeSchema.createFrom(Applications.class); //根據使用者id獲取當前使用者可登入的系統 public List<Applications> getListApplications(String userId) throws Exception { //返回資料初始化 List<Applications> list=new ArrayList<Applications>(); try { //獲取redis操作物件 Jedis jedis = jedisPool.getResource(); try { //選擇redis的db2 jedis.select(2); //redis的key String key = "ListApplications:" + userId+":"; String keySize = "ListApplicationsSize:" + userId; //取得byte[]反序列取得相應的物件 //獲取list長度遍歷獲取list String listSize=jedis.get(keySize); if(null!=listSize){ int size=Integer.parseInt(listSize); if(size>0){ //獲取對應的例項物件 for(int x=0;x<size;x++){ byte[] bytes=jedis.get((key+x).getBytes()); //獲取快取,操作 if(null!=bytes){ //空物件 Applications applications=schema.newMessage(); //空物件被反序列 ProtobufIOUtil.mergeFrom(bytes,applications,schema); //新增返回list list.add(applications); }else{ //丟擲一個自定義的異常 throw new RedisException(SSOEnum.NOT_REDIS_EMPTY.getInfo()+key+x); } } }else{ //使用者配置為空 throw new RedisException(userId+SSOEnum.NOT_APP_CANT_USE.getInfo()); } }else{ throw new RedisException(SSOEnum.NOT_REDIS_EMPTY.getInfo()+keySize); } } finally { //關閉連線 jedis.close(); } } catch (Exception e) { //記錄錯誤日誌 logger.error(e.getMessage(), e); //redis。連線失敗,不用redis throw new RedisException(e.getMessage()); } return list; } //將資料庫生成的查詢快取到redis public void putListApplications(List<Applications> list,String userId) throws Exception{ //獲取list的長度儲存起來 try{ //獲取redis操作物件 Jedis jedis=jedisPool.getResource(); try { jedis.select(2); //redis的key String key = "ListApplications:" + userId + ":"; String keySize = "ListApplicationsSize:" + userId; //儲存list的長度 String back=jedis.setex(keySize,Config.REDIS_TIMEOUT,Integer.toString(list.size())); if("OK".equals(back)){ //儲存例項物件 int x=0; for(Applications data:list){ //將物件序列化 byte[] bytes=ProtobufIOUtil.toByteArray(data,schema, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE)); //儲存相應的資料 back=jedis.setex((key+x).getBytes(),Config.REDIS_TIMEOUT,bytes); //判斷是否成功 if(!"OK".equals(back)){ throw new RedisException(SSOEnum.NOT_REDIS_CACHE_ERROR.getInfo()+key+x); } x++; } }else{ throw new RedisException(SSOEnum.NOT_REDIS_CACHE_ERROR.getInfo()+keySize); } }finally { //關閉redis連線 jedis.close(); } }catch (Exception e){ //記錄錯誤資訊到日誌 logger.error(e.getMessage(),e); //redis。連線失敗,不用redis throw new RedisException(e.getMessage()); } } //根據查詢到的單條例項進行快取 public Applications getApplications(String id,String code)throws Exception{ try{ //獲取redis操作物件 Jedis jedis = jedisPool.getResource(); try { jedis.select(2); //設定去得的key String key="Applications:"+id+":"+code; //取得快取資訊 byte[] bytes=jedis.get(key.getBytes()); //判斷取得的資料 if(null!=bytes){ //新建空物件 Applications applications=schema.newMessage(); //取得快取物件 ProtobufIOUtil.mergeFrom(bytes,applications,schema); //返回物件 return applications; }else{ throw new RedisException(SSOEnum.NOT_REDIS_EMPTY.getInfo()+key); } }finally { jedis.close(); } }catch (Exception e){ //記錄錯誤資訊到日誌 logger.error(e.getMessage(),e); //redis。連線失敗,不用redis throw new RedisException(e.getMessage()); } } //獲取單條資料的快取 public void putApplications(Applications data,String id,String code)throws Exception{ try{ //獲取redis連線物件 Jedis jedis=jedisPool.getResource(); try{ //選擇資料庫 jedis.select(2); //建立key String key="Applications:"+id+":"+code; //將物件序列化 byte[] bytes=ProtobufIOUtil.toByteArray(data,schema, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE)); //將資料快取 String back=jedis.setex(key.getBytes(),Config.REDIS_TIMEOUT,bytes); //判斷是否快取成功 if(!"OK".equals(back)){ throw new RedisException(SSOEnum.NOT_REDIS_CACHE_ERROR.getInfo()+key); } }finally { //關閉redis連線 jedis.close(); } }catch (Exception e){ //將錯誤記錄日誌 logger.error(e.getMessage(),e); //redis。連線失敗,不用redis throw new RedisException(e.getMessage()); } } }
<bean id="redisApplicationsDao" class="com.mvc.dao.redis.RedisApplicationsDao"/>
5、建立單元測試類檢測當前的編碼是否可行
package com.mvc.dao.redis;
import com.mvc.dao.ApplicationsDAO;
import com.mvc.entity.Applications;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.util.List;
import static org.junit.Assert.*;
/**
* Created by yuyu on 2017/4/18.
*/
@RunWith(SpringJUnit4ClassRunner.class)
//告訴junit spring的配置檔案
@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class RedisApplicationsDaoTest {
@Autowired
public RedisApplicationsDao redisApplicationsDao;
@Autowired
public ApplicationsDAO applicationsDAO;
@Test
public void getListApplications() throws Exception {
List<Applications> list= redisApplicationsDao.getListApplications("3");
for(Applications data:list){
System.out.println(data);
}
}
@Test
public void putListApplications() throws Exception {
String id="3";
List<Applications> list=applicationsDAO.selectByUserid(id);
redisApplicationsDao.putListApplications(list,id);
}
@Test
public void putApplications() throws Exception {
String id="1";
String code="TEST";
Applications applications=applicationsDAO.selectByUserIdAndAppCode(id,code);
System.out.println(applications);
redisApplicationsDao.putApplications(applications,id,code);
}
@Test
public void getApplications() throws Exception {
String id="1";
String code="TEST";
Applications applications=redisApplicationsDao.getApplications(id,code);
System.out.println(applications);
}
}
6、執行的結果