分布式学习笔记SpringBoot整合redis实现mybatis二级缓存

合集下载

SpringBoot与Redis缓存集成实践

SpringBoot与Redis缓存集成实践

SpringBoot与Redis缓存集成实践一、引言随着现代应用程序的复杂性不断增加,缓存成为提高系统性能和响应速度的重要手段之一。

而SpringBoot与Redis的集成可以帮助我们更加高效地实现缓存功能。

本文将介绍SpringBoot与Redis缓存集成的实践,从配置Redis、使用RedisTemplate进行缓存操作以及解决缓存穿透与缓存雪崩等问题进行探讨。

二、配置Redis1. 引入依赖在pom.xml文件中添加SpringDataRedis的依赖:```xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>```2. 配置Redis连接参数在application.properties或application.yml文件中配置Redis连接参数:```spring.redis.host=127.0.0.1spring.redis.port=6379spring.redis.database=0spring.redis.password=```其中,host为Redis服务器的IP地址,port为端口号,database为数据库索引,password为连接密码(如果有设置)。

3. 配置RedisTemplate在SpringBoot的配置类中,通过@Bean注解创建一个RedisTemplate的实例,并设置相关参数,例如连接工厂、序列化器等:```java@Configurationpublic class RedisConfig {@Beanpublic RedisTemplate<String, Object>redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(newGenericJackson2JsonRedisSerializer());return redisTemplate;}}```在上述代码中,我们使用了StringRedisSerializer对key进行序列化,使用了GenericJackson2JsonRedisSerializer对value进行序列化。

Mybatis缓存配置——二级缓存

Mybatis缓存配置——二级缓存

Mybatis缓存配置——⼆级缓存⼀、配置⼆级缓存1. 在mybatis_config.xml中进⾏如下配置:<setting name="cacheEnabled" value="true"/>其实这⾥的⼆级缓存默认是出于开启状态,因此这个位置可以不进⾏配置,知道有这么回事⼉即可。

2.MyBatis⼆级缓存是和命名空间是绑定的,即⼆级缓存需要配置在 Mapper.xml 映射⽂件中,或者配置在 Mapper.java 接⼝中。

在映射⽂件中命名空间就是 XML 根节点 mapper namespace 属性 Mapper 接⼝中,命名空间就是接⼝的全限定名称。

(1)在RoleMapper.xml中进⾏⼆级缓存配置,添加配置如下:<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.example.simple.mapper.RoleMapper"><cacheeviction="FIFO"flushInterval="6000"size="512"readOnly="false"/>/mapper>(2)在RoleMapper.java类中添加注解:@CacheNamespaceRef(RoleMapper.class)public interface RoleMapper {//代码}最基本的⼆级缓存就配置好了。

SpringBoot+MySQL+MyBatis整合Redis实现缓存操作

SpringBoot+MySQL+MyBatis整合Redis实现缓存操作

