springboot 2.x redis缓存

符号 阅读:613 2021-04-01 11:16:13 评论:0

1.pom文件导入依赖,本项目持久层使用mybatis,springboot 版本2.1.8

<parent> 
		<groupId>org.springframework.boot</groupId> 
		<artifactId>spring-boot-starter-parent</artifactId> 
		<version>2.1.8.RELEASE</version> 
		<relativePath /> <!-- lookup parent from repository --> 
	</parent> 
	<groupId>com.example</groupId> 
	<artifactId>rediscache2</artifactId> 
	<version>0.0.1-SNAPSHOT</version> 
	<name>rediscache2</name> 
	<description>Demo project for Spring Boot</description> 
 
	<properties> 
		<java.version>1.8</java.version> 
	</properties> 
 
	<dependencies> 
		<dependency> 
			<groupId>org.springframework.boot</groupId> 
			<artifactId>spring-boot-starter-web</artifactId> 
		</dependency> 
		<dependency> 
			<groupId>org.mybatis.spring.boot</groupId> 
			<artifactId>mybatis-spring-boot-starter</artifactId> 
			<version>2.1.1</version> 
		</dependency> 
		<!-- mysql --> 
		<dependency> 
			<groupId>mysql</groupId> 
			<artifactId>mysql-connector-java</artifactId> 
		</dependency> 
		<dependency> 
			<groupId>org.springframework.boot</groupId> 
			<artifactId>spring-boot-starter-test</artifactId> 
			<scope>test</scope> 
			<exclusions> 
				<exclusion> 
					<groupId>org.junit.vintage</groupId> 
					<artifactId>junit-vintage-engine</artifactId> 
				</exclusion> 
			</exclusions> 
		</dependency> 
		<!--spring2.0集成redis所需common-pool2--> 
        <dependency> 
            <groupId>org.apache.commons</groupId> 
            <artifactId>commons-pool2</artifactId> 
            <version>2.4.2</version> 
        </dependency> 
<!-- redis依赖,2.0以上使用这个依赖 --> 
        <dependency> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-data-redis</artifactId> 
        </dependency> 
<!-- 缓存依赖 --> 
        <dependency> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-cache</artifactId> 
        </dependency> 
	</dependencies> 

2.application.yml配置文件

#Web服务 
# address           :可指定在某个IP上启动服务。空表示在所有IP上启动 
# context-path      :发布的路径 
# session.timeout   :超时时间,单位:秒 
server: 
    address: 
    port: 8080 
    servlet: 
        context-path:  
        session: 
          timeout: 1800 
 
spring: 
  #MySQL数据库 
  datasource: 
    url: jdbc:mysql://192.168.2.101:3306/redisTest?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=GMT%2B8 
    username: root 
    password: root 
    driver-class-name: com.mysql.jdbc.Driver 
