SpringBoot整合Redis入门之缓存数据的方法


Posted in Redis onNovember 17, 2021

前言

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

为什么要使用Redis呢?

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

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


相关依赖

<!-- springboot版本 -->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.2.7.RELEASE</version>
</parent>
<!-- 依赖 -->
<dependencies>
	<!-- redis -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-redis</artifactId>
	</dependency>
	<!-- 通用池 -->
	<dependency>
		<groupId>org.apache.commons</groupId>
		<artifactId>commons-pool2</artifactId>
	</dependency>
	<!-- mysql -->
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
	</dependency>
	<!-- mybatis -->
		<dependency>
		<groupId>org.mybatis.spring.boot</groupId>
		<artifactId>mybatis-spring-boot-starter</artifactId>
		<version>2.1.1</version>
	</dependency>
	<!-- 通用mapper -->
	<dependency>
		<groupId>tk.mybatis</groupId>
		<artifactId>mapper-spring-boot-starter</artifactId>
		<version>2.1.5</version>
	</dependency>
	<!-- lombok -->
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
	</dependency>
	<!-- test -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
	</dependency>
</dependencies>

配置

# 端口
server:
  port: 9998
# mysql数据源
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/dbtest?serverTimezone=GMT%2B8
# redis
  redis:
    host: localhost
    port: 6379
    timeout: 1000
    jedis:
      pool:
        min-idle: 5
        max-idle: 10
        max-wait: -1