SpringBoot+MySQL+MyBatis整合Redis实现缓存操作本地安装 Redis项⽬结构:SpringBootRedis ⼯程项⽬结构如下: controller - Controller 层 dao - 数据操作层 model - 实体层 service - 业务逻辑层 Application - 启动类 resources 资源⽂件夹 application.properties - 应⽤配置⽂件,应⽤启动会⾃动读取配置 generatorConfig.xml - mybatis 逆向⽣成配置(这⾥不是本⽂只要重点,所以不进⾏介绍) mapper ⽂件夹 StudentMapper.xml - mybatis 关系映射 xml ⽂件项⽬⼯程代码详情pom.xml 配置<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.7.RELEASE</version><relativePath/><!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><!-- web 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- tomcat插件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope></dependency><!-- Test 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- mysql 依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><!-- redis 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.1.6.RELEASE</version></dependency><!-- mybatis 依赖 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><!-- Gson json 格式化 --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!-- mybatis.generator 插件 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile><overwrite>true</overwrite></configuration><!-- 数据库依赖 --><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.15</version></dependency></dependencies></plugin></plugins></build></project>application.properties 配置spring:datasource:url: jdbc:mysql://localhost:3306/mydb?useSSL=trueusername: oukelepassword: oukeledriver-class-name: com.mysql.jdbc.Driver# 配置 redisredis:# redis 数据库索引(默认为0)database: 0# redis 服务地址host: 127.0.0.1# redis 连接端⼝port: 6379# redis 服务器链接密码(默认为空)password:# 连接超时时间(毫秒)timeout: 5000# 配置 redis 连接池jedis:pool:# 连接池最⼤连接数 (使⽤负值表⽰没有限制)max-active: 8# 连接池最⼤阻塞等待时间(使⽤负值表⽰没有限制)max-wait: -1# 连接池的最⼤空闲连接max-idle: 8# 连接池中最⼩空闲连接min-idle: 0# 配置 mybatismybatis:# 设置实体类所在的包名typeAliasesPackage: com.example.demo.model# mybatis xml 映射关系mapper-locations: classpath:mapper/*.xml项⽬结构图model 层 Student.javapackage com.example.demo.model;public class Student {private Integer id;private String numbercode;private String stuname;private String stusex;private Integer stuage;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getNumbercode() {return numbercode;}public void setNumbercode(String numbercode) {this.numbercode = numbercode == null ? null : numbercode.trim(); }public String getStuname() {return stuname;}public void setStuname(String stuname) {this.stuname = stuname == null ? null : stuname.trim();}public String getStusex() {return stusex;}public void setStusex(String stusex) {this.stusex = stusex == null ? null : stusex.trim();}public Integer getStuage() {return stuage;}public void setStuage(Integer stuage) {this.stuage = stuage;}@Overridepublic String toString() {return "Student{" +"id=" + id +", numbercode='" + numbercode + '\'' +", stuname='" + stuname + '\'' +", stusex='" + stusex + '\'' +", stuage=" + stuage +'}';}}View Codedao 层 StudentMapper.java (使⽤了注解 + xml 形式 )package com.example.demo.dao;import com.example.demo.model.Student;import org.apache.ibatis.annotations.Delete;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select;import org.springframework.stereotype.Repository;import java.util.List;@Repositorypublic interface StudentMapper {@Select("select * from student")List<Student> selectAll();@Select("select * from student where numbercode = #{numberCode}") Student getStudent(@Param("numberCode") String numberCode);@Delete("delete from student where numbercode = #{numberCode}") int delete(@Param("numberCode") String numberCode);int update(Student student);int insert(Student student);}View Codeservice 层 StudentService.javapackage com.example.demo.service;import com.example.demo.model.Student;import java.util.List;public interface StudentService {List<Student> selectAll();Student getStudent(String numberCode);int delete(String numberCode);int update(Student student);int insert(Student student);}View Codeservice imple (业务实现)层 StudentServiceImpl.javapackage com.example.demo.service.impl;import com.example.demo.dao.StudentMapper;import com.example.demo.model.Student;import com.example.demo.service.StudentService;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.stereotype.Service;import ng.reflect.Type;import java.util.List;import java.util.concurrent.TimeUnit;@Servicepublic class StudentServiceImpl implements StudentService {@Autowiredprivate StudentMapper studentMapper;@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic List<Student> selectAll() {String key = "student_list";Boolean hasKey = redisTemplate.hasKey(key);ValueOperations operations = redisTemplate.opsForValue();if (hasKey) {String redisList = (String) operations.get(key);Type type = new TypeToken<List<Student>>() {}.getType();List<Student> list = new Gson().fromJson(redisList,type);System.out.println("StudentServiceImpl.selectAll() : 从缓存取得数据,条数:" + list.size());return list;}List<Student> list = studentMapper.selectAll();String toJson = new Gson().toJson(list);// 存在到缓存中operations.set(key, toJson, 10, TimeUnit.SECONDS);return list;}/*** 获取⼀位学⽣逻辑:* 如果缓存存在,从缓存中获取学⽣信息* 如果缓存不存在,从 DB 中获取学⽣信息,然后插⼊缓存*/@Overridepublic Student getStudent(String numberCode) {// 从缓存中取出学⽣信息String key = "student_" + numberCode;Boolean hasKey = redisTemplate.hasKey(key);ValueOperations operations = redisTemplate.opsForValue();// 缓存存在if (hasKey) {String str = (String) operations.get(key);Student student = new Gson().fromJson(str, Student.class);System.out.println("StudentServiceImpl.getStudent() : 从缓存取得数据 >> " + student.toString());return student;}Student student = studentMapper.getStudent(numberCode);String str = new Gson().toJson(student);// 插⼊缓存中operations.set(key, str, 10, TimeUnit.SECONDS);System.out.println("StudentServiceImpl.getStudent() : 学⽣信息插⼊缓存 >> " + student.toString());return student;}@Overridepublic int delete(String numberCode) {String key = "student_" + numberCode;Boolean hasKey = redisTemplate.hasKey(key);int delete = studentMapper.delete(numberCode);if( delete > 0){// 缓存存在,进⾏删除if (hasKey) {redisTemplate.delete(key);System.out.println("StudentServiceImpl.update() : 从缓存中删除编号学⽣ >> " + numberCode); }}return delete;}/*** 更新学⽣信息逻辑:* 如果缓存存在,删除* 如果缓存不存在,不操作*/@Overridepublic int update(Student student) {String key = "student_" + student.getNumbercode();Boolean hasKey = redisTemplate.hasKey(key);int update = studentMapper.update(student);if( update > 0 ){// 缓存存在,进⾏删除if (hasKey) {redisTemplate.delete(key);System.out.println("StudentServiceImpl.update() : 从缓存中删除学⽣ >> " + student.toString()); }}return update;}@Overridepublic int insert(Student student) {String key = "student_list";int insert = studentMapper.insert(student);if (insert > 0) {redisTemplate.delete(key);}return insert;}}View Codecontroller 层 StudentController.javapackage com.example.demo.controller;import com.example.demo.model.Student;import com.example.demo.service.StudentService;import com.google.gson.Gson;import org.apache.ibatis.annotations.Param;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController@RequestMapping(path = "/student")public class StudentController {@Autowiredprivate StudentService studentService;@GetMapping( path = "/getList")public List<Student> getList(){List<Student> students = studentService.selectAll();return students;}@GetMapping( path = "/getStudent")public String getList(@Param("numberCode") String numberCode){ Student students = studentService.getStudent(numberCode); String str = new Gson().toJson(students);return str;}@PostMapping(path = "/insert")public String insert(@RequestBody Student student){int insert = studentService.insert(student);String msg = "";if( insert > 0 ){msg = "{\"msg\":\"新增成功\",\"flag\":true}";}else {msg = "{\"msg\":\"新增失败\",\"flag\":false}";}return msg;}@GetMapping(path = "/delete")public String delete(@Param("numberCode") String numberCode){ int delete = studentService.delete(numberCode);String msg = "";if( delete > 0 ){msg = "{\"msg\":\"删除成功!!\",\"flag\":true}";}else {msg = "{\"msg\":\"删除失败!!\",\"flag\":false}";}return msg;}@PostMapping(path = "/update")public String update(@RequestBody Student student){int update = studentService.update(student);String msg = "";if( update > 0 ){msg = "{\"msg\":\"更新成功\",\"flag\":true}";}else {msg = "{\"msg\":\"更新失败\",\"flag\":false}";}return msg;}}View Code。

