Redis Spring配置(供参考!)
1添加redis自动操作配置
1可以通过设置相关类的mapper.xml加入<cache type="com.xxx.util.RedisCache"></cache>用来调用一个工具类并实现Cache接口,从而在实现业务SQL时,自动使用redis存入对应的SQL返回的内容,达到提高性能的效果
具体代码部分:
对应需要使用redis的mapperXML文件:
<?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.lzx.mapper.ClassesMapper" >
<cache type="com.lzx.util.RedisCache"></cache><!-- 这里 -->
<resultMap id="BaseResultMap" type="com.lzx.entity.Classes" >
<id column="cid" property="cid" jdbcType="INTEGER" />
<result column="classname" property="classname" jdbcType="VARCHAR" />
<result column="classaddress" property="classaddress" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List" >
cid, classname, classaddress
</sql>
<!-- 这里后面的省略。。-->
工具类
//工具类
@Component
public class RedisCache implements Cache {
private static JedisConnectionFactory jcf;
public void setJcf(JedisConnectionFactory jcf) {
RedisCache.jcf = jcf;
}
private String id;
private static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public RedisCache(String id) {
if (id == null) {
throw new IllegalArgumentException("id is null");
}
this.id = id;
}
public RedisCache() {
}
@Override
public String getId() {
return this.id;
}
@Override
public void putObject(Object key, Object value) {
JedisConnection connection = null;
try {
System.out.println("abc:"+jcf);
connection = jcf.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
connection.set(serializer.serialize(key), serializer.serialize(value));
connection.lPush(serializer.serialize(id),serializer.serialize(key));
System.out.println("写入缓存:" + key + "," + value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
}
@Override
public Object getObject(Object key) {
Object res = null;
JedisConnection connection = null;
try {
connection = jcf.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
res = serializer.deserialize(connection.get(serializer.serialize(key)));
if (res != null) {
System.out.println("获取缓存数据:" + res.toString());
} else {
System.out.println("当前没有缓存:" + key);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
return res;
}
@Override
public Object removeObject(Object key) {
Object res = null;
JedisConnection connection = null;
try {
connection = jcf.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
res = connection.expire(serializer.serialize(key), 0);
connection.lRem(serializer.serialize(id),0,serializer.serialize(key));
System.out.println("删除缓存:" + key);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
return res;
}
@Override
public void clear() {
JedisConnection connection = null;
try {
connection = jcf.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
// connection.flushDb();
// connection.flushAll();
Long length = connection.lLen(serializer.serialize(id));
if (0 == length) {
return;
}
List<byte[]> keys = connection.lRange(serializer.serialize(id),0,length-1);
for (byte[] key :keys) {
connection.expireAt(key,0);
System.out.println("删除缓存:"+serializer.deserialize(key).toString());
}
connection.expireAt(serializer.serialize(id),0);
keys.clear();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
}
@Override
public int getSize() {
int result = 0;
JedisConnection connection = null;
try {
connection = jcf.getConnection();
result = Integer.valueOf(connection.dbSize().toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
return result;
}
@Override
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
}
}
局限性:但仅仅用于小型项目中,若业务中需要不断修改查询数据,则redis起不到效果反而成为累赘。
这里就需要用到手动添加redis调用。也是普遍用的最多的方法。
2手动配置Redis缓存
a) 万事第一步,检查包pom.xml的依赖是否正确导入,这里是我使用到的依赖
<!-- redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- redis-spring -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.2.RELEASE</version>
</dependency>
b) 在Spring的配置文件applicationContext.xml中添加配置
<!-- redis配置 -->
<bean id="PoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="600"/>
<property name="maxIdle" value="300"/>
<property name="maxWaitMillis" value="1000"/>
<property name="testOnBorrow" value="true"/>
</bean>
<bean id="JedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="localhost"/>
<property name="port" value="6379"/>
<property name="password" value=""/>
<property name="poolConfig" ref="PoolConfig"/>
</bean>
<!-- 使用字符串进行序列化 -->
<bean id="StringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer">
</bean>
<!-- 使用JDK的序列化进行转化 -->
<bean id="JdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer">
</bean>
<!-- 配置Spring RedisTemplate -->
<bean id="RedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="JedisConnectionFactory"/>
<property name="keySerializer" ref="StringRedisSerializer"/>
<property name="valueSerializer" ref="JdkSerializationRedisSerializer"/>
</bean>
<!-- 注册Redis工具类 -->
<bean id="redisCeche" class="com.lzx.util.RedisCeche"></bean>
c) 创建对应工具类手动创建调用方法
<context:component-scan base-package="xxx"></context:component-scan>
因为注册了bean,注意使用@Componet,然后私有化一个RedisTemplate 类自动注入一个redisTemplate类(注意spring配置文件的包扫描,不然无法找到该bean)然后给setter redisTemplate方法,接着就是创建需要的关于Redis的set、get、delete等方法,具体看以下代码:
@Component
public class RedisCeche {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations<String, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
System.out.println("set data:"+key+","+value+" to redis");
result = true;
} catch (Exception e) {
System.out.println("set cache error");
}
return result;
}
public Object get(final String key) {
Object result = null;
try {
ValueOperations<String,Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
System.out.println("get data:"+key+" from redis");
}
catch (Exception e) {
System.out.println("get cache error");
// TODO: handle exception
}
return result;
}
// 通过key删除
public boolean deletebykey(final String key) {
boolean result = false;
try {
System.out.println("找关于 Key:"+key+"并删除,或者key本身不存在");
redisTemplate.delete(key);
if (get(key)==null) {
System.out.println("已删除 Key:"+key);
result = true;
}
} catch (Exception e) {
// TODO: handle exception
System.out.println("error delete by key from redis ,check your correct key!");
}
return result;
}
// 通过key的 模糊查询 并根据对应key批量删除
@SuppressWarnings("unused")
// @SuppressWarnings("unused") 表示该属性在方法或类中没有使用。添加此注解可以去除属性上的黄色警告!!!
public boolean deletebypattern(final String pattern) {
boolean result = false;
List<Object> strsList = new ArrayList<Object>();
try {
Set<String> keys = redisTemplate.keys(pattern);
if(keys.size()>0) {
redisTemplate.delete(keys);
for (String s : keys) {
strsList.add((Object) get(s));
}
}
if(strsList.size()==0) {
result = true;
System.out.println("Find keys pattern:"+pattern+"from redis and it has been deleted!");
}
} catch (Exception e) {
// TODO: handle exception
System.out.println("error delete by keypattern from redis ,check your correct pattern!");
}
return result;
}
}
(不仅仅这是这些还有的可以通过查看redisTemplate的源代码进行合理调用就可!,我的代码可能不完全最优,仅供参考!)
d) 然后就是实现与调用工具类的方法进行Redis的真正操作了
1 我这里就做了查询students所有的操作
我的Studentsservice interface 代码如下:
public interface StudentService {
public List<Students> getAllstu();
public void dropdatafromRedisbykey(String key);
public void dropdatafromRedisbyPattern(String Pattern);
}
2 然后在StudentServiceImpl文件中如下操作:(这里用到applicationContext.xml中注册的Bean,因此用来自动注入方便使用)
<!-- 注册Redis工具类 -->
<bean id="redisCeche" class="com.lzx.util.RedisCeche"></bean>
@Service
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED,noRollbackFor = Exception.class)
public class StudentsImpl implements StudentService {
@Autowired
private StudentsMapper sm;
@Autowired
private RedisCeche rc;
@Override
public List<Students> getAllstu() {
List<Students> stuList = new ArrayList<Students>();
try {
stuList = (List<Students>) rc.get("stu");
} catch (Exception e) {
// TODO: handle exception
System.out.println("error get from redis!");
}
if(stuList==null) {
stuList = sm.selectAll();
rc.set("stu", stuList);
}
return stuList;
// TODO Auto-generated method stub
}
@Override
public void dropdatafromRedisbykey(String key) {
// TODO Auto-generated method stub
rc.deletebykey(key);
}
@Override
public void dropdatafromRedisbyPattern(String Pattern) {
// TODO Auto-generated method stub
rc.deletebypattern(Pattern);
}
}
e) 然后回到StudentController中,调用service的实现方法,我这里使用了Resetful风格的url以及,使用json的格式返回前端(具体需要配置xml以即maven依赖),我没有使用视图返回,我使用了postman测试可行!
@Controller
public class StudentsController{
@Autowired
private StudentService studentService;
Map<String, Object> map = new HashMap<String, Object>();
@GetMapping(value = "/Student/getall")
@ResponseBody
public Object getall() {
map.clear();
List<Students> stulist= studentService.getAllstu();
map.put("stulist", stulist);
return map;
}
@PostMapping(value ="/Student/dropredisbykey/{key}")
@ResponseBody
public Object dodrop(@PathVariable(name = "key") String key) {
map.clear();
studentService.dropdatafromRedisbykey(key);
map.put("dropkey", key);
return map;
}
@PostMapping(value ="/Student/dropredisbypattern/{pattern}")
@ResponseBody
public Object dodrops(@PathVariable(name = "pattern") String pattern) {
map.clear();
studentService.dropdatafromRedisbyPattern(pattern);
map.put("dropkeys", pattern);
return map;
}
}
f) 测试结果:
1 首先测试删除功能,先cmd运行,开启Redis服务,添加测试数据
2 其次,使用postman 测试pattern
使用postman 测试key
使用postman 测试业务逻辑,调用redis作为缓存使用
大致原理是:从数据库中获得数据,然后存入redis中,第二次使用时,先去redis查询有没有此key,若无则从数据库查询,再存入redis,
注意请求方式是post 还是get。
到此,完成基本的手动添加redis缓存写入的方法,用于记录学习过程,希望对大家有帮助!