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 sentinel 频繁主备切换的问题
Apr 12 Redis
Redis IP地址的绑定的实现
May 08 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
redis哨兵常用命令和监控示例详解
May 27 Redis
redis客户端实现高可用读写分离的方式详解
Jul 04 Redis
Redis 彻底禁用RDB持久化操作
Jul 09 Redis
解析redis hash应用场景和常用命令
Aug 04 Redis
分布式Redis Cluster集群搭建与Redis基本用法
Feb 24 Redis
Redis 中使用 list,streams,pub/sub 几种方式实现消息队列的问题
Mar 16 Redis
muduo TcpServer模块源码分析
Apr 26 Redis
windows安装 redis 6.2.6最新步骤详解
Apr 26 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
Window server中安装Redis的超详细教程
关于SpringBoot 使用 Redis 分布式锁解决并发问题
Redis Stream类型的使用详解
Redis 持久化 RDB 与 AOF的执行过程
Redis模仿手机验证码发送的实现示例
redis中lua脚本使用教程
Redis高并发防止秒杀超卖实战源码解决方案
You might like
PHP SEO优化之URL优化方法
2011/04/21 PHP
PHP中如何调用webservice的实例参考
2013/04/25 PHP
PHP用身份证号获取星座和生肖的方法
2013/11/07 PHP
PHP根据传来的16进制颜色代码自动改变背景颜色
2014/06/13 PHP
php实现图片转换成ASCII码的方法
2015/04/03 PHP
php数组生成html下拉列表的方法
2015/07/20 PHP
CodeIgniter钩子用法实例详解
2016/01/20 PHP
php json_encode与json_decode详解及实例
2016/12/13 PHP
Javascript 设计模式(二) 闭包
2010/05/26 Javascript
Javascript的严格模式strict mode详细介绍
2014/06/06 Javascript
JS实现选中当前菜单后高亮显示的导航条效果
2015/10/15 Javascript
JavaScript实现仿淘宝商品购买数量的增减效果
2016/01/22 Javascript
微信小程序  action-sheet详解及实例代码
2016/11/09 Javascript
ES6中module模块化开发实例浅析
2017/04/06 Javascript
Bootstrap弹出框(Popover)被挤压的问题小结
2017/07/11 Javascript
关于定制FileField中的上传文件名称问题
2017/08/22 Javascript
基于js中的原型(全面讲解)
2017/09/19 Javascript
vuex进阶知识点巩固
2018/05/20 Javascript
JS实现滚动条触底加载更多
2019/09/19 Javascript
layer.alert自定义关闭回调事件的方法
2019/09/27 Javascript
Vue实现剪贴板复制功能
2019/12/31 Javascript
JavaScript函数Call、Apply原理实例解析
2020/02/17 Javascript
javascript设计模式 ? 访问者模式原理与用法实例分析
2020/04/26 Javascript
自己使用总结Python程序代码片段
2015/06/02 Python
Python+matplotlib实现计算两个信号的交叉谱密度实例
2018/01/08 Python
浅谈flask截获所有访问及before/after_request修饰器
2018/01/18 Python
python中使用psutil查看内存占用的情况
2018/06/11 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
2018/11/30 Python
python3获取当前目录的实现方法
2019/07/29 Python
django 微信网页授权登陆的实现
2019/07/30 Python
python读取图片颜色值并生成excel像素画的方法实例
2021/02/19 Python
澳大利亚在线家具店:Luxo Living
2019/03/24 全球购物
Intersport西班牙:在线体育商店
2019/11/06 全球购物
党员干部公开承诺书
2014/03/26 职场文书
十八大标语口号
2014/10/09 职场文书
预备党员入党思想汇报(范文)
2019/08/14 职场文书