程序员看了不后悔一步一步轻松实现SpringBoot整合Redis缓存

程序员看了不后悔一步一步轻松实现SpringBoot整合Redis缓存

程序员看了不后悔一步一步轻松实现SpringBoot整合Redis缓存前言随着技术的发展,程序框架也越来越多,非常考验程序的学习能力,但是框架的产生在程序员开发过程中也提供很多便利,框架可以为程序员减少许多工作量,比如spring boot 、mybatis等都可以提高开发人员的工作效率,今天就来聊聊spring boot与redis 的整合。

一、基本概况为什么使用缓存缓存是在内存中存储的数据备份,当数据没有发生本质变化时就可以直接从内存中查询数据,而不用去数据库查询(在磁盘中)CPU读取内存的速度要比读取磁盘快,可以提高效率Redis缓存Remote Dictionnary Server(远程数据服务),是一款内存高速缓存数据库。

五种常用数据类型: String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)可持久化:一边运行,一边向硬盘备份一份,防止断电等偶然情况,导致内存中数据丢失二、搭建Redis环境1.下载Redis平台限制不能贴链接,自行去官网下载哈!2.设置Redis开机自启在解压好的文件夹下输入cmd命令window下安装Redis服务redis-server --service-install redis.windows.conf检查安装是否成功搜索服务点击设置为开机自启三、新建SpringBoot项目新建好项目的童鞋可以自动跳过添加web依赖选择数据库依赖选择项目位置,点击finish四、使用StringRedisTemplate操作Redis1.pom.xml文件引入坐标<!--redis依赖包--> <dependency><groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>2.在appliaction.properties配置redis数据库连接信息#redis配置#Redis服务器地址spring.redis.host=127.0.0.1#Redis服务器连接端口spring.redis.port=6379#Redis数据库索引(默认为0)spring.redis.database=03.在SpringbootdemoApplicationTests中测试操作Redis@SpringBootTestclass SpringbootdemoApplicationTests {@Autowired StringRedisTemplate stringRedisTemplate; //操作key-value都是字符串,最常用@Test public void test01(){ //字符串操作stringRedisTemplate.opsForValue().append("msg","coder"); //列表操作stringRedisTemplate.opsForList().leftPush("mylist","1"); stringRedisTemplate.opsForList().leftPush("mylist","2"); }}对于Redis的五大常用数据类型都提供了方法String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)stringRedisTemplate.opsForValue();[String(字符串)]stringRedisTemplate.opsForList();[List(列表)]stringRedisTemplate.opsForSet();[Set(集合)]stringRedisTemplate.opsForHash();[Hash(散列)]stringRedisTemplate.opsForZSet();[ZSet(有序集合)]使用RedisDesktopManager可视化工具查看结果StringTemplate类中方法存取的key-value值是String类型,RedisTemplate中key-value值是Object类型,RedisTemplate是StringTemplate父类下面就用RedisTemplate实现从MySQL数据库取出数据放到Redis缓存五、使用RedisTemplate操作Redis1.项目目录结构2.建立与数据库相关的类建表的sql脚本application.properties配置文件MySQL及Redis连接的相关配置User类采用ORM思想,属性和数据库字段对应package com.thinkcoder.bean;import java.io.Serializable;importjava.util.Date;/*** @ClassName User * @Author Think-Coder * @Data 2020/5/27 10:35* @Version 1.0 */public class User implements Serializable { private Integer id; private String username; private Date birthday; private String sex;private String address; //getter和setter方法 public Integer getId() {returnid;} public void setId(Integer id) {this.id = id;} public StringgetUsername() {return username;} public void setUsername(String username){ername = username;} public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;} publicString getSex() {return sex;} public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;} public void setAddress(Stringaddress) {this.address = address;} //重写toString方法 @Override publicString toString() { return "User{" + "id=" + id +", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; }}UserMapper类使用注解方法操作数据库@Mapperpublic interface UserMapper {@Select("SELECT * FROM user WHERE id =#{id}") User findById(int id);}3.MyRedisConfig自定义序列化类,将存储在Redis的对象序列化为json格式,不会产生乱码@Configuration@EnableAutoConfigurationpublic class MyRedisConfig {@Beanpublic RedisTemplate<Object, User> redisTemplate(RedisConnectionFactory redisConnectionFactory){ RedisTemplate<Object, User> template = newRedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory);Jackson2JsonRedisSerializer<User> ser = newJackson2JsonRedisSerializer<>(User.class);template.setDefaultSerializer(ser); return template; }}4.工具类RedisUtil类//工具类中使用Autowired注解需要加上Compoent@Componentpublic class RedisUtil{@Autowired RedisTemplate redisTemplate; //key-value是对象的 //判断是否存在key public boolean hasKey(String key){ returnredisTemplate.hasKey(key); } //从redis中获取值 public Object get(String key){ return redisTemplate.opsForValue().get(key); } //向redis插入值 public boolean set(final String key,Object value){ boolean result = false; try{ redisTemplate.opsForValue().set(key,value); result = true; }catch (Exceptione){ e.printStackTrace(); } return result; }}5.sevice包代码IUserService@Servicepublic interface IUserService {//根据id查用户信息 UserfindById(int id);}UserService实现类@Servicepublic class UserServiceImpl implements IUserService {User user;@Autowired UserMapper userMapper; @Autowired private RedisUtil redisUtil; @Override public User findById(int id) { String key = "user"+id;if(redisUtil.hasKey(key)) { user = (User)redisUtil.get(key); System.out.println("查询的是缓存"); }else{ user =userMapper.findById(id); System.out.println("查询的是数据库"); System.out.println(redisUtil.set(key,user) ? "插入成功" : "插入失败"); } return user; }}erController类@RestControllerpublic class UserController {@Autowired IUserService userService; @GetMapping("/user/{id}") public UserfindById(@PathVariable("id") Integer id){ User user =userService.findById(id); return user; }}7.测试打开浏览器输入下方url查看控制台输出Redis Desktop Manager显示结果六、总结整体来说,操作Redis是两个类,RedisTemplate类和StringTemplate类,为父子关系,提供的方法正好对应操作Redis数据类型的指令,所以要把数据类型及常用的指令练熟。

