缓存在一个系统是非常有必要的,最简单的说法:当你查看一个用户信息的时候(例如查看个人资料),当频繁去查询(同一个用户资料)的时候,每次都去数据库查询的话这个查询是非常没必要的。
最好的做法就是第一次去数据库查询,查询结果集我们进行缓存,下一次/下几次查询的时候直接从以前查询出来的结果获取所需要的值,这样减少数据库查询对我们系统优化是非常大的(假设查询一次需要0.01秒,当很多人一起查询的时候这个数值就非常恐怖了)
案例:基于mybatis查询结果集使用redis作缓存处理
step 1:首先基于mybatis做数据库操作
@Repository
public interface InfoUserMapper {
//获取某个用户
InfoUser getInfoUser(int infoId);
//新增用户
int insertInfoUser(@Param("user")InfoUser user);
//修改用户
int updateInfoUser(@Param("user")InfoUser user);
// 删除用户
int deleteInfoUser(int infoId);
//根据用户名查询用户
List<InfoUser> findUserLikeName(@Param("userName")String userName);
}
具体的mapper操作
<select id="getInfoUser" resultType="infoUser">
select
info_id as
infoId,user_name as infoName,user_pwd as infoPwd,user_gender as sex
from infouser where
info_id=#{infoId}
</select>
<insert id="insertInfoUser" useGeneratedKeys="true" keyProperty="user.infoId"
parameterType="infoUser" >
insert into infouser(user_name,user_pwd,user_gender)
values(#{user.infoName},#{user.infoPwd},#{user.sex})
</insert>
<update id="updateInfoUser" parameterType="infoUser" >
update infouser
<set>
<if test="user.infoName!=null">user_name=#{user.infoName},</if>
<if test="user.infoPwd!=null">user_pwd=#{user.infoPwd}</if>
</set>
where info_id=#{user.infoId}
</update>
<delete id="deleteInfoUser">
delete from infouser where
info_id=#{infoId}
</delete>
<select id="findUserLikeName" resultType="infoUser">
select
info_id as infoId,user_name as infoName,user_pwd as
infoPwd,user_gender as sex from infouser
where user_name like
"%"#{userName}"%"
</select>
step 2: 配置redis连接以及缓存
application-redis.properties文件
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
spring.redis.port=6379
spring.redis.host=127.0.0.1
spring.redis.password=
spring.redis.timeout=1000
#缓存
spring.cache.type=REDIS
spring.cache.cache-names=redisCache
# 禁用前缀
spring.cache.redis.use-key-prefix=false
# 允许保存空值
#spring.cache.redis.cache-null-values=true
# 自定义前缀
#spring.cache.redis.key-prefix=
# 定义超时时间,单位毫秒
spring.cache.redis.time-to-live=500000
application.properties文件中
spring.profiles.include=redis
spring.datasource.url=jdbc:mysql://localhost:3306/myschool?useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=admin123
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mybatis.mapper-locations=classpath:com/action/myboot/mapper/*.xml
mybatis.type-aliases-package=com.action.myboot.pojo
mybatis.type-handlers-package=com.action.myboot.typeHandler
logging.level.com.action.myboot.mapper=debug
RedisConfig.java文件中
@Configuration
@EnableCaching // 开启注解
public class RedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
return stringRedisTemplate;
}
}
MybootApplication.java文件
@SpringBootApplication
@MapperScan("com.action.myboot.mapper")
@EnableCaching
public class MybootApplication {
@Resource(name="redisTemplate")
private RedisTemplate redisTemplate;
// 自定义初始化
@PostConstruct
public void init() {
initRedisTemplate();
}
// 改变RedisTemplate对于键的序列化策略
private void initRedisTemplate() {
RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
}
public static void main(String[] args) {
SpringApplication.run(MybootApplication.class, args);
}
}
这样我们就将基础搭建好了
step 3: 具体操作
主要在service中去操作一些东西
定义接口(前边mapper中已经对数据库做了操作)
public interface InfoUserService {
public InfoUser getInfoUser(int infoId);
InfoUser addInfoUser(InfoUser user); //返回值就是要操作的对象类型,不是写错了~!~!
InfoUser updateInfoUser(InfoUser user);
int deleteInfoUser(int infoId);
List<InfoUser> findUserLikeName(String userName);
}
具体操作接口InfoUserServiceImpl.java:
@Service("infoUserService")
public class InfoUserServiceImpl implements InfoUserService {
@Resource
private InfoUserMapper infoMapper;
@Override
@Transactional
@Cacheable(value="redisCache",key="'redis_user'+#infoId")
public InfoUser getInfoUser(int infoId) {
// TODO Auto-generated method stub
return infoMapper.getInfoUser(infoId);
}
@Override
@Transactional
@CachePut(value="redisCache",key="'redis_user'+#result.infoId")
public InfoUser addInfoUser(InfoUser user) {
infoMapper.insertInfoUser(user);
return user;
}
@Override
@CachePut(value="redisCache",condition="#result != 'null'", key = "'redis_user'+#result.infoId")
public InfoUser updateInfoUser(InfoUser user) {
// TODO Auto-generated method stub
infoMapper.updateInfoUser(user);
return user;
}
@Override
@Transactional
@CacheEvict(value="redisCache",key="'redis_user'+#infoId",beforeInvocation=false)
//移除缓存 在方法执行之后移除
public int deleteInfoUser(int infoId) {
// TODO Auto-generated method stub
return infoMapper.deleteInfoUser(infoId);
}
@Override
@Transactional
//查询结果不准确
public List<InfoUser> findUserLikeName(String userName) {
// TODO Auto-generated method stub
return infoMapper.findUserLikeName(userName);
}
1:@Cacheable代表首先从redis中去查询有没有相应的缓存 ,主要应用于getInfoUser()这个方法
2:@CachePut主要应用于将数据加入到redis缓存中去,主要应用于
1):addInfoUser()这个方法
完整代码为:@CachePut(value=“redisCache”,key="‘redis_user’+#result.infoId")
其中 value=“redisCache” 是我们前边配置文件规定的缓存name ,key="‘redis_user’+#result.infoId" 作用是在redis中命名存储的key 值
2):updateInfoUser()方法
@CachePut(value=“redisCache”,condition="#result != ‘null’", key = “‘redis_user’+#result.infoId”)
解释为如果返回结果值不为空,将修改的对象存储到redis缓存中
3@CacheEvict主要是从缓存中删除数据
主要应用在删除相关操作deleteInfoUser()
@CacheEvict(value=“redisCache”,key="‘redis_user’+#infoId",beforeInvocation=false)