在SSM(Spring + Spring MVC +Mybatis)項目中使用到Redis緩存,在網上查找了一些方法和文檔後總結出自己可用的一些配置如下:
1、pom.xml文件中引入需要的依賴
<!-- 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>
2、在spring配置文件中配置添加如下配置,配置文件中配置<!-- 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(需要緩存的對象)
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());
}
}
}
4、在對應spring配置文件中加入該文件的依賴
<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、運行的結果