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 相关文章推荐
在K8s上部署Redis集群的方法步骤
Apr 27 Redis
详解Redis实现限流的三种方式
Apr 27 Redis
redis通过6379端口无法连接服务器(redis-server.exe闪退)
May 08 Redis
Redis实现订单自动过期功能的示例代码
May 08 Redis
Redis可视化客户端小结
Jun 10 Redis
比较几种Redis集群方案
Jun 21 Redis
聊一聊Redis与MySQL双写一致性如何保证
Jun 26 Redis
redis不能访问本机真实ip地址的解决方案
Jul 07 Redis
在redisCluster中模糊获取key方式
Jul 09 Redis
Redis Stream类型的使用详解
Nov 11 Redis
解决redis批量删除key值的问题
Mar 23 Redis
Redis实现短信验证码登录的示例代码
Jun 14 Redis
Window server中安装Redis的超详细教程
关于SpringBoot 使用 Redis 分布式锁解决并发问题
Redis Stream类型的使用详解
Redis 持久化 RDB 与 AOF的执行过程
Redis模仿手机验证码发送的实现示例
redis中lua脚本使用教程
Redis高并发防止秒杀超卖实战源码解决方案
You might like
PHP的FTP学习(一)[转自奥索]
2006/10/09 PHP
setcookie中Cannot modify header information-headers already sent by错误的解决方法详解
2013/05/08 PHP
PHP根据IP地址获取所在城市具体实现
2013/11/27 PHP
destoon实现底部添加你是第几位访问者的方法
2014/07/15 PHP
PHP语法自动检查的Vim插件
2014/08/11 PHP
Extjs中常用表单介绍与应用
2010/06/07 Javascript
浅析offsetLeft,Left,clientLeft之间的区别
2013/11/30 Javascript
jQuery多项选项卡的实现思路附样式及代码
2014/06/03 Javascript
Javascript获取当前时间函数和时间操作小结
2014/10/01 Javascript
vueJS简单的点击显示与隐藏的效果【实现代码】
2016/05/03 Javascript
js通过classname来获取元素的方法
2016/11/24 Javascript
nodejs使用express创建一个简单web应用
2017/03/31 NodeJs
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
2018/09/26 Javascript
详解Vue-axios 设置请求头问题
2018/12/06 Javascript
JavaScript命名空间模式实例详解
2019/06/20 Javascript
js中offset,client , scroll 三大元素知识点总结
2019/09/11 Javascript
vue获取form表单的值示例
2019/10/29 Javascript
python查找指定具有相同内容文件的方法
2015/06/28 Python
python创建列表并给列表赋初始值的方法
2015/07/28 Python
Python win32com 操作Exce的l简单方法(必看)
2017/05/25 Python
Python操作SQLite数据库的方法详解【导入,创建,游标,增删改查等】
2017/07/11 Python
python解析html提取数据,并生成word文档实例解析
2018/01/22 Python
Window10+Python3.5安装opencv的教程推荐
2018/04/02 Python
对python 数据处理中的LabelEncoder 和 OneHotEncoder详解
2018/07/11 Python
Python列表list操作相关知识小结
2020/01/29 Python
python图片合成的示例
2020/11/09 Python
委托书英文
2015/01/28 职场文书
语文教师求职信范文
2015/03/20 职场文书
2016元旦文艺汇演主持词(开场白+结束语)
2015/12/03 职场文书
如何使用JavaScript策略模式校验表单
2021/04/29 Javascript
MySQL COUNT函数的使用与优化
2021/05/10 MySQL
Redis延迟队列和分布式延迟队列的简答实现
2021/05/13 Redis
Vue如何实现组件间通信
2021/05/15 Vue.js
html中显示特殊符号(附带特殊字符对应表)
2021/06/21 HTML / CSS
详解Java实现设计模式之责任链模式
2021/06/23 Java/Android
Java 轮询锁使用时遇到问题
2022/05/11 Java/Android