SpringBoot整合Redis以及Redis的序列化
2020-03-10 00:06
639 查看
一、搭建基本环境
1、导入数据库文件 创建department和employee表
SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS `department`; CREATE TABLE `department` ( `id` int(11) NOT NULL AUTO_INCREMENT, `departmentName` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `employee`; CREATE TABLE `employee` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lastName` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `gender` int(2) DEFAULT NULL, `d_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; INSERT INTO `employee` VALUES ('1', '李四', 'lisi@111.com', '1', '1'); INSERT INTO `employee` VALUES ('2', '张三', '123@123.com', '1', '1');
2、创建javabean封装数据
Department .java
package com.wzw.cache.bean; public class Department { private Integer id; private String departmentName; public Department() { super(); // TODO Auto-generated constructor stub } public Department(Integer id, String departmentName) { super(); this.id = id; this.departmentName = departmentName; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } @Override public String toString() { return "Department [id=" + id + ", departmentName=" + departmentName + "]"; } }
Employee .java
package com.wzw.cache.bean; import java.io.Serializable; public class Employee implements Serializable { private Integer id; private String lastName; private String email; private Integer gender; //性别 1男 0女 private Integer dId; public Employee() { super(); } public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) { super(); this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; this.dId = dId; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getGender() { return gender; } public void setGender(Integer gender) { this.gender = gender; } public Integer getdId() { return dId; } public void setdId(Integer dId) { this.dId = dId; } @Override public String toString() { return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId=" + dId + "]"; } }
3、整合Mybatis操作数据库
1)POM中导入需要的依赖,配置数据源信息
pom文件
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <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> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <scope>runtime</scope> </dependency>
properties配置文件
spring.datasource.url=jdbc:mysql://localhost:3306/spring_cache?serverTimezone=UTC //不加serverTimezone=UTC的话,运行时会时区报错 spring.datasource.username=root spring.datasource.password=root
2)使用注解版的Mybatis
在SpringBoot启动类加上@MapperScan,指定需要扫描的mapper接口所在的包
二、给需要缓存的类加上注解
1、开启基于注解的缓存@EnableCaching
SpringBoot启动类加上开启注解@EnableCaching
2、标注缓存注解
@Cacheable
/** * 将方法的运行结果进行缓存,以后再有相同的数据就直接从缓存中取,不再调用方法 * CacheManager管理多个Cache组件,对缓存的CRUD操作在Cache组件中,每一个缓存组件有自己唯一的名字 * @Cacheable的几个属性 * value/cacheNames:指定缓存组件的名称,将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存 * key:缓存数据使用的Key,可以用它来指定,key默认是使用方法参数的值,value它的值就是方法的返回值 * 编写SpEL:#id:参数id的值 #root.args[0]:第0个参数的值 * key = "#root.methodName+'['+#id+']'"————key的值就是getEmp[2] * keyGenerator:key的生成器,可以自己指定key的生成器的组件Id * keyGenerator/key:二选一使用 * cacheManager:指定缓存管理器,或者cacheResolver指定缓存解析器 * cacheManagercacheResolver/二选一 * condition:指定符合条件的情况下才缓存 condition = "#id>0":#id大于0才缓存 * unless:否定缓存;当unless指定条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断 * unless="#result==null" * sync:是否使用异步模式 * @param id * @return */ @Cacheable(cacheNames = "emp"/*,keyGenerator = "myKeyGenerator",condition = "#a0>1",unless = "#a0==2"*/) public Employee getEmp(Integer id){ System.out.println("查询"+id+"号员工"); return employeeMapper.getEmpById(id); }
@CachePut
/** * @CachePut :既调用方法又更新缓存,修改了数据库某个数据,同时更新缓存 * 1、先调用目标方法, * 2、将目标方法的结果缓存起来 * 测试: * 1、查询1号员工,结果会存在缓存中 * 2、更新1号员工 * 3、结果没更新 * 因为之前1号员工的key保存的是1,而更新1号员工时,默认的key是employee对象 * 4、指定更新的员工的key * key = "#employee.id",可以从传入的参数的属性取值 * key = "#result.id",这个方法返回了值,也可以从返回值的属性取值 * @param employee * @return */ @CachePut(value = "emp",key = "#employee.id") public Employee updateEmp(Employee employee){ System.out.println("调update方法:"+employee); employeeMapper.updateEmployee(employee); return employee; }
@CacheEvict
/** * @CacheEvict 缓存清除 * allEntries = true:清除emp这个缓存中所有缓存 * beforeInvocation = false:缓存的清除是否在方法之前执行,默认是在方法执行之后执行,如果出现异常,缓存就不会清除 * beforeInvocation = true:代表清除缓存在方法之前运行,无论是否出现异常,缓存都清除 * @param id */ @CacheEvict(value = "emp",allEntries = true) public void deleteEmp(Integer id){ System.out.println("删除员工:"+id); employeeMapper.deleteEmpById(id); }
三、整合Redis作为缓存
1、安装Redis
引入redis的starter
最开始的POM已经引入过了
3、配置redis
这里就配置redis的ip地址即可
spring.redis.host=192.168.43.223
4、测试缓存
编写Mapper接口
package com.wzw.cache.mapper; @Repository public interface EmployeeMapper { @Select("select * from employee where id=#{id}") public Employee getEmpById(Integer id); @Update("update employee set lastName=#{lastName},email=#{email},gender=#{gender},d_id=#{dId} where id=#{id}") public void updateEmployee(Employee employee); @Delete("delete from employee where id=#{id}") public void deleteEmpById(Integer id); @Options(useGeneratedKeys = true,keyProperty = "id") @Insert("insert into employee(lastName,email,gender,d_id) values(#{lastName},#{email},#{gender},#{dId})") public void insertUser(Employee employee); @Select("select * from employee where lastName=#{lastName}") Employee getEmpByLastName(String lastName); }
引入redis的starter,CacheManager就会变为RedisCacheManager,直接保存在Redis中。
package com.wzw.cache; import com.wzw.cache.bean.Employee; import com.wzw.cache.mapper.EmployeeMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; @SpringBootTest class Springboot01CacheApplicationTests { @Autowired EmployeeMapper employeeMapper; @Autowired RedisTemplate redisTemplate; //操作k-v都是对象的 @Autowired StringRedisTemplate stringRedisTemplate; //因为操作字符串的比较多,所以单独列出来一个StringRedisTemplate操作k-v都是字符串的 @Autowired RedisTemplate<Object, Employee> empRedisTemplate; /** * redis常见的五大数据类型 * String(字符串) * stringRedisTemplate.opsForValue() * List(列表) * stringRedisTemplate.opsForList() * Set(集合) * stringRedisTemplate.opsForSet() * Hash(散列) * stringRedisTemplate.opsForHash() * ZSet(有序集合) * stringRedisTemplate.opsForZSet() */ @Test void testRedis(){ // stringRedisTemplate.opsForValue().append("key1","value1"); // System.out.println(stringRedisTemplate.opsForValue().get("key1")); stringRedisTemplate.opsForList().leftPushAll("mylist","1","2","3","4"); // System.out.println(stringRedisTemplate.opsForList().range("mylist",0,-1)); } //测试保存对象 @Test void tetRedisObject(){ //默认如果保存对象,使用Jdk序列化机制,序列化后的数据保存到redis中 // redisTemplate.opsForValue().set("emp1",employeeMapper.getEmpById(1)); /** * 1.将数据以json方式保存, * (1)自己将对象转成json * (2)redisTemplate默认的序列化规则,改变默认的序列化规则 */ empRedisTemplate.opsForValue().set("emp1",employeeMapper.getEmpById(1)); System.out.println(empRedisTemplate.opsForValue().get("emp1")); } }
默认保存数据k-v都是Object,利用序列化保存,在Redis Desktop中查看到的是序列化后的结果
默认创建的RedisCacheManager操作Redis的时候使用的是RedisTemplate<Object,Objet>
想要直接在Redis中查看到对象,如下所示,需要编写配置类
编写配置类
@Configuration public class MyRedisConfig extends CachingConfigurerSupport { /** * 配置序列化,作为一个对象存在Redis中,而不是jdk的序列化机制 * * @param redisConnectionFactory * @return * @throws UnknownHostException */ @Bean public RedisTemplate<Object, Employee> empRedisTemplate(RedisConnectionFactory redisConnectionFactory ) throws UnknownHostException { RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>(); template.setConnectionFactory(redisConnectionFactory); // Jackson2JsonRedisSerializer<Employee> ser = new Jackson2JsonRedisSerializer<Employee>(Employee.class); GenericJackson2JsonRedisSerializer ser = new GenericJackson2JsonRedisSerializer(); template.setDefaultSerializer(ser); return template; }
以上是测试的时候通过注入RedisTemplate就能改变默认的jdk序列化,作为一个对象存在Redis中,网页访问需要自定义配置类
自定义配置类
@Configuration public class MyRedisConfig extends CachingConfigurerSupport { /** * 配置序列化,作为一个对象存在Redis中,而不是jdk的序列化机制 * * @param redisConnectionFactory * @return * @throws UnknownHostException */ @Bean public RedisTemplate<Object, Employee> empRedisTemplate(RedisConnectionFactory redisConnectionFactory ) throws UnknownHostException { RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>(); template.setConnectionFactory(redisConnectionFactory); // Jackson2JsonRedisSerializer<Employee> ser = new Jackson2JsonRedisSerializer<Employee>(Employee.class); GenericJackson2JsonRedisSerializer ser = new GenericJackson2JsonRedisSerializer(); template.setDefaultSerializer(ser); return template; } /* springboot2.0已经废弃 @Bean public RedisCacheManager employeeCacheManager(RedisTemplate<Object, Employee> empRedisTemplate){ RedisCacheManager cacheManager=new RedisCacheManager(empRedisTemplate); cacheManager.setUsePrefix(true); }*/ //过期时间1天 private Duration timeToLive = Duration.ofDays(1); @Bean public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) { //默认1 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(this.timeToLive) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())) .disableCachingNullValues(); RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory) .cacheDefaults(config) .transactionAware() .build(); // log.debug("自定义RedisCacheManager加载完成"); return redisCacheManager; } private RedisSerializer<String> keySerializer() { return new StringRedisSerializer(); } private RedisSerializer<Object> valueSerializer() { return new GenericJackson2JsonRedisSerializer(); } }
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- SpringBoot 2.x整合Redis实现RedisTemplate以及缓存
- REDIS学习(4)spring boot redisTemplate 对REDIS的简单封装,以及对引用包的说明,以及对序列化的详细说明
- Docker入门实践笔记(三)一篇文章搞懂Docker下安装Redis,以及Redis与SpringBoot整合
- Spring Boot学习之旅:(六)springboot 整合 redis 以及 redis 通用工具类
- spring-data-redis 整合,以及使用kryo序列化代替jdk原生序列化机制
- SpringBoot整合Redis(附带序列化方式对比)
- SpringBoot整合Redis(附带序列化方式对比)
- spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑
- springboot使用protostuff进行序列化和反序列化整合redis的redisTemplate的各种方法的写法
- 在Springboot中整合Ehcache以及整合Redis
- springboot整合redis进行数据操作(一)
- Spring Boot 整合 Redis 实现缓存操作
- SpringBoot进阶教程(二十八)整合Redis事物
- spring boot整合mybatis、Junit、spring data JPA、redis
- springboot整合redis和Redis工具类
- springboot整合redis
- Spring-boot通过redisTemplate使用redis(无须手动序列化)
- spring-boot 整合redis作为数据缓存
- spring boot 中redis与cookie整合
- SpringBoot整合Redis集群