一、环境和依赖的搭配
application.yml
server:
port: 8888
spring:
datasource:
url: jdbc:mysql://localhost:3306/testredis
username: root
password: 123
driver-class-name: com.mysql.cj.jdbc.Driver
#redis集群
redis:
host: 127.0.0.1 #Redis 服务器地址
port: 6379 #redis 服务器连接口
timeout: 20000 #连接超时时间(毫秒)
# 集群环境打开下面注释,单机不需要打开
# cluster:
# 集群信息
# nodes: xxx.xxx.xxx.xxx:xxxx,xxx.xxx.xxx.xxx:xxxx,xxx.xxx.xxx.xxx:xxxx
# #默认值是5 一般当此值设置过大时,容易报:Too many Cluster redirections
# maxRedirects: 3
pool:
max-active: 8 #连接池最大连接数(使用负值表示没有限制)
min-idle: 0 #连接池中的最小空闲连接
max-idle: 8 #连接池中的最大空闲连接
max-wait: -1 #最大阻塞等待时间(负数表示没有限制)
password:
database: 0 #Redis数据库索引(默认为零)
mybatis:
type-aliases-package: com.study.entity #所有数据库表逆向后所一一映射的实体类 Entity/Bean/POJO
mapper-locations: classpath*:mappers/**/*.xml #所有mapper映射的文件所在目录位置
configuration:
map-underscore-to-camel-case: true #将下划线转换成驼峰
#在控制台显示sql语句的查询
logging:
level:
com.study: debug
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.study</groupId>
<artifactId>springboot-Redis-Demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/>
</parent>
<dependencies>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--reids-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--通用池-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.11.1</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</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>
</project>
二、创建 实体类 和 mapper
entity (实体类)
@Data
@Table(name = "emp")
public class Emp implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //逐渐自动增长才设置
private Integer id;
private String name;
private Integer age;
}
mapper
这边继承通用mapper 可以减少写sql语句(也可以自己写sql 也可以自己写)
@Repository
public interface EmpMapper extends Mapper<Emp> {
}
三、创建 redis的配置类
RedisConfig
package com.study.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@EnableCaching //开启缓存 ,开启redis操作
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
//设置“key"的序列化方式 设置键的序列化,是String
template.setKeySerializer(new StringRedisSerializer());
//设置“值”的序列化方式 设置值的序列化,是jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
//设置“hash”类型数据的序列化方式
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
StringRedisSerializer redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//配置序列化(解决乱码问题)过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
六、创建service类(实现 增删改 过程中对 redis的使用)
package com.study.service;
import com.study.entity.Emp;
public interface EmpService {
Integer add(Emp emp);
Object getById(Integer id);
Integer Upade(Emp emp);
Integer del(Integer id);
}
package com.study.service.impl;
import com.study.entity.Emp;
import com.study.mapper.EmpMapper;
import com.study.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j
@Service
public class EmpServiceImpl implements EmpService {
@Resource
private EmpMapper empMapper;
@Resource
private RedisTemplate redisTemplate;
@Resource
private EmpMapperB empMapperB;
@Override
public Integer add(Emp emp) {
String key = "user:"+ emp.getId();
int num = empMapper.insert(emp);
Object addObj = redisTemplate.opsForValue().get(key);
if (addObj == null){
log.debug("----->>>>需要存入缓存----");
redisTemplate.opsForValue().set(key,emp);
}else {
log.debug("---====---直接存入数据库");
}
return num;
}
/**
* 先从缓存获取数据,如果有则直接返回
* 如果无,则查询mysql,并将数据设置到缓存
* synchronized关键字是用来控制线程同步的,就是在多线程的环境下,
* 控制synchronized代码段不被多个线程同时执行
*/
@Override
public Object getById(Integer id) {
String key = "user:" + id;
Object redisObj = redisTemplate.opsForValue().get(key);
if (redisObj == null ){ //判断缓存中有无数据
log.debug("=== 从数据库中获取 ====");
Emp emp = empMapper.selectByPrimaryKey(id);
redisTemplate.opsForValue().set(key,emp);
return emp;
}else {
log.debug("----->>>>>从缓存中获取-------");
return redisObj;
}
}
@Override
public Integer Upade(Emp emp) {
String key = "user:" + emp.getId();
int num = empMapper.updateByPrimaryKey(emp);
Object upObj = redisTemplate.opsForValue().get(key);
if (upObj != null){
log.debug("需要更新缓存中的数据");
redisTemplate.opsForValue().getAndSet(key,emp);
}else{
log.debug("直接更新数据库中的数据");
}
return num;
}
@Override
public Integer del(Integer id) {
String key = "user:" + id;
int num = empMapper.deleteByPrimaryKey(id);
Object redisObj = redisTemplate.opsForValue().get(key);
if (redisObj != null){
log.debug("/------需要删除缓存-----/");
redisTemplate.delete(key);
}else {
log.debug("------->>>>只要从数据库中删除");
}
return num;
}
}
七、创建controller 利用接口的调用来对 功能的实现
package com.study.controller;
import com.study.entity.Emp;
import com.study.service.EmpService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
public class EmpController {
@Resource
private EmpService empService;
//插入数据 同时添加到缓存中
@PostMapping("add")
public Integer insert(@RequestBody Emp emp){
Integer num = empService.add(emp);
return num;
}
//查询数据 判断缓存中有无数据 无在缓存中插入数据
@GetMapping("select/{id}")
public Object getById(@PathVariable("id") Integer id){
return empService.getById(id);
}
//判断缓存中有无数据 有需要更新 无直接更新数据库
@PostMapping("update")
public Integer Update(@RequestBody Emp emp){
Integer num = empService.Upade(emp);
return num;
}
//判断缓存中有无数据 有需要删除 无直接删除数据库中的数据
@GetMapping("del/{id}")
public Integer Del(@PathVariable("id") Integer id){
Integer num = empService.del(id);
return num;
}
}
八、启动类 application.java
package com.study;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan("com.study.mapper")
public class application {
public static void main(String[] args) {
SpringApplication.run(application.class);
}
}
版权声明:本文为m0_63180675原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。