SpringBoot整合Redis入门之缓存数据

x33g5p2x  于2021-11-16 转载在 Spring  
字(5.4k)|赞(0)|评价(0)|浏览(642)

前言

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。

为什么要使用Redis呢?

举个例子,假如系统中有2千万用户信息,用户信息基本固定,一旦录入很少变动,那么你每次加载所有用户信息时,如果都要请求数据库,数据库编译并执行你的查询语句,这样效率就会低下很多,针对这种信息不经常变动并且数据量。

较大的情况,通常做法,就是把他加入缓存,每次取数前先去判断,如果缓存不为空,那么就从缓存取值,如果为空,再去请求数据库,并将数据加入缓存,这样大大提高系统访问效率。

相关依赖

  1. <!-- springboot版本 -->
  2. <parent>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-parent</artifactId>
  5. <version>2.2.7.RELEASE</version>
  6. </parent>
  7. <!-- 依赖 -->
  8. <dependencies>
  9. <!-- redis -->
  10. <dependency>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-starter-data-redis</artifactId>
  13. </dependency>
  14. <!-- 通用池 -->
  15. <dependency>
  16. <groupId>org.apache.commons</groupId>
  17. <artifactId>commons-pool2</artifactId>
  18. </dependency>
  19. <!-- mysql -->
  20. <dependency>
  21. <groupId>mysql</groupId>
  22. <artifactId>mysql-connector-java</artifactId>
  23. </dependency>
  24. <!-- mybatis -->
  25. <dependency>
  26. <groupId>org.mybatis.spring.boot</groupId>
  27. <artifactId>mybatis-spring-boot-starter</artifactId>
  28. <version>2.1.1</version>
  29. </dependency>
  30. <!-- 通用mapper -->
  31. <dependency>
  32. <groupId>tk.mybatis</groupId>
  33. <artifactId>mapper-spring-boot-starter</artifactId>
  34. <version>2.1.5</version>
  35. </dependency>
  36. <!-- lombok -->
  37. <dependency>
  38. <groupId>org.projectlombok</groupId>
  39. <artifactId>lombok</artifactId>
  40. </dependency>
  41. <!-- test -->
  42. <dependency>
  43. <groupId>org.springframework.boot</groupId>
  44. <artifactId>spring-boot-starter-test</artifactId>
  45. </dependency>
  46. </dependencies>

配置

  1. # 端口
  2. server:
  3. port: 9998
  4. # mysql数据源
  5. spring:
  6. datasource:
  7. username: root
  8. password: root
  9. url: jdbc:mysql://127.0.0.1:3306/dbtest?serverTimezone=GMT%2B8
  10. # redis
  11. redis:
  12. host: localhost
  13. port: 6379
  14. timeout: 1000
  15. jedis:
  16. pool:
  17. min-idle: 5
  18. max-idle: 10
  19. max-wait: -1
  20. # mybatis
  21. mybatis:
  22. mapper-locations: classpath:/mybatis/mapper/*.xml
  23. type-aliases-package: cn.kgc.entities
  24. # 开启驼峰命名
  25. configuration:
  26. map-underscore-to-camel-case: true
  27. # log
  28. logging:
  29. level:
  30. cn.kgc: debug

数据库

  1. #建表
  2. CREATE TABLE `emp` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  5. `age` int(11) NULL DEFAULT NULL,
  6. PRIMARY KEY (`id`) USING BTREE
  7. ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  8. #插入数据
  9. INSERT INTO `emp` VALUES (1, '张三', 18);
  10. INSERT INTO `emp` VALUES (2, '李四', 20);
  11. INSERT INTO `emp` VALUES (3, '王五', 22);

实体类

Emp

  1. @Data
  2. @Table(name = "emp")
  3. public class Emp implements Serializable {
  4. @Id
  5. @GeneratedValue(strategy = GenerationType.IDENTITY)
  6. private Integer id;
  7. private String name;
  8. private Integer age;
  9. }

RedisConfig

指定Redis序列化方式

  1. @Configuration
  2. public class RedisConfig {
  3. @Bean
  4. public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
  5. RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
  6. redisTemplate.setConnectionFactory(factory);
  7. // 指定kv的序列化方式
  8. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
  9. redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
  10. redisTemplate.setKeySerializer(new StringRedisSerializer());
  11. return redisTemplate;
  12. }
  13. }

Mapper

Emp的Mapper接口继承tk的Mapper类,泛型为实体类Emp

  1. public interface EmpMapper extends Mapper<Emp> {
  2. }

Service接口

业务接口定义add添加和getEmpById根据id查询的方法

  1. public interface EmpService {
  2. public void add(Emp emp);
  3. public Object getEmpById(Integer id);
  4. }

Service实现类

先查Redis,Redis没有数据再从数据库中拿数据,同时缓存到Redis中。

  1. @Service
  2. @Slf4j
  3. public class EmpServiceImpl implements EmpService {
  4. @Autowired
  5. public RedisTemplate redisTemplate;
  6. @Resource
  7. private EmpMapper empMapper;
  8. @Override
  9. public void add(Emp emp) {
  10. empMapper.insert(emp);
  11. }
  12. @Override
  13. public Object getEmpById(Integer id) {
  14. // 先从缓存获取数据,如果有则直接返回
  15. // 如果无,则查询mysql,并将数据设置到缓存
  16. String key = "user:" + id;
  17. Object userObj = redisTemplate.opsForValue().get(key);
  18. if(userObj == null){
  19. synchronized (this.getClass()){
  20. userObj = redisTemplate.opsForValue().get(key);
  21. if(userObj == null ){
  22. log.debug("----> 查询数据库..............");
  23. // 查数据库
  24. Emp emp = empMapper.selectByPrimaryKey(id);
  25. redisTemplate.opsForValue().set(key,emp);
  26. return emp;
  27. }else{
  28. log.debug("----> 查询缓存(同步代码块)>>>>>>>>>>>>>>>>>");
  29. return userObj;
  30. }
  31. }
  32. }else{
  33. log.debug("----> 查询缓存>>>>>>>>>>>>>>>>>");
  34. }
  35. return userObj;
  36. }
  37. }

测试Redis

Redis-Controller

  1. @RestController
  2. public class RedisContoller {
  3. @Autowired
  4. private RedisTemplate redisTemplate;
  5. @GetMapping("/redis/get/{key}")
  6. public Object get(@PathVariable("key") String key){
  7. return redisTemplate.opsForValue().get(key);
  8. }
  9. @PostMapping("/redis/set/{key}/{value}")
  10. public Object set(@PathVariable("key") String key,
  11. @PathVariable("value") String value){
  12. redisTemplate.opsForValue().set(key,value);
  13. return "set success";
  14. }
  15. }

Controller

Redis+MySQL

  1. @RestController
  2. public class EmpController {
  3. @Autowired
  4. private EmpService empService;
  5. @PostMapping("/emp")
  6. public String addEmp(Emp emp){
  7. empService.add(emp);
  8. return "add ok";
  9. }
  10. @GetMapping("/emp/{id}")
  11. public Object getEmpById(@PathVariable("id") Integer id){
  12. ExecutorService es = Executors.newFixedThreadPool(200);
  13. for(int i=0 ;i<500;i++){
  14. es.submit(new Runnable() {
  15. @Override
  16. public void run() {
  17. empService.getEmpById(id);
  18. }
  19. });
  20. }
  21. return empService.getEmpById(id);
  22. }
  23. }

相关文章