SpringBoot+SpringCache实现两级缓存(Redis+Caffeine)

SpringBoot+SpringCache实现两级缓存(Redis+Caffeine)

SpringBoot+SpringCache实现两级缓存(Redis+Caffeine)1. 缓存、两级缓存1.1 内容说明Spring cache:主要包含spring cache定义的接⼝⽅法说明和注解中的属性说明springboot+spring cache:rediscache实现中的缺陷caffeine简介spring boot+spring cache实现两级缓存使⽤缓存时的流程图1.2 Sping Cachespring cache是spring-context包中提供的基于注解⽅式使⽤的缓存组件,定义了⼀些标准接⼝,通过实现这些接⼝,就可以通过在⽅法上增加注解来实现缓存。

这样就能够避免缓存代码与业务处理耦合在⼀起的问题。

spring cache的实现是使⽤spring aop中对⽅法切⾯(MethodInterceptor)封装的扩展,当然spring aop也是基于Aspect来实现的。

spring cache核⼼的接⼝就两个:Cache和CacheManager1.2.1 Cache接⼝提供缓存的具体操作,⽐如缓存的放⼊,读取,清理,spring框架中默认提供的实现有1.2.2 CacheManager接⼝主要提供Cache实现bean的创建,每个应⽤⾥可以通过cacheName来对Cache进⾏隔离,每个CaheName对应⼀个Cache实现,spring框架中默认提供的实现与Cache的实现都是成对出现的1.2.3 常⽤的注解说明@Cacheable:主要应⽤到查询数据的⽅法上@CacheEvict:清除缓存,主要应⽤到删除数据的⽅法上@CachePut:放⼊缓存,主要⽤到对数据有更新的⽅法上@Caching:⽤于在⼀个⽅法上配置多种注解@EnableCaching:启⽤spring cache缓存,作为总的开关,在spring boot的启动类或配置类上需要加⼊次注解才会⽣效2.实战多级缓存的⽤法package com.xfgg.demo.config;import lombok.AllArgsConstructor;import com.github.benmanes.caffeine.cache.Caffeine;import org.springframework.cache.CacheManager;import org.springframework.cache.caffeine.CaffeineCacheManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.concurrent.TimeUnit;@Configuration@AllArgsConstructor//把定义的缓存加⼊到Caffeine中public class CacheConfig {@Beanpublic CacheManager cacheManager(){CaffeineCacheManager cacheManager = new CaffeineCacheManager();cacheManager.setCaffeine(Caffeine.newBuilder()//使⽤refreshAfterWrite必须要设置cacheLoader//在5分钟内没有创建/覆盖时,会移除该key,下次取的时候从loading中取【重点:失效、移除Key、失效后需要获取新值】.expireAfterWrite(5, TimeUnit.MINUTES)//初始容量.initialCapacity(10)//⽤来控制cache的最⼤缓存数量.maximumSize(150));return cacheManager;}}package com.xfgg.demo.config;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.connection.RedisPassword;import org.springframework.data.redis.connection.RedisStandaloneConfiguration;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.StringRedisSerializer;//⽣成的redis连接public class RedisConfig<GenericObjectPoolConfig> {@Value("${spring.redis1.host}")private String host;@Value("${spring.redis1.port}")private Integer port;@Value("${spring.redis1.password}")private String password;@Value("${spring.redis1.database}")private Integer database;@Value("${spring.redis1.lettuce.pool.max-active}")private Integer maxActive;@Value("${spring.redis1.lettuce.pool.max-idle}")private Integer maxIdle;@Value("${spring.redis1.lettuce.pool.max-wait}")private Long maxWait;@Value("${spring.redis1.lettuce.pool.min-idle}")private Integer minIdle;@Beanpublic RedisStandaloneConfiguration redis1RedisConfig() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setHostName(host);config.setPassword(RedisPassword.of(password));config.setPort(port);config.setDatabase(database);return config;}//配置序列化器@Beanpublic RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){RedisTemplate<String,Object>template=new RedisTemplate<>();//关联template.setConnectionFactory(factory);//设置key的序列化器template.setKeySerializer(new StringRedisSerializer());//设置value的序列化器template.setValueSerializer(new StringRedisSerializer());return template;}}⼀个使⽤cacheable注解,⼀个使⽤redistemplate进⾏缓存因为公司项⽬中⽤到的是jedis和jediscluster所以这⾥只是做个了解,没有写的很细到此这篇关于SpringBoot+SpringCache实现两级缓存(Redis+Caffeine)的⽂章就介绍到这了,更多相关SpringBoot SpringCache两级缓存内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

