暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringBoot2.x学习笔记-使用Spring缓存注解操作Redis

CodeWu 2019-04-15
243

Spring缓存注解操作Redis

    为了进一步简化Redis的使用,Spring还提供了缓存注解,使用Spring缓存注解可以有效简化编程过程。

    在使用Spring缓存注解前,需要配置缓存管理器。在缓存管理器中提供了一些重要的信息,如缓存类型、超时时间等。Spring可以支持多种缓存技术使用,因此存在多种缓存处理器,并提供了缓存处理器的接口CacheManager和各类缓存技术的具体实现类。

    在SpringBoot的starter机制中,允许我们通过配置文件生成缓存管理器并配置缓存管理器的参数。

#redis缓存管理器配置
#缓存名称
spring.cache.cache-names=redisCache
#是否允许缓存存储空值
spring.cache.redis.cache-null-values=false
#超时时间
spring.cache.redis.time-to-live=0ms
#是否启用Redis键前缀
spring.cache.redis.key-prefix=true
#缓存类型
spring.cache.type=redis

    在对缓存类型(spring.cache.type)进行配置后,SpringBoot会根据配置的缓存类型生成对应的CacheManager实现类。

    在SpringBoot应用程序入口添加如下配置启用缓存管理器。

    

@EnableCaching
public class DemoApplication {


public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}

}

 使用缓存注解示例

     示例缓存配置信息如下: 

#Druid连接池配置
spring.datasource.druid.username=root
spring.datasource.druid.password=WU830118
spring.datasource.druid.url=jdbc:mysql://localhost:3306/mybatis_demo?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#初始化连接数
spring.datasource.druid.initial-size=5
#最小等待数
spring.datasource.druid.min-idle=5
#最大连接数
spring.datasource.druid.max-active=20
#最大等待时间,单位毫秒
spring.datasource.druid.max-wait=10000
#执行连接检测间隔时间,同时也作为testWhileIdel执行的依据,单位毫秒
spring.datasource.druid.time-between-eviction-runs-millis=60000
#申请连接检测,如果连接时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效
spring.datasource.druid.test-while-idle=true
#检测连接是否有效,必须为查询语句(oracle为select 1 from DUAL)
spring.datasource.druid.validation-query=select 'x'
#申请连接时会检测连接是否有效(validationQuery),开启会降低性能,默认true
spring.datasource.druid.test-on-borrow=false
#归还连接时检测连接是否有效(validationQuery),开启会降低性能,默认true
spring.datasource.druid.test-on-return=false
#数据库抛出不可恢复异常,抛弃该连接
#spring.datasource.druid.exception-sorter=true
#开启预编译缓存
#spring.datasource.druid.pool-prepared-statements=true
#每个数据库连接上预编译缓存大小,大于0自动开启预编译缓存(poolProparedStatements自动设置为true)
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
#配置监控统计拦截过滤器,去掉监控界面SQL无法统计
spring.datasource.druid.filters=stat,wall
#通过connectionProperties属性打开mergeSql功能,慢SQL记录
spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
#合并多个DruidDataSource的监控数据
spring.datasource.druid.use-global-data-source-stat=true
#配置访问Druid监控页的账号和密码(默认无)
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
#设置默认的数据库事务隔离级别为读写提交
spring.datasource.druid.default-transaction-isolation=2
#配置mybatis内容
#映射器扫描包
mybatis.mapper-locations=classpath:/mappers/*Mapper.xml
#接口扫描包
mybatis.type-aliases-package=com.springboot.demo.mybatis.dao
#类型转换器扫描包
mybatis.type-handlers-package=com.springboot.demo.mybatis.typehandler
#配置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.timeout=1000
#redis缓存管理器配置
#缓存名称
spring.cache.cache-names=redisCache
#是否允许缓存存储空值
spring.cache.redis.cache-null-values=false
#超时时间
spring.cache.redis.time-to-live=0ms
#是否启用Redis键前缀
spring.cache.redis.key-prefix=true
#缓存类型
spring.cache.type=redis


    测试实体

public class UserInfo implements Serializable{
private int userId;


private String userName;
private String loginAccount;
private String passWord;
private int userAge;
private String createDate;
private String updateDate;
private String userState;
private SexEnum sexEnum;
}

    数据库访问层接口

package com.springboot.demo.redis.dao;


import com.springboot.demo.jpa.pojo.UserInfo;
import org.springframework.stereotype.Repository;


import java.util.List;


@Repository
public interface RedisUserInfoRespository {
/**
* 根据用户名模糊查询
* @param userName:用户名
* @return 用户信息集合
*/
public List<UserInfo> findByUserName(String userName);
/**
* 根据登录账户名模糊查询
* @param loginAccount:登录账户
* @return 用户集合信息
*/
public List<UserInfo> findByLoginAccount(String loginAccount);


