目录
1.配置缓存redis
1.1.启用缓存
package com.zyf.springTrans.rediscache.config;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching //启用缓存
public class RedisCacheConfig {
}
1.2.springboot配置
#---------------------------------------------------redis 部分 开始---------------------------------
#redis配置连接池属性
spring.redis.jedis.pool.min-idle=5
spring.redis.jedis.pool.max-active=10
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.max-wait=2000
#redis配置服务器属性
spring.redis.port=6379
spring.redis.host=localhost
spring.redis.password=123456
#redis配置连接超时,毫秒
spring.redis.timeout=2000
#---------------------------------------------------redis 部分 结束---------------------------------
#---------------------------------------------------redis缓存 部分 开始------------------------------
#数据库的基本配置
spring.datasource.url=jdbc:mysql://localhost:3306/SpringBootLearn?serverTimezone=UTC&useUnicode=yes&characterEncoding=utf8
spring.datasource.username=springdb
spring.datasource.password=springdb
#--------------连接池配置dbcp2 start --------------#
#数据库连接池类型= dbcp2(不配置则默认使用HikariCP)
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
#池中保持空闲的最大连接数,超出设置值之外的空闲连接将被回收,如设置为负数,则不限制
spring.datasource.dbcp2.max-idle=10
#池中同时被分配的有效连接数的最大值,如设置为负数,则不限制
spring.datasource.dbcp2.max-total=50
#池在抛出异常前等待的一个连接被归还的最大毫秒数,设置为-1则等待时间不确定
spring.datasource.dbcp2.max-wait-millis=10000
#池被启动时初始化的创建的连接个数
spring.datasource.dbcp2.initial-size=5
#--------------连接池配置dbcp2 end --------------#
#--------------mybatis配置 start --------------#
logging.level.root=DEBUG
logging.level.org.springframework=DEBUG
logging.level.org.org.mybatis=DEBUG
#--------------mybatis配置 end --------------#
#--------------redis缓存配置 end --------------#
#缓存类型
spring.cache.type=REDIS
#缓存名称
spring.cache.cache-name=rediscache01
#--------------redis缓存配置 start --------------#
#---------------------------------------------------redis缓存 部分 结束------------------------------
重点在于redis缓存配置部分,给spring增加缓存类型为REDIS,spring也是可以用其他缓存的,此处我们使用redis。
给缓存增加一个缓存名称为rediscache01,改名称会放在key的开头,如下图:
2.操作redis
2.1.pojo代码
定义一个用户类User,必须实现Serializable,否则将user数据存入到redis会报错。
package com.zyf.springTrans.rediscache.pojo;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1682049189405672046L;
private int id;
private String name;
private int sex;
private String note;
// setters and getters......
}
2.2.dao层代码
<?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.zyf.springTrans.rediscache.dao.UserMapper">
<select id="getUserById" parameterType="int"
resultType="com.zyf.springTrans.rediscache.pojo.User">
select id, name, sex, note from t_user where id = #{id}
</select>
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id"
parameterType="com.zyf.springTrans.rediscache.pojo.User">
insert into t_user (name,sex,note) value (#{name},#{sex},#{note})
</insert>
<update id="updateUser" parameterType="com.zyf.springTrans.rediscache.pojo.User">
update t_user
set name = #{name},sex = #{sex},note = #{note}
where id = #{id}
</update>
<delete id="deleteUserById" parameterType="int">
delete from t_user where id = #{id}
</delete>
</mapper>
package com.zyf.springTrans.rediscache.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.zyf.springTrans.rediscache.pojo.User;
@Repository
public interface UserMapper {
User getUserById(int id);
int insertUser(User user);
int updateUser(User user);
// List<User> getUsers(User user);
int deleteUserById(int id);
}
2.3.sevice层代码
package com.zyf.springTrans.rediscache.servcie;
import java.util.List;
import com.zyf.springTrans.rediscache.pojo.User;
public interface UserServcie {
User getUserById(int id);
User insertUser(User user);
User updateUser(User user);
List<User> getUsers(User user);
int deleteUserById(int id);
}
package com.zyf.springTrans.rediscache.servcie;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.zyf.springTrans.rediscache.dao.UserMapper;
import com.zyf.springTrans.rediscache.pojo.User;
/** 缓存注解操作redis */
@Service
public class UserServcieImpl implements UserServcie {
@Autowired
private UserMapper userMapper;
/**
* 查询用户
* 优先从redis缓存查,如果查不到,再执行mybatis查询,且将查询结果存入到redis缓存
*/
@Override
@Cacheable(value = "rediscache01", key = "'redis_user_'+#id") // value=缓存名称
public User getUserById(int id) {
System.out.println("执行mybatis代码查询用户id=" + id);
return userMapper.getUserById(id);
}
/**
* 插入用户
* 存入缓存
*/
@Override
@CachePut(value = "rediscache01", key = "'redis_user_'+#result.id")
public User insertUser(User user) {
int in = userMapper.insertUser(user);
System.out.println("执行mybatis代码存入用户"+in+"个,id=" + user.getId());
return user;
}
/**
* 更新用户
* 存入缓存,存入的前提条件是user不为null
*/
@Override
@CachePut(value = "rediscache01", key = "'redis_user_'+#result.id", condition = "#result != 'null'")
public User updateUser(User user) {
int in = userMapper.updateUser(user);
System.out.println("执行mybatis代码更新用户"+in+"个,id=" + user.getId());
return user;
}
/**
* 删除用户
* 移除缓存,beforeInvocation表示是否在方法前移除,默认为false
*/
@Override
@CacheEvict(value = "rediscache01", key = "'redis_user_'+#id", beforeInvocation = false)
public int deleteUserById(int id) {
int in = userMapper.deleteUserById(id);
return in;
}
@Override
public List<User> getUsers(User user) {
return null;
}
}
- @Cacheable:先从缓存查询数据,如果没查到,再执行方法内的逻辑(mybatis查询)。value标识使用的缓存名称,在spring配置文件有配置。key表示在缓存中使用的key,此处使用el表达式,获取参数id组装key。
- @CachePut:将方法返回结果存入或更新到缓存中。condition表示满足其表达式的条件则执行存入缓存的操作。
- @CacheEvict:将数据从缓存中移除。beforeInvocation默认为false,标识在方法执行后移除缓存。
2.4.junit测试代码
2.4.1.测试@Cacheable【查询】
首先缓存没有数据:
第一次执行查询逻辑,查询id=5的用户:
@Autowired
UserServcie userServcie;
@Test
public void getUserById() {
System.out.println("=================== 测试 userServcie.getUserById() 开始=======================");
Long start = System.currentTimeMillis();
System.out.println("查询用户:"+userServcie.getUserById(5));
Long end = System.currentTimeMillis();
System.out.println("耗时="+(end - start));
System.out.println("=================== 测试 userServcie.getUserById() 结束=======================");
}
日志:
=================== 测试 userServcie.getUserById() 开始=======================
执行mybatis代码查询用户id=5
查询用户:id=5,name=redis1,sex=3,note=redis缓存测试...更新缓存...
耗时=819
=================== 测试 userServcie.getUserById() 结束=======================
说明执行了方法体的逻辑。
redis:
顺利将数据存入到缓存中。
第二次执行查询逻辑,查询id=5的用户,日志:
=================== 测试 userServcie.getUserById() 开始=======================
查询用户:id=5,name=redis1,sex=3,note=redis缓存测试...更新缓存...
耗时=100
=================== 测试 userServcie.getUserById() 结束=======================
小结:
第一次查询,经过mybatis查询,即执行了查询方法,并且将查询结果存入到缓存中。
第二次查询,没有执行mybatis查询方法,直接从缓存获取数据。且从缓存中查询耗时明显较少。
2.4.2.测试@CachePut【更新】
2.4.2.1.新增数据:
@Test
public void insertUser() {
User user = new User();
user.setName("redis1");
user.setNote("redis缓存测试。。。");
user.setSex(3);
System.out.println("=================== 测试 userServcie.insertUser() 开始=======================");
System.out.println("存入用户:"+userServcie.insertUser(user));
System.out.println("=================== 测试 userServcie.insertUser() 结束=======================");
}
日志:
=================== 测试 userServcie.insertUser() 开始=======================
执行mybatis代码存入用户1个,id=14
存入用户:id=14,name=redis1,sex=3,note=redis缓存测试。。。
=================== 测试 userServcie.insertUser() 结束=======================
redis,成功存入缓存数据:
2.4.2.2.更新数据:
@Test
public void updateUser() {
User user = new User();
user.setId(14);
user.setName("redis14");
user.setNote("更新缓存14...");
user.setSex(14);
System.out.println("=================== 测试 userServcie.updateUser() 开始=======================");
System.out.println("更新用户:"+userServcie.updateUser(user));
System.out.println("=================== 测试 userServcie.updateUser() 结束=======================");
}
利用2.4.1的方法查询redis,看看缓存中数据:
=================== 测试 userServcie.getUserById() 开始=======================
查询用户:id=14,name=redis14,sex=14,note=更新缓存14...
耗时=91
=================== 测试 userServcie.getUserById() 结束=======================
日志表面上面数据是从缓存中查出的,且数据更新成功。
2.4.3.测试@CacheEvict【删除】
@Test
public void deleteUserById() {
System.out.println("=================== 测试 userServcie.deleteUserById() 开始=======================");
System.out.println("删除用户:"+userServcie.deleteUserById(14));
System.out.println("=================== 测试 userServcie.deleteUserById() 结束=======================");
}
利用2.4.1的方法查询redis,看看缓存中数据:
=================== 测试 userServcie.getUserById() 开始=======================
执行mybatis代码查询用户id=14
查询用户:null
耗时=794
=================== 测试 userServcie.getUserById() 结束=======================
说明在缓存中没有查询到数据,然后再执行方法内的逻辑查询,依旧没有查询到,删除缓存成功。
github:https://github.com/zhangyangfei/SpringBootLearn.git中的springRedis工程。