docker安装redis连接redis可视化工具Redis Desktop Manager+springboot项目使用Cache缓存+springboot项目整合 Redis 实现缓存
今天进一步学习了redis的相关知识,希望下面的博客可以给博友们带来帮助。
docker安装redis连接Redis Desktop Manager
启动docker (系统控制ctl:control) systemctl start docker 查找Docker Hub上的redis镜像 docker search redis 这里我们拉取官方的默认redis镜像 docker pull redis 查询已有的镜像 docker images 使用redis镜像 运行容器 docker run -p 6379:6379 -d redis 命令说明: -p 6379:6379 : 将容器的6379端口映射到主机的6379端口 查看容器启动情况 docker ps 连接、查看容器,使用redis镜像执行redis-cli命令连接到刚启动的容器,主机IP为127.0.0.1 docker exec -it 43f7a65ec7f8 redis-cli 127.0.0.1:6379> info
打开redis可视化工具Redis Desktop Manager
连接本地redis
redis中文网 http://redis.cn/ 可以查看redis命令等
springboot项目使用Cache缓存
一.Cache缓存的作用
大规模的数据库查询操作会成为影响用户使用体验的瓶颈,此时Cache缓存往往是解决这一问题非常好的手段之一。
1.JSR107
Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
示意图:
CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可 以在运行期访问多个CachingProvider。 CacheManager定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache 存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。 Cache是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个 CacheManager所拥有。 Entry是一个存储在Cache中的key-value对。 Expiry 每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期 的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。
2.Spring缓存抽象
Spring从3.1开始定义了org.springframework.cache.Cache 和org.springframework.cache.CacheManager接口来统一不同的缓存技术; 并支持使用JCache(JSR-107)注解简化我们开发。 Cache接口为缓存的组件规范定义,包含缓存的各种操作集合。 Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache , ConcurrentMapCache。 每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否 已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法 并缓存结果后返回给用户。下次调用直接从缓存中获取。 使用Spring缓存抽象时我们需要关注以下两点: 1.、确定方法需要被缓存以及他们的缓存策略 Spring从3.1开始定义了org.springframework.cache.Cache 和org.springframework.cache.CacheManager接口来统一不同的缓存技术; 并支持使用JCache(JSR-107)注解简化我们开发。 Cache接口为缓存的组件规范定义,包含缓存的各种操作集合。 Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache , ConcurrentMapCache。 每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否 已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法 并缓存结果后返回给用户。下次调用直接从缓存中获取。 使用Spring缓存抽象时我们需要关注以下两点: 1.确定方法需要被缓存以及他们的缓存策略 2、从缓存中读取之前缓存存储的数据
二.几个重要概念&缓存注解
三.SpringBoot中Cache缓存的使用
1.引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
2.在配置文件中设置属性debug=true,这样就会打印所有的配置报告。
logging: level: com.szh.springboot_redis.mapper.*: debug debug: true
2.@EnableCaching开启缓存
@MapperScan(basePackages = {"com.szh.springboot_redis.mapper"}) @SpringBootApplication @EnableCaching // 开启缓存注解 public class SpringbootRedisApplication { public static void main(String[] args) { SpringApplication.run(SpringbootRedisApplication.class, args); } }
3.@Cacheable缓存注解的使用 (标注在service业务层方法上)
执行流程:先执行@Cacheable注解中的getCache(String name)方法,根据name判断ConcurrentMap中是否有此缓存,如果没有缓存那么创建缓存并保存数据,另外service层的方法也会执行。如果有缓存不再创建缓存,另外service层的方法也不会执行。
总结:先执行@Cacheable----->再执行service层的方法
@Cacheable注解的属性如下:
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Cacheable { @AliasFor("cacheNames") String[] value() default {}; @AliasFor("value") String[] cacheNames() default {}; String key() default ""; String keyGenerator() default ""; String cacheManager() default ""; String cacheResolver() default ""; String condition() default ""; String unless() default ""; boolean sync() default false; }
service层代码
第一次查询数据库打印service类方法日志,并把数据保存到Cahce中
第二次传入相同参数不再执行service类方法,不会打印日志,查询的数据直接从缓存中获取
@Service @CacheConfig(cacheNames = "person") //将cacheNames抽取出来 public class PersonService { @Autowired PersonDao personDao; /*1. @Cacheable的几个属性详解: * cacheNames/value:指定缓存组件的名字 * key:缓存数据使用的key,可以用它来指定。默认使用方法参数的值,一般不需要指定 * keyGenerator:作用和key一样,二选一 * cacheManager和cacheResolver作用相同:指定缓存管理器,二选一 * condition:指定符合条件才缓存,比如:condition="#id>3" * 也就是说传入的参数id>3才缓存数据 * unless:否定缓存,当unless为true时不缓存,可以获取方法结果进行判断 * sync:是否使用异步模式*/ //@Cacheable(cacheNames= "person") //@Cacheable(cacheNames= "person",key="#id",condition="#id>3") @Cacheable(key="#id") public Person queryPersonById(Integer id){ System.out.println("查询"+id+"号员工信息"); Person person=new Person(); person.setId(id); return personDao.query(person); } /** * @CachePut:即调用方法,又更新缓存数据 * 修改了数据库中的数据,同时又更新了缓存 * *运行时机: * 1.先调用目标方法 * 2.将目标方法返回的结果缓存起来 * * 测试步骤: * 1.查询1号的个人信息 * 2.以后查询还是之前的结果 * 3.更新1号的个人信息 * 4.查询一号员工返回的结果是什么? * 应该是更新后的员工 * 但只更新了数据库,但没有更新缓存是什么原因? * 5.如何解决缓存和数据库同步更新? * 这样写:@CachePut(cacheNames = "person",key = "#person.id") * @CachePut(cacheNames = "person",key = "#result.id") */ @CachePut(key = "#result.id") public Person updatePerson(Person person){ System.out.println("修改"+person.getId()+"号员工信息"); personDao.update(person); return person; } /** * @CacheEvict:清除缓存 * 1.key:指定要清除缓存中的某条数据 * 2.allEntries=true:删除缓存中的所有数据 * beforeInvocation=false:默认是在方法之后执行清除缓存 * 3.beforeInvocation=true:现在是在方法执行之前执行清除缓存, * 作用是:只清除缓存、不删除数据库数据 */ //@CacheEvict(cacheNames = "person",key = "#id") @CacheEvict(cacheNames = "person",allEntries=true) public void deletePerson(Integer id){ System.out.println("删除"+id+"号个人信息"); //删除数据库数据的同时删除缓存数据 //personDao.delete(id); /** * beforeInvocation=true * 使用在方法之前执行的好处: * 1.如果方法出现异常,缓存依旧会被删除 */ //int a=1/0; } /** * @Caching是 @Cacheable、@CachePut、@CacheEvict注解的组合 * 以下注解的含义: * 1.当使用指定名字查询数据库后,数据保存到缓存 * 2.现在使用id、age就会直接查询缓存,而不是查询数据库 */ @Caching( cacheable = {@Cacheable(key="#name")}, put={ @CachePut(key = "#result.id"), @CachePut(key = "#result.age") } ) public Person queryPersonByName(String name){ System.out.println("查询的姓名:"+name); return personDao.queryByName(name); } }
springboot项目整合 Redis 实现缓存操作
缓存大致流程
springboot-mybatis-redis 案例
pom.xml 依赖配置:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- Spring Boot 启动父依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.szh</groupId> <artifactId>springboot_redis</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot_redis</name> <!--整合 Mybatis 并使用 Redis 作为缓存--> <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-cache</artifactId> </dependency>--> <!-- Spring Boot Reids 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</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.0.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.1.8.RELEASE</version> <scope>compile</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.yml 应用配置文件,增加 Redis 相关配置
server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/first?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: root redis: host: 192.168.72.129 ##Redis服务器地址 port: 6379 ## Redis服务器连接端口 database: 0 ## Redis数据库索引(默认为0) logging: level: com.szh.springboot_redis.mapper.*: debug debug: true
实体类这里就不细写了,各位小伙伴就根据自己相应的数据库来编写吧。
Service业务逻辑层
package com.szh.springboot_redis.service; import com.szh.springboot_redis.pojo.Students; import java.util.List; public interface StudentService { /** * 查询所有信息 * @return */ List<Students> findAllStudnet(); /** * 删除指定信息 * @param id * @return */ int delStudent(Integer id); /** * 修改指定信息 * @param students * @return */ int updateStudent(Students students); /** * 根据id查询 * @param id * @return */ Students findStudentById(Integer id); }
业务逻辑实现类 StudnetServiceImpl .java:
package com.szh.springboot_redis.service.impl; import com.szh.springboot_redis.mapper.StudentMapper; import com.szh.springboot_redis.pojo.Students; import com.szh.springboot_redis.service.StudentService; 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 java.util.List; @Service public class StudnetServiceImpl implements StudentService { @Autowired private StudentMapper studentMapper; @Autowired private RedisTemplate redisTemplate; /** * 查询所有信息 * @return */ @Override public List<Students> findAllStudnet() { String key = "student"; ValueOperations<String, List<Students>> operations = redisTemplate.opsForValue(); // 缓存存在 boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { List<Students> students = operations.get(key); return students; }else { // 从 DB 中获取城市信息 List<Students> students = studentMapper.findAllStudnet(); // 插入缓存 operations.set(key, students); return students; } } /** * 根据id查询信息 * @param id * @return */ @Override public Students findStudentById(Integer id) { String key = "city_" + id; ValueOperations<String, Students> operations = redisTemplate.opsForValue(); // 缓存存在 boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { Students students = operations.get(key); return students; }else { // 从 DB 中获取城市信息 Students students = studentMapper.findStudentById(id); // 插入缓存 operations.set(key, students); return students; } } /** * 删除指定信息 * @param id * @return */ @Override public int delStudent(Integer id) { int ret = studentMapper.delStudent(id); // 缓存存在,删除缓存 String key = "studnet_" + id; boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { redisTemplate.delete(key); } return ret; } /** * 修改指定信息 * @param students * @return */ @Override public int updateStudent(Students students) { int ret = studentMapper.updateStudent(students); // 缓存存在,删除缓存 String key = "students_" + students.getSid(); boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { redisTemplate.delete(key); } return ret; } }
Controller层
StudentController.java类
package com.szh.springboot_redis.controller; import com.szh.springboot_redis.pojo.Students; import com.szh.springboot_redis.service.StudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController public class StudentController { @Autowired StudentService studentService; /** * 查询所有信息 * @return */ @GetMapping("/select") public List<Students> findStudents(){ List<Students> students = studentService.findAllStudnet(); return students; } /** * 根据id查询信息 * @param id * @return */ @GetMapping("/select/{id}") public Students selStudentId(@PathVariable("id") Integer id){ Students student = studentService.findStudentById(id); return student; } /** * 修改信息 * @param student * @return */ @PutMapping("/update") public int update(Students student) { return studentService.updateStudent(student); } /** * 删除信息 * @param id * @return */ @DeleteMapping("delete") public int delete(Integer id) { return studentService.delStudent(id); } }
修改springboot中redis配置中的修改RedisTemplate 默认的序列化规则,将缓存序列化。
配置config文件
RedisConfig.java类
package com.szh.springboot_redis.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig{ @Bean @SuppressWarnings("all") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); template.setConnectionFactory(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key采用String的序列化方式 template.setKeySerializer(stringRedisSerializer); // hash的key也采用String的序列化方式 template.setHashKeySerializer(stringRedisSerializer); // value序列化方式采用jackson template.setValueSerializer(jackson2JsonRedisSerializer); // hash的value序列化方式采用jackson template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }
运行
测试
第一次查询是用sql语句从mysql数据库中查询出数据
第二次直接从缓存中拿数据
redis的可视化工具Redis Desktop Manager查看
大功告成!
希望本博客可以给大家带来帮助。
记得点关注,评论哦!
- 使用 SpringBoot 之 JPA 整合 Redis 实现缓存
- 使用IDEA创建Spring Boot项目, 整合Mybatis ,连接MySql数据库,实现简单的登录注册功能
- 使用Redis作为SpringBoot项目数据缓存
- SpringBoot+Mybatis项目使用Redis做Mybatis的二级缓存
- Docker 部署 SpringBoot 项目整合 Redis 镜像做访问计数Demo
- springboot2.x整合redis实现缓存(附github链接)
- 10、Spring技术栈-整合Redis,使用RedisTemplate实现数据缓存实战
- SpringBoot中使用Redis实现缓存
- [置顶] 安装docker-compose 并且发布spring boot整合redis做访问计数demo
- Docker 部署 SpringBoot 项目整合 Redis 镜像做访问计数Demo
- centos7使用docker命令安装java-1.8 + tomcat + mysql+部署springboot项目
- Spring Boot 整合 Redis 实现缓存操作
- Spring Boot 整合 Redis 实现缓存操作
- SpringBoot+Mybatis项目使用Redis做Mybatis的二级缓存的方法
- Docker入门实践笔记(三)一篇文章搞懂Docker下安装Redis,以及Redis与SpringBoot整合
- Docker 部署 SpringBoot 项目整合 Redis 镜像做访问计数Demo
- Redis使用(二):SpringBoot整合Redis 配置文件及项目种简单应用
- SpringBoot整合ehcache和redis实现二级缓存
- SpringBoot整合Redis使用Restful风格实现CRUD功能
- springboot项目使用redis数据库作缓存