redis在web开发中使用的场景很多,其中缓存是其中一个很重要的使用场景,之所以用作缓存,得益于redis的读写数据,尤其是在读取数据的时候是直接走内存的,这样在高并发访问数据的时候,和查询数据库相比,redis读取数据的高效性、快速性的优势可见一斑
- Redis注解概念
名称 | 解释 |
---|---|
Cache | 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
CacheManager | 缓存管理器,管理各种缓存(cache)组件 |
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其进行缓存 |
@CacheEvict | 清空缓存 |
@CachePut | 保证方法被调用,又希望结果被缓存与@Cacheable区别在于是否每次都调用方法,常用于更新 |
@EnableCaching | 开启基于注解的缓存 |
keyGenerator | 缓存数据时key生成策略 |
serialize | 缓存数据时value序列化策略 |
@CacheConfig | 统一配置本类的缓存注解的属性 |
- 在看代码前先看看目录结构
- 启动类
@SpringBootApplication
@EnableCaching
public class RedisdemoApplication {
public static void main(String[] args) {
SpringApplication.run(RedisdemoApplication.class, args);
}
}
- application.yml配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://127.0.0.1:3306/schooldb?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
#redis配置
redis:
host: 127.0.0.1
password: 123456
port: 6379
jedis:
pool:
max-active: 20
max-idle: 8
min-idle: 0
max-wait: 5000
#mybatis的配置
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mapper/*.xml
- 实体类
public class Dept implements Serializable {
private Integer id;
private String dname;
private String loc;
@Override
public String toString() {
return "Dept{" +
"id=" + id +
", dname='" + dname + '\'' +
", loc='" + loc + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
public class RespBean {
private Integer status;
private String msg;
private Object obj;
public RespBean(Integer status, String msg) {
this.status = status;
this.msg = msg;
}
public static final RespBean DELETE_SUCCESS = new RespBean(200,"删除成功");
public static final RespBean DELETE_ERROR = new RespBean(-1,"删除失败");
public static final RespBean ADD_SUCCESS = new RespBean(200,"添加成功");
public static final RespBean ADD_ERROR = new RespBean(-1,"添加失败");
public static final RespBean UPDATE_SUCCESS = new RespBean(200,"更新成功");
public static final RespBean UPDATE_ERROR = new RespBean(-1,"更新失败");
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
private RespBean(Integer status, String msg, Object obj) {
this.status = status;
this.msg = msg;
this.obj = obj;
}
private RespBean() {
}
}
- mapper层
@Mapper
public interface DeptMapper {
Integer addDept(Dept dept);
Integer deleteById(Integer id);
Integer updateDeptById(Dept dept);
Dept findAllDept(Integer id);
}
- service层
public interface DeptService {
Dept addDept(Dept dept);
Integer deleteById(Integer id);
Dept updateDeptById(Dept dept);
Dept findAllDept(Integer id);
}
- serviceimpl层
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@CachePut(cacheNames = "dept",key = "#result.id")
@Override
public Dept addDept(Dept dept) {
deptMapper.addDept(dept);
return dept;
}
@CacheEvict(cacheNames = "dept")
@Override
public Integer deleteById(Integer id) {
Integer result=deptMapper.deleteById(id);
return result;
}
@CachePut(cacheNames = "dept",key = "#result.id")
@Override
public Dept updateDeptById(Dept dept) {
deptMapper.updateDeptById(dept);
return dept;
}
@Cacheable(cacheNames = "dept",key = "#id")
@Override
public Dept findAllDept(Integer id) {
return deptMapper.findAllDept(id);
}
}
- controller
@RestController
@RequestMapping("/dept")
public class DeptController {
@Autowired
private DeptService deptService;
@GetMapping("/{id}")
public Object findAll(@PathVariable Integer id){
Dept allDept = deptService.findAllDept(id);
return allDept;
}
/**
* 删除
* @param id
* @return
*/
@DeleteMapping("/{id}")
public RespBean deleteDept(@PathVariable Integer id){
try {
deptService.deleteById(id);
return RespBean.DELETE_SUCCESS;//删除成功
} catch (Exception e) {
e.printStackTrace();
return RespBean.DELETE_ERROR;//删除失败
}
}
/**
* 添加
* @param dept
* @return
*/
@PostMapping("/")
public RespBean addDept(@RequestBody Dept dept){
try {
deptService.addDept(dept);
return RespBean.ADD_SUCCESS;//添加成功
} catch (Exception e) {
e.printStackTrace();
return RespBean.ADD_ERROR;//添加失败
}
}
/**
* 更新
* @param dept
* @return
*/
@PutMapping("/")
public RespBean updateDept(@RequestBody Dept dept){
try {
deptService.updateDeptById(dept);
return RespBean.UPDATE_SUCCESS;//添加成功
} catch (Exception e) {
e.printStackTrace();
return RespBean.UPDATE_ERROR;//添加失败
}
}
}
- DeptMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.song.mapper.DeptMapper">
<insert id="addDept" keyProperty="id" useGeneratedKeys="true" parameterType="com.song.entity.Dept" >
insert into dept(dname,loc)values (#{dname},#{loc})
</insert>
<delete id="deleteById">
delete from dept where id=#{id}
</delete>
<update id="updateDeptById" parameterType="com.song.entity.Dept">
update dept set dname=#{dname},loc=#{loc} where id=#{id}
</update>
<select id="findAllDept" resultType="com.song.entity.Dept" >
select*from dept where id=#{id}
</select>
</mapper>
- 改变默认jdk序列化器
@Configuration
public class MyRedisConfig {
@Bean(name = "redisTemplate")
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(keySerializer());
redisTemplate.setHashKeySerializer(keySerializer());
redisTemplate.setValueSerializer(valueSerializer());
redisTemplate.setHashValueSerializer(valueSerializer());
return redisTemplate;
}
@Primary
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
//缓存配置对象
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.entryTtl(Duration.ofMinutes(30L)) //设置缓存的默认超时时间:30分钟
.disableCachingNullValues() //如果是空值,不缓存
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())) //设置key序列化器
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer((valueSerializer()))); //设置value序列化器
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
private RedisSerializer<String> keySerializer() {
return new StringRedisSerializer();
}
private RedisSerializer<Object> valueSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
- 效果
可以打开redis可视化工具,首先没有数据
使用postman测试
redis中