/**
* 根据用户标识查询用户信息
* @param userId:用户标识
* @return 用户明细信息
*/
public UserInfo findByUserId(int userId);


/**
* 保存用户信息
* @param userInfo
* @return 被保存用户
*/
public UserInfo save(UserInfo userInfo);
    /**
* 根据用户标识删除用户
* @param userId:用户标识
* @return 受影响行数
*/
public int deleteUserInfoByUserId(int userId);
}


  映射器配置文件

<?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.springboot.demo.redis.dao.RedisUserInfoRespository">
<!--自定义查询语句,便于复用-->
<sql id="selectSql">
SELECT u.user_id,u.user_name,u.login_account,u.user_age,u.user_state,u.user_sex from t_user u
</sql>
<!--定义查询结果集-->
<resultMap id="userInfo" type="com.springboot.demo.mybatis.pojo.UserInfo">
<id column="user_id" property="userId" javaType="int" jdbcType="INTEGER"/>
<result column="user_name" property="userName" javaType="String" jdbcType="VARCHAR"/>
<result column="pass_word" property="passWord" javaType="String" jdbcType="VARCHAR"/>
<result column="login_account" property="loginAccount" javaType="String" jdbcType="VARCHAR"/>
<result column="user_age" property="userAge" jdbcType="INTEGER" javaType="int"/>
<result column="create_date" property="createDate" javaType="String" jdbcType="DATE" typeHandler="com.springboot.demo.mybatis.typehandler.DateTypeHandler"/>
<result column="update_date" property="updateDate" javaType="String" jdbcType="DATE" typeHandler="com.springboot.demo.mybatis.typehandler.DateTypeHandler"/>
<result column="user_state" property="userState" javaType="String" />
<result column="user_sex" property="sexEnum" jdbcType="INTEGER" typeHandler="com.springboot.demo.mybatis.typehandler.SexTypeHandler"/>
</resultMap>
<!--根据用户名查询用户集合信息-->
<select id="findUserInfoByUserName" parameterType="String" resultMap="userInfo">
<include refid="selectSql"/> where u.user_name LIKE CONCAT('%',#{userName},'%')
</select>
<!--根据登录账号查询用户集合信息-->
<select id="findUserInfoByLoginAccount" parameterType="String" resultMap="userInfo">
<include refid="selectSql"/> where u.login_account LIKE CONCAT('%',#{loginAccount},'%')
</select>
<!--根据用户标识查询用户详情-->
<select id="findUserInfoByUserId" parameterType="int" resultMap="userInfo">
<include refid="selectSql"/> where u.user_id=#{userId}
</select>
<!--保存用户信息-->
<insert id="saveUserInfo" parameterType="com.springboot.demo.mybatis.pojo.UserInfo" useGeneratedKeys="true" keyProperty="user_id">
insert into t_user(user_name,pass_word,login_account,user_age,create_date,update_date,user_state,user_sex)
VALUES (#{userName},#{passWord},#{loginAccount},#{userAge},#{createDate},#{updateDate},#{userState},#{sexEnum});
</insert>
<!--更新用户状态-->
<update id="updateUserState" parameterType="com.springboot.demo.mybatis.pojo.UserInfo">
update t_user u set u.user_state=#{userState},u.update_date=#{updateDate} where u.user_id=#{userId}
</update>
<!--物理删除用户-->
<delete id="deleteUserInfoByUserId" parameterType="int">
delete from t_user where user_id=#{userId}
</delete>
</mapper>

    业务逻辑层接口

public interface RedisUserInfoService{
/**
* 根据用户名模糊查询
* @param userName:用户名
* @return 用户信息集合
*/
public List<UserInfo> findByUserName(String userName);
/**
* 根据登录账户名模糊查询
* @param loginAccount:登录账户
* @return 用户集合信息
*/
public List<UserInfo> findByLoginAccount(String loginAccount);


/**
* 根据用户标识查询用户信息
* @param userId:用户标识
* @return 用户明细信息
*/
public UserInfo findByUserId(int userId);


/**
* 保存用户信息
* @param userInfo:被保存用户
* @return 保存后用户
*/
public UserInfo save(UserInfo userInfo);


/**
* 更新用户信息
* @param userInfo:被更新用户信息
* @return 更新后用户
*/
public UserInfo updateUserInfo(UserInfo userInfo);


/**
* 根据用户标识删除用户信息
* @param userId:用户表述
* @return受影响行数
*/
public int deleteUserInfoByUserId(int userId);
}

    业务逻辑层接口实现类

package com.springboot.demo.redis.service.impl;


import com.springboot.demo.mybatis.pojo.UserInfo;
import com.springboot.demo.redis.dao.RedisUserInfoRespository;
import com.springboot.demo.redis.service.RedisUserInfoService;
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 org.springframework.transaction.annotation.Transactional;


import java.util.List;
@Service
public class RedisUserInfoServiceImpl implements RedisUserInfoService {
@Autowired
private RedisUserInfoRespository redisUserInfoRespository;


/**
* 根据用户名查询用户集合信息(命中率低无需启用缓存)
* @param userName:用户名
* @return用户集合信息
*/
@Override
@Transactional
public List<UserInfo> findByUserName(String userName) {
return redisUserInfoRespository.findByUserName(userName);
}


/**
* 根据登录账户查询用户集合信息(命中率低无需启用缓存)
* @param loginAccount:登录账户
* @return用户集合信息
*/
@Override
@Transactional
public List<UserInfo> findByLoginAccount(String loginAccount) {
return redisUserInfoRespository.findByLoginAccount(loginAccount);
}


/**
* 根据用户标识查询用户信息(将查询到的用户信息存入Redis缓存中,value为配置文件中配置的spring.cache.cache-names,key为缓存键)
* @param userId:用户标识
* @return用户详情信息
*/
@Override
@Transactional
@Cacheable(value = "redisCache",key = "'redis_user_'+#userId")
public UserInfo findByUserId(int userId) {
return redisUserInfoRespository.findByUserId(userId);
}


/**
* 保存用户信息(将成功保存的用户信息存入Redis缓存中,value为配置文件中配置的spring.cache.cache-names,key为缓存键)
* @param userInfo:用户信息
* @return 保存成功用户信息
*/
@Override
@Transactional
@CachePut(value = "redisCache",key = "'redis_user_'+#result.userId")
public UserInfo save(UserInfo userInfo) {
return redisUserInfoRespository.save(userInfo);
}


/**
* 更新用户信息(将成功更新的用户信息存入Redis缓存中,value为配置文件中配置的spring.cache.cache-names,key为缓存键)
* @param userInfo:被更新用户信息
* @return 更新后用户信息
*/
@Override
@Transactional
@CachePut(value = "redisCache",
condition = "#result != 'null'",
key="'redis_user_'+#result.userId")
public UserInfo updateUserInfo(UserInfo userInfo) {
UserInfo updateUser=this.findByUserId(userInfo.getUserId());
if(updateUser==null)
{
return null;
}
redisUserInfoRespository.updateUserState(userInfo);
return updateUser;
}


/**
* 删除用户信息(将成功删除的用户信息从Redis缓存中移除,value为配置文件中配置的spring.cache.cache-names,key为缓存键)
* @param userId:用户标识
* @return受影响行数
*/
@Override
@CacheEvict(value = "redisCache",key = "'redis_user_'+#userId",beforeInvocation = false)
public int deleteUserInfoByUserId(int userId) {
return redisUserInfoRespository.deleteUserInfoByUserId(userId);
}




}


    Spring缓存注解说明

    

注解名注解作用
@CachePut将方法返回结果存入缓存中
@CacheEnable根据缓存key从缓存中进行查询,查询到结果则返回,否则执行该方法进行查询,将查询结果存入缓存
@CacheEvict根据缓存key从缓存中移除数据,beforInvocation配置方法执行前从缓存中移除数据,配置为false则是在方法执行后从缓存中移除数据

    测试用例


@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RedisAnnotationTest {
@Autowired
private RedisUserInfoService redisUserInfoServiceImpl;


@Test
public void testFindByUserId()
{
UserInfo userInfo=redisUserInfoServiceImpl.findByUserId(10);
System.out.println("用户名-----------"+userInfo.getUserName()+",用户状态--------"+userInfo.getUserState());
}
@Test
public void testSavaUserInfo()
{
UserInfo userInfo=new UserInfo();
userInfo.setUserName("testRedis2");
userInfo.setLoginAccount("testRedis2");
userInfo.setCreateDate(DatetimeUtils.dateFormatStr(new Date()));
userInfo.setUpdateDate(DatetimeUtils.dateFormatStr(new Date()));
userInfo.setUserAge(36);
userInfo.setUserState("1");
userInfo.setPassWord("123456");
userInfo.setSexEnum(SexEnum.MALE);
redisUserInfoServiceImpl.save(userInfo);
}
@Test
public void testDeleteUserInfo()
{
redisUserInfoServiceImpl.deleteUserInfoByUserId(8);
}
}


文章转载自CodeWu,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论