# mybatis
mybatis:
  mapper-locations: classpath:/mybatis/mapper/*.xml
  type-aliases-package: cn.kgc.entities
#  开启驼峰命名
  configuration:
    map-underscore-to-camel-case: true
# log
logging:
  level:
    cn.kgc: debug

数据库

SpringBoot整合Redis入门之缓存数据的方法

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

实体类

Emp

@Data
@Table(name = "emp")
public class Emp implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer age;
}

RedisConfig

指定Redis序列化方式

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);

        // 指定kv的序列化方式
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        return redisTemplate;
    }
}

Mapper

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

public interface EmpMapper extends Mapper<Emp> {

}

Service接口

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

public interface EmpService {
    public void add(Emp emp);
    public Object getEmpById(Integer id);
}

Service实现类

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

@Service
@Slf4j
public class EmpServiceImpl implements EmpService {

    @Autowired
    public RedisTemplate redisTemplate;

    @Resource
    private EmpMapper empMapper;

    @Override
    public void add(Emp emp) {
        empMapper.insert(emp);
    }

    @Override
    public  Object getEmpById(Integer id) {
        // 先从缓存获取数据,如果有则直接返回
        //                   如果无,则查询mysql,并将数据设置到缓存
        String key = "user:" + id;
        Object userObj = redisTemplate.opsForValue().get(key);
        if(userObj == null){
            synchronized (this.getClass()){
                userObj = redisTemplate.opsForValue().get(key);
                if(userObj == null ){
                    log.debug("----> 查询数据库..............");
                    // 查数据库
                    Emp emp = empMapper.selectByPrimaryKey(id);
                    redisTemplate.opsForValue().set(key,emp);
                    return emp;
                }else{
                    log.debug("----> 查询缓存(同步代码块)>>>>>>>>>>>>>>>>>");
                    return userObj;
                }
            }

        }else{
            log.debug("----> 查询缓存>>>>>>>>>>>>>>>>>");
        }
        return userObj;
    }
}

测试Redis

Redis-Controller

@RestController
public class RedisContoller {
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/redis/get/{key}")
    public Object get(@PathVariable("key") String key){
       return  redisTemplate.opsForValue().get(key);
    }

    @PostMapping("/redis/set/{key}/{value}")
    public Object set(@PathVariable("key") String key,
                      @PathVariable("value") String value){
        redisTemplate.opsForValue().set(key,value);
        return "set success";
    }
}

Controller

Redis+MySQL

@RestController
public class EmpController {
    @Autowired
    private EmpService empService;

    @PostMapping("/emp")
    public String addEmp(Emp emp){
        empService.add(emp);
        return "add ok";
    }

    @GetMapping("/emp/{id}")
    public Object getEmpById(@PathVariable("id") Integer id){
        ExecutorService es = Executors.newFixedThreadPool(200);
        for(int i=0 ;i<500;i++){
            es.submit(new Runnable() {
                @Override
                public void run() {
                    empService.getEmpById(id);
                }
            });
        }
        return empService.getEmpById(id);
    }
}

到此这篇关于SpringBoot整合Redis入门之缓存数据的文章就介绍到这了,更多相关SpringBoot整合Redis缓存数据内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
浅谈redis缓存在项目中的使用
May 20 Redis
redis哨兵常用命令和监控示例详解
May 27 Redis
详解Redis集群搭建的三种方式
May 31 Redis
深入理解redis中multi与pipeline
Jun 02 Redis
Redis性能监控的实现
Jul 09 Redis
关于使用Redisson订阅数问题
Jan 18 Redis
Redis调用Lua脚本及使用场景快速掌握
Mar 16 Redis
Redis 异步机制
May 15 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
如何使用注解方式实现 Redis 分布式锁
Jul 23 Redis
Redis实战之Lettuce的使用技巧详解
Dec 24 Redis
Window server中安装Redis的超详细教程
关于SpringBoot 使用 Redis 分布式锁解决并发问题
Redis Stream类型的使用详解
Redis 持久化 RDB 与 AOF的执行过程
Redis模仿手机验证码发送的实现示例
redis中lua脚本使用教程
Redis高并发防止秒杀超卖实战源码解决方案
You might like
php中对2个数组相加的函数
2011/06/24 PHP
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
2013/06/03 PHP
PHP版本的选择5.2.17 5.3.27 5.3.28 5.4 5.5兼容性问题分析
2016/04/04 PHP
微信公众号实现会员卡领取功能
2017/06/08 PHP
JS类库Bindows1.3中的内存释放方式分析
2007/03/08 Javascript
js 调用本地exe的例子(支持IE内核的浏览器)
2012/12/26 Javascript
jQuery 遍历-nextUntil()方法以及prevUntil()方法的使用介绍
2013/04/26 Javascript
js实现匹配时换色的输入提示特效代码
2015/08/17 Javascript
js实现九宫格拼图小游戏
2017/02/13 Javascript
ajax接收后台数据在html页面显示
2017/02/19 Javascript
详解angular2封装material2对话框组件
2017/03/03 Javascript
javaScript 逻辑运算符使用技巧整理
2017/05/03 Javascript
BootStrap模态框和select2合用时input无法获取焦点的解决方法
2017/09/01 Javascript
JQ图片文件上传之前预览功能的简单实例(分享)
2017/11/12 Javascript
jQuery简单实现的HTML页面文本框模糊匹配查询功能完整示例
2018/05/09 jQuery
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
[03:14]DOTA2斧王 英雄基础教程
2013/11/26 DOTA
python 布尔操作实现代码
2013/03/23 Python
详解Python对JSON中的特殊类型进行Encoder
2019/07/15 Python
Python标准库json模块和pickle模块使用详解
2020/03/10 Python
python实现在线翻译
2020/06/18 Python
全球第二大家装零售商:Lowe’s
2018/01/13 全球购物
cf收人广告词
2014/03/14 职场文书
生日宴会主持词
2014/03/20 职场文书
四议两公开实施方案
2014/03/28 职场文书
春节请假条
2014/04/11 职场文书
教师节倡议书
2014/08/30 职场文书
党性锻炼的心得体会
2014/09/03 职场文书
心得体会的写法
2014/09/05 职场文书
2014年残联工作总结
2014/11/21 职场文书
2014小学数学教研组工作总结
2014/12/06 职场文书
2014年工作总结及2015工作计划
2014/12/12 职场文书
Angular性能优化之第三方组件和懒加载技术
2021/05/10 Javascript
在MySQL中你成功的避开了所有索引
2022/04/20 MySQL
vue使用watch监听属性变化
2022/04/30 Vue.js
Python使用Web框架Flask开发项目
2022/06/01 Python