mybatis二级缓存的用法

mybatis二级缓存的用法

MyBatis二级缓存的用法什么是MyBatis二级缓存?在理解MyBatis二级缓存之前,我们先来了解一下MyBatis的一级缓存。

MyBatis的一级缓存是指SqlSession级别的缓存,它默认开启,并且是线程私有的。

也就是说,在同一个SqlSession中执行相同的SQL语句,第一次查询会将查询结果放入缓存中,后续再执行相同的SQL语句时,直接从缓存中获取结果,而不需要再去数据库查询。

而MyBatis的二级缓存则是SqlSessionFactory级别的缓存,它可以被多个SqlSession共享。

当多个SqlSession共享同一个SqlSessionFactory时,如果其中一个SqlSession执行了查询操作并将结果放入了二级缓存中,在后续其他SqlSession执行相同的查询操作时,可以直接从二级缓存中获取结果。

如何配置MyBatis二级缓存?要使用MyBatis二级缓存,我们需要进行以下几个步骤:1.在MyBatis配置文件(例如mybatis-config.xml)中开启二级缓存:<configuration><settings><setting name="cacheEnabled" value="true"/></settings></configuration>2.在需要使用二级缓存的Mapper接口上添加@CacheNamespace注解:@CacheNamespacepublic interface UserMapper {// ...}3.在需要进行缓存的查询语句上添加@Options注解,设置useCache属性为true:@Select("SELECT * FROM user WHERE id = #{id}")@Options(useCache = true)User getUserById(Long id);经过以上配置,我们就可以开始使用MyBatis的二级缓存了。

分布式学习笔记redis二级缓存

分布式学习笔记redis二级缓存

13 14 15 16 17 18 19 20 21 22 23 24 25 }
context= applicationContext; }
//泛型方法 public static <T> T getBean(Class<T> aClass){
return context.getBean(aClass); }
26
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
27
28
29
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
30
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
7
eviction="FIFO" :驱逐策略 清除册率
8
9 -->
10
<cache flushInterval=""/>
3、设置类实现序列化的接口
实现二级缓存的类要实现Cache接口,mybatis提供的有默认的实现
1 public interface Cache {
2
//id
3
String getId();
14
Dept dept = mapper.queryById(1);
15
System.out.println("查询:");
16
System.out.println(dept);
17
//session关闭才会将数据存入二级缓存

SpringBoot下mybatis-一级、二级缓存测试及总结

SpringBoot下mybatis-一级、二级缓存测试及总结

一、默认开启一级缓存。

一级缓存是 SqlSession 级别的。

具体什么意思测试一下。

一次事务中,同一语句调用两次,代码:VarDateEntity varDateEntity = dateMapper.getVarDate();System.out.println("var1 var:"+varDateEntity.getVarTime());System.out.println("var1 not:"+varDateEntity.getNotTime());System.out.println("var1 null:"+varDateEntity.getNullTime());varDateEntity = dateMapper.getVarDate();System.out.println("var2 var:"+varDateEntity.getVarTime());System.out.println("var2 not:"+varDateEntity.getNotTime());System.out.println("var2 null:"+varDateEntity.getNullTime());Postman 中执行两次:测试结果:结论1:同一事务中的两次查询,只查询了一次。

但是两次事务中,每次均进行了一次查询;一级缓存的 scope 默认值session;设置为:statment 。

重启 springboot 应用再次测试:结论2:设置mybatis.configuration.local-cache-scope=statement后,即使 xmxxxxl 语句中配置useCache="true",一级缓存均失效。

总结:•Mybatis一级缓存的生命周期和SqlSession一致。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

22
23
}
24 }
5、创建myabtis 中的Cache接口的实现类
1 //将数据存入到Redis中,删除、获取
2 public class RedisCache implements Cache {
3
4
5
//创建一个重入锁 的对象:防止线程并发带来的资源争抢
6
private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
/** * 获取该命名空间下的key的数量 * @return */
@Override public int getSize() {
return getRedisTemplate().keys("*" + id + "*").size(); }
@Override public ReadWriteLock getReadWriteLock() {
56
ValueOperations ops = getRedisTemplate().opsForValue();
57
return ops.get(key.toString());
58
}
59
return null;
60
}
61
62
/**
63
* 删除指定的key
64
* @param key
65
* @return
1、开启二级缓存
2、linux服务器上启动redis服务 3、配置连接信息
4、默认可以直接使用RedisTemplate,注入就可以使用,需要配置下序列化方式,转换成json序列化
1 @Configuration
2 public class RedisConfig {
3
@Bean
4
public RedisTemplate redisTemplate(RedisConnectionFactory
Redis实现mybatis的二级缓存
0:引入jar
1 <dependency>
2
<groupId>org.springframework.boot</groupId>
3
<artifactId>spring-boot-starter-data-redis</artifactId>
4 </dependency>
7
8
//Spring中封装的用来操作redis的一个工具类,连接,支持redis中的个中命令
9
private RedisTemplate redisTemplate;
10
11
public RedisTemplate getRedisTemplate() {
12
if(redisTemplate==null){
}
6、确定要开启二级缓存的命名空间
7、测试 测试查询, 测试:修改、删除、增加
connectionFactory){
5
//创建实例
6
RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
7
//配置连接对象
8
redisTemplate.setConnectionFactory(connectionFactory);
* @param key

37
* @param value

38
*/
39
@Override
40
public void putObject(Object key, Object value) {
41
if(key!=null){
42
ValueOperations ops = getRedisTemplate().opsForValue();
* @param id
24
*/
25
public RedisCache(String id) {
26
this.id = id;
27
}
28
29
@Override
30
public String getId() {
31
return this.id;
32
}
33
34
/**
35
* 将数据存入缓存:redis
36
76
* 清空该命名空间下所有的key
77
*/
78
@Override
79
public void clear() {
80
Set keys = getRedisTemplate().keys("*" + id + "*");
81
getRedisTemplate().delete(keys);
82
}
83
84 85 86 87 88 89 90 91 92 93 94 95 96 97 }
13
redisTemplate=ApplicatonContextHolder.getBean("redisTemplate");
14
}
15
return redisTemplate;
16
}
17
18
//命名空间的标识
19
private String id;
20
21
/**
22
* 构造方法:初始化iD
23
return readWriteLock; }
准备工具类ApplicationContextHolder:获取到指定的bean
1 //ApplicationContextAware:获取到上下文对象
2 public class ApplicatonContextHolder implements ApplicationContextAware {
13
ObjectMapper mapper=new ObjectMapper();
14
mapper.setVisibility(PropertyAccessor.FIELD,
JsonAutoDetect.Visibility.NON_PRIVATE);
15
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
17
* public <类型占位符:T> T
18
* @param tClass
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 }
* @return */ public static <T> T getBean(Class<T> tClass){
9
//key:使用字符串序列化
10
redisTemplate.setKeySerializer(new StringRedisSerializer());
11
12
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer=new
Jackson2JsonRedisSerializer<Object>(Object.class);
return ctx.getBean(tClass); }
/** * 根据名字获取bean * @param beanName * @param <T> * @return */
public static <T> T getBean(String beanName){ return (T) ctx.getBean(beanName);
66
*/
67
@Override
68
public Object removeObject(Object key) {
69
if(key!=null){
70
return getRedisTemplate().delete(key.toString());
71
}
72
return null;
73
}
74
75
/**
16
jackson2JsonRedisSerializer.setObjectMapper(mapper);
17
18
//value:值得序列化方式
19
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
20
21
return redisTemplate;
applicationContext) throws BeansException {
11
//实例方法可以直接操作静态属性
12
ctx=applicationContext;
13
}
14
15
/**
16
* 泛型方法:方法的返回类型或者是参数的数据类型,都可以在定义时用占位符来代替,实际调
用时指定具体的数据类型
3
private static ApplicationContext ctx;
4
/**
5
* 注入上下文对象
6
* @param applicationContext
7
相关文档
最新文档