#Mybatis配置 
mybatis: 
  mapper-locations: classpath*:com/example/demo/mapper/*.xml 
  configuration: 
    log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl 
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 
logging.level.com.example.demo.dao: debug 
 
spring.redis.database: 2  
spring.redis.host: localhost  
spring.redis.port: 6379 
spring.redis.password:  
 
# springboot2.x以上如此配置,由于2.x的客户端是lettuce 
# 单位要带上 
spring.redis.lettuce.pool.max-active: 8 
spring.redis.lettuce.pool.min-idle: 0 
spring.redis.lettuce.pool.max-idle: 8 
spring.redis.lettuce.pool.max-wait: 10000ms 
spring.redis.lettuce.shutdown-timeout: 100ms 

3.RedisCacheConfig缓存配置文件

import java.time.Duration; 
 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.cache.annotation.CachingConfigurerSupport; 
import org.springframework.cache.annotation.EnableCaching; 
import org.springframework.cache.interceptor.KeyGenerator; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.data.redis.cache.RedisCacheConfiguration; 
import org.springframework.data.redis.cache.RedisCacheManager; 
import org.springframework.data.redis.connection.RedisConnectionFactory; 
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 
import org.springframework.data.redis.serializer.RedisSerializationContext; 
import org.springframework.data.redis.serializer.RedisSerializer; 
import org.springframework.data.redis.serializer.StringRedisSerializer; 
 
@Configuration 
@EnableCaching 
public class RedisCacheConfig extends CachingConfigurerSupport { 
 
    private static final Logger logger = LoggerFactory.getLogger(RedisCacheConfig.class); 
 
    // 自定义key生成器 
    @Bean 
    public KeyGenerator keyGenerator(){ 
        return (o, method, params) ->{ 
            StringBuilder sb = new StringBuilder(); 
            sb.append(o.getClass().getName()); // 类目 
            sb.append(method.getName()); // 方法名 
            for(Object param: params){ 
                sb.append(param.toString()); // 参数名 
            } 
            return sb.toString(); 
        }; 
    } 
 
    // 配置缓存管理器 
    @Bean 
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) { 
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() 
                .entryTtl(Duration.ofSeconds(300)) // 60s缓存失效 
                // 设置key的序列化方式 
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())) 
                // 设置value的序列化方式 
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())); 
                // 不缓存null值 
//                .disableCachingNullValues(); 
 
        RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory) 
                .cacheDefaults(config) 
                .transactionAware() 
                .build(); 
 
        logger.info("自定义RedisCacheManager加载完成"); 
        return redisCacheManager; 
    } 
 
    // key键序列化方式 
    private RedisSerializer<String> keySerializer() { 
        return new StringRedisSerializer(); 
    } 
 
    // value值序列化方式 
    private GenericJackson2JsonRedisSerializer valueSerializer(){ 
        return new GenericJackson2JsonRedisSerializer(); 
    } 
} 
 

4.测试service代码

package com.example.demo; 
 
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.example.demo.dao.FilmBaseMapper; 
@Service 
public class TestService { 
	@Autowired 
	private FilmBaseMapper filmBaseMapper; 
	//指定id作为redis的key,"film::9"为key 
	@Cacheable(cacheNames="film",key="#id") 
	public FilmBase getFilmById(int id) { 
		FilmBase film = filmBaseMapper.selectByPrimaryKey(id); 
		return film; 
	} 
	//方法全名为key,"films::com.example.demo.TestServicegetAll"为key 
	@Cacheable(cacheNames="films") 
	public List<FilmBase> getAll() { 
		List<FilmBase> selectAll = filmBaseMapper.selectAll(); 
		return selectAll; 
	} 
	//方法必定执行一次,同时修改缓存 "film::9"为key 
	@CachePut(cacheNames = "film", key = "#filmBase.id") 
	public FilmBase updateFilm(FilmBase filmBase){ 
		Integer i; 
		try { 
			i = filmBaseMapper.updateByPrimaryKey(filmBase); 
			return filmBase; 
		} catch (Exception e) { 
			// TODO Auto-generated catch block 
			e.printStackTrace(); 
		} 
		return filmBase; 
	} 
	//删除cacheNames 为film和films开头的缓存,allEntries =false只删除指定 "film::9"或"films::9"为key的缓存,allEntries =true删除两种cacheNames 缓存 
	@CacheEvict(cacheNames = {"film","films"}, key ="#filmId",allEntries = false, beforeInvocation = true 
		   ) 
    public Integer delFilm(Integer filmId) { 
        return filmBaseMapper.deleteByPrimaryKey(filmId); 
    } 
} 

5.测试FilmBaseMapper.xml文件

<?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.example.demo.dao.FilmBaseMapper"> 
	<resultMap id="BaseResultMap" type="com.example.demo.FilmBase"> 
		<id column="id" jdbcType="INTEGER" property="id" /> 
		<result column="film_name" jdbcType="VARCHAR" property="filmName" /> 
		<result column="user_id" jdbcType="INTEGER" property="userId" /> 
		<result column="year" jdbcType="INTEGER" property="year" /> 
		<result column="release_date" jdbcType="TIMESTAMP" property="releaseDate" /> 
		<result column="note" jdbcType="VARCHAR" property="note" /> 
		<result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> 
	</resultMap> 
	<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> 
		delete from film_base 
		where id = #{id,jdbcType=INTEGER} 
	</delete> 
	<insert id="insert" parameterType="com.example.demo.FilmBase"> 
	 <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> 
			SELECT LAST_INSERT_ID() 
 	</selectKey> 
		insert into film_base (id, film_name, user_id, 
		year, release_date, note 
		) 
		values (#{id,jdbcType=INTEGER}, #{filmName,jdbcType=VARCHAR}, 
		#{userId,jdbcType=INTEGER}, 
		#{year,jdbcType=INTEGER}, #{releaseDate,jdbcType=TIMESTAMP}, #{note,jdbcType=VARCHAR} 
		) 
	</insert> 
	<update id="updateByPrimaryKey" parameterType="com.example.demo.FilmBase"> 
		update film_base 
		set film_name = #{filmName,jdbcType=VARCHAR}, 
		user_id = #{userId,jdbcType=INTEGER}, 
		year = #{year,jdbcType=INTEGER}, 
		release_date = #{releaseDate,jdbcType=TIMESTAMP}, 
		note = #{note,jdbcType=VARCHAR} 
		where id = #{id,jdbcType=INTEGER} 
	</update> 
	<select id="selectByPrimaryKey" parameterType="java.lang.Integer" 
		resultMap="BaseResultMap"> 
		select id, film_name, user_id, year, release_date, note 
		from film_base 
		where id = #{id,jdbcType=INTEGER} 
	</select> 
	<select id="selectByUserIdAndFilmName" resultMap="BaseResultMap"> 
		select id, film_name, user_id, year, release_date, note 
		from film_base 
		where user_id = #{userId,jdbcType=INTEGER} and film_name = 
		#{filmName,jdbcType=VARCHAR} 
	</select> 
	<select id="selectByUserId" resultMap="BaseResultMap"> 
		select id, film_name, user_id, year, release_date, note,create_time 
		from film_base 
		where user_id = #{userId,jdbcType=INTEGER} 
	</select> 
	<select id="selectAll" resultMap="BaseResultMap"> 
		select id, film_name, user_id, year, release_date, note 
		from film_base 
	</select> 
</mapper> 

6.dao文件FilmBaseMapper

public interface FilmBaseMapper { 
	int deleteByPrimaryKey(Integer id); 
 
	int insert(FilmBase record); 
 
	FilmBase selectByPrimaryKey(Integer id); 
 
	List<FilmBase> selectAll(); 
 
	Integer updateFilm(FilmBase filmBase); 
 
	Integer updateByPrimaryKey(FilmBase filmBase); 
} 

7.entity文件FilmBase

public class FilmBase implements Serializable { 
    private Integer id; 
 
    private String filmName; 
 
    private Integer userId; 
 
    private Integer year; 
 
    private Date releaseDate; 
 
    private String note; 
 
    private Date createTime; 
    private static final long serialVersionUID = 1L; 
	//省略getset 
} 

8.测试类

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class DemoApplicationTests { 
	@Autowired 
	private TestService testService; 
	@Test 
	public void getAll() { 
		List<FilmBase> all = testService.getAll(); 
		System.out.println(all.size()); 
		for (FilmBase filmBase : all) { 
			System.out.println(filmBase.getFilmName()); 
		} 
	} 
	@Test 
	public void getFilmById() { 
		try { 
			FilmBase all = testService.getFilmById(9); 
			System.out.println(all.getFilmName()); 
		} catch (Exception e) { 
			// TODO Auto-generated catch block 
			e.printStackTrace(); 
		} 
	} 
	@Test 
	public void updateFilm() { 
		FilmBase fb =new FilmBase(); 
		fb.setId(8); 
		fb.setFilmName("中国记账"); 
		fb = testService.updateFilm(fb); 
		System.out.println(fb.getFilmName()); 
	} 
	@Test 
	public void delFilm() { 
		int i = testService.delFilm(14); 
		System.out.println(i); 
	} 
} 

9.sql文件

 
 
SET FOREIGN_KEY_CHECKS=0; 
 
-- ---------------------------- 
-- Table structure for `film_base` 
-- ---------------------------- 
DROP TABLE IF EXISTS `film_base`; 
CREATE TABLE `film_base` ( 
  `id` int(11) NOT NULL AUTO_INCREMENT, 
  `film_name` varchar(255) DEFAULT NULL COMMENT '电影名称', 
  `user_id` int(11) DEFAULT NULL COMMENT '用户id', 
  `year` int(11) DEFAULT NULL COMMENT '年份', 
  `release_date` datetime DEFAULT NULL COMMENT '发行日期', 
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', 
  `note` varchar(255) DEFAULT NULL, 
  PRIMARY KEY (`id`), 
  UNIQUE KEY `filmName_user_unique` (`film_name`,`user_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8; 
 
-- ---------------------------- 
-- Records of film_base 
-- ---------------------------- 
INSERT INTO `film_base` VALUES ('9', '建党伟业', '17', '2017', '2018-10-24 00:00:00', '2019-10-31 16:31:51', null); 
INSERT INTO `film_base` VALUES ('20', '战狼', '4', '2017', '2017-12-12 00:00:00', '2019-10-31 19:18:47', null); 
INSERT INTO `film_base` VALUES ('21', '哪吒', '4', '2018', '2019-10-01 00:00:00', '2019-10-31 19:57:58', null); 
INSERT INTO `film_base` VALUES ('22', '齐天大圣', '2', '2017', '2019-10-07 00:00:00', '2019-10-31 20:13:25', null); 
INSERT INTO `film_base` VALUES ('23', '神龙教', '17', '2017', '2018-09-04 00:00:00', '2019-10-31 20:53:23', null); 
INSERT INTO `film_base` VALUES ('24', '太极张三丰', '17', '2018', '2019-02-01 00:00:00', '2019-10-31 21:08:57', null); 
INSERT INTO `film_base` VALUES ('25', '战狼2', '4', '2017', '2017-12-12 00:00:00', '2019-10-31 21:11:33', null); 
INSERT INTO `film_base` VALUES ('26', '战狼3', '4', '2017', '2017-12-12 00:00:00', '2019-10-31 21:11:41', null); 
INSERT INTO `film_base` VALUES ('27', '上甘岭', '1', '1955', '1955-10-12 00:00:00', '2019-10-31 21:20:18', null); 
INSERT INTO `film_base` VALUES ('28', '上甘岭2', '1', '1956', '1957-05-12 00:00:00', '2019-10-31 21:31:43', null); 
INSERT INTO `film_base` VALUES ('29', '上甘岭4', '1', '1960', '1960-08-18 00:00:00', '2019-10-31 21:39:17', null); 
INSERT INTO `film_base` VALUES ('30', '飒飒飒飒多所', '1', '2019', '2019-10-31 00:00:00', '2019-10-31 21:40:17', null); 
INSERT INTO `film_base` VALUES ('31', '死亡骑士无', '1', '2018', '2018-10-31 00:00:00', '2019-10-31 21:41:45', null); 
INSERT INTO `film_base` VALUES ('32', '读完读完群', '1', '2019', '2019-10-31 00:00:00', '2019-10-31 21:42:37', null); 
INSERT INTO `film_base` VALUES ('33', '大萨达', '1', '2019', '2019-10-31 00:00:00', '2019-10-31 21:43:57', null); 
INSERT INTO `film_base` VALUES ('34', '额滴神哒', '1', '2017', '2017-10-31 00:00:00', '2019-10-31 21:45:05', null); 
INSERT INTO `film_base` VALUES ('35', '落花流水', '17', '2018', '2019-10-01 00:00:00', '2019-10-31 21:48:39', null); 
INSERT INTO `film_base` VALUES ('36', '灵魂摆渡·黄泉', '4', null, null, '2019-11-01 09:30:29', null); 
INSERT INTO `film_base` VALUES ('37', '死亡骑士', '1', '2016', '2016-11-15 00:00:00', '2019-11-01 10:12:34', null); 
INSERT INTO `film_base` VALUES ('38', '死亡骑士1', '1', '2017', '2017-06-14 00:00:00', '2019-11-01 10:14:24', null); 
INSERT INTO `film_base` VALUES ('39', 'test2', '2', '2019', '2019-11-19 00:00:00', '2019-11-01 10:31:16', null); 
INSERT INTO `film_base` VALUES ('40', '九门提督', '4', '2019', '2019-11-13 00:00:00', '2019-11-01 10:33:34', null); 
INSERT INTO `film_base` VALUES ('41', '唐山大地震', '17', '2017', '2017-07-03 00:00:00', '2019-11-01 10:44:59', null); 
INSERT INTO `film_base` VALUES ('42', '超时空救援', '4', '2019', '2019-11-19 00:00:00', '2019-11-01 11:14:52', null); 
 

10.测试方法,打印sql为走数据库,不打印为走缓存
a.执行getFilmById()方法,第一次走数据库
第一次走数据库
b.再次执行getFilmById()方法,第二次走缓存
在这里插入图片描述
c.执行getAll()方法,第一次走数据库
在这里插入图片描述
d.再次执行getAll()方法,第二次走缓存
在这里插入图片描述
e.redis数据库内容
在这里插入图片描述
f.执行delFilm()方法allEntries = false,指定id我传的9,将id为9的数据删除
在这里插入图片描述
g.执行delFilm()方法allEntries = true,指定id我传的20,将id为9的数据删除,同时删除film和films两个cacheNames缓存区域
在这里插入图片描述
h.补充。执行 getFilmById方法后,再执行updateFilm()方法,可以修改缓存和数据库

标签:Spring Boot
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号