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 08 Redis
基于Redis过期事件实现订单超时取消
May 08 Redis
Redis延迟队列和分布式延迟队列的简答实现
May 13 Redis
Redis 配置文件重要属性的具体使用
May 20 Redis
SpringBoot 集成Redis 过程
Jun 02 Redis
Redis 常见使用场景
Aug 30 Redis
详解Redis在SpringBoot工程中的综合应用
Oct 16 Redis
redis缓存存储Session原理机制
Nov 20 Redis
Redis安装使用RedisJSON模块的方法
Mar 23 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
Apr 07 Redis
Redis 报错 error:NOAUTH Authentication required
May 15 Redis
利用Redis实现点赞功能的示例代码
Jun 28 Redis
Window server中安装Redis的超详细教程
关于SpringBoot 使用 Redis 分布式锁解决并发问题
Redis Stream类型的使用详解
Redis 持久化 RDB 与 AOF的执行过程
Redis模仿手机验证码发送的实现示例
redis中lua脚本使用教程
Redis高并发防止秒杀超卖实战源码解决方案
You might like
FCKeditor添加自定义按钮
2008/03/27 PHP
采用PHP函数memory_get_usage获取PHP内存清耗量的方法
2011/12/06 PHP
php获取从百度、谷歌等搜索引擎进入网站关键词的方法
2015/07/08 PHP
PHPstorm激活码2020年5月13日亲测有效
2020/09/17 PHP
使用JavaScript库还是自己写代码?
2010/01/28 Javascript
枚举的实现求得1-1000所有出现1的数字并计算出现1的个数
2013/09/10 Javascript
JS如何判断移动端访问设备并解析对应CSS
2013/11/27 Javascript
JS中产生20位随机数以0-9为例也可以是a-z A-Z
2014/08/01 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
2015/02/04 Javascript
JS和css实现检测移动设备方向的变化并判断横竖屏幕
2015/05/25 Javascript
angular forEach方法遍历源码解读
2017/01/25 Javascript
JavaScript数据结构之二叉查找树的定义与表示方法
2017/04/12 Javascript
jQuery使用bind函数实现绑定多个事件的方法
2017/10/11 jQuery
一个简易时钟效果js实现代码
2020/03/25 Javascript
Vue自定义指令封装节流函数的方法示例
2018/07/09 Javascript
webpack4 升级迁移的实现
2018/09/12 Javascript
ng-repeat指令在迭代对象时的去重方法
2018/10/02 Javascript
js变量值传到php过程详解 将php解析成数据
2019/06/26 Javascript
vue实现多组关键词对应高亮显示功能
2019/07/25 Javascript
在vue中获取wangeditor的html和text的操作
2020/10/23 Javascript
Python对两个有序列表进行合并和排序的例子
2014/06/13 Python
python魔法方法-自定义序列详解
2016/07/21 Python
Python方法的延迟加载的示例代码
2017/12/18 Python
python3实现跳一跳点击跳跃
2018/01/08 Python
Python 虚拟空间的使用代码详解
2019/06/10 Python
Python如何访问字符串中的值
2020/02/09 Python
爱尔兰电子产品购物网站:Komplett.ie
2018/04/04 全球购物
劳力士官方珠宝商:J.R. Dunn Jewelers
2018/09/29 全球购物
医院标语大全
2014/06/23 职场文书
责任书格式
2015/01/29 职场文书
涪陵白鹤梁导游词
2015/02/09 职场文书
我爱我班主题班会
2015/08/13 职场文书
创业计划书之冷饮店
2019/09/27 职场文书
如何用RabbitMQ和Swoole实现一个异步任务系统
2021/05/29 PHP
解决pytorch读取自制数据集出现过的问题
2021/05/31 Python
C站最全Python标准库总结,你想要的都在这里
2021/07/03 Python