服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Redis - Redis之sql缓存的具体使用

Redis之sql缓存的具体使用

2022-01-24 17:49yzm4399 Redis

本文主要介绍了Redis之sql缓存的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

1.环境搭建

?
1
2
3
4
5
<!-- redistemplate -->
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-data-redis</artifactid>
</dependency>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
  redis:
    host: 192.168.8.128
    port: 6380
    password: 1234
    database: 0
    timeout: 3000
    jedis:
      pool:
        max-wait: -1
        max-active: -1
        max-idle: 20
        min-idle: 10

Redis之sql缓存的具体使用

2.redis配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.yzm.redis01.config;
 
import com.fasterxml.jackson.annotation.jsonautodetect;
import com.fasterxml.jackson.annotation.jsoninclude;
import com.fasterxml.jackson.annotation.jsontypeinfo;
import com.fasterxml.jackson.annotation.propertyaccessor;
import com.fasterxml.jackson.core.jsongenerator;
import com.fasterxml.jackson.core.jsonparser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.javatimemodule;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
 
import java.io.ioexception;
import java.text.simpledateformat;
import java.time.localdatetime;
import java.time.format.datetimeformatter;
 
@configuration
public class objectmapperconfig {
 
    private static final string pattern = "yyyy-mm-dd hh:mm:ss";
 
    @bean(name = "myobjectmapper")
    public objectmapper objectmapper() {
        javatimemodule javatimemodule = new javatimemodule();
        javatimemodule.addserializer(localdatetime.class, new localdatetimeserializer());
        javatimemodule.adddeserializer(localdatetime.class, new localdatetimedeserializer());
        return new objectmapper()
                // 转换为格式化的json(控制台打印时,自动格式化规范)
                //.enable(serializationfeature.indent_output)
                // include.always  是序列化对像所有属性(默认)
                // include.non_null 只有不为null的字段才被序列化,属性为null 不序列化
                // include.non_empty 如果为null或者 空字符串和空集合都不会被序列化
                // include.non_default 属性为默认值不序列化
                .setserializationinclusion(jsoninclude.include.non_null)
                // 如果是空对象的时候,不抛异常
                .configure(serializationfeature.fail_on_empty_beans, false)
                // 反序列化的时候如果多了其他属性,不抛出异常
                .configure(deserializationfeature.fail_on_unknown_properties, false)
                // 取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式
                .configure(serializationfeature.write_dates_as_timestamps, false)
                .setdateformat(new simpledateformat(pattern))
                // 对localdatetime序列化跟反序列化
                .registermodule(javatimemodule)
 
                .setvisibility(propertyaccessor.all, jsonautodetect.visibility.any)
                // 此项必须配置,否则会报java.lang.classcastexception: java.util.linkedhashmap cannot be cast to xxx
                .enabledefaulttyping(objectmapper.defaulttyping.non_final, jsontypeinfo.as.property)
                ;
    }
 
    static class localdatetimeserializer extends jsonserializer<localdatetime> {
        @override
        public void serialize(localdatetime value, jsongenerator gen, serializerprovider serializers) throws ioexception {
            gen.writestring(value.format(datetimeformatter.ofpattern(pattern)));
        }
    }
 
    static class localdatetimedeserializer extends jsondeserializer<localdatetime> {
        @override
        public localdatetime deserialize(jsonparser p, deserializationcontext deserializationcontext) throws ioexception {
            return localdatetime.parse(p.getvalueasstring(), datetimeformatter.ofpattern(pattern));
        }
    }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.yzm.redis01.config;
 
import lombok.extern.slf4j.slf4j;
import org.springframework.cache.interceptor.keygenerator;
import org.springframework.cache.interceptor.simplekey;
 
import java.lang.reflect.method;
import java.util.arrays;
/**
 * key生成器
 */
@slf4j
public class mykeygenerator implements keygenerator {
 
    private static final string no_param = "[]";
    private static final string null_param = "_";
 
    @override
    public object generate(object target, method method, object... params) {
        stringbuilder key = new stringbuilder();
        key.append(target.getclass().getsimplename()).append(".").append(method.getname()).append(":");
 
        if (params.length == 0) {
            return new simplekey(key.append(no_param).tostring());
        }
 
        return new simplekey(key.append(arrays.tostring(params).replace("null", null_param)).tostring());
    }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package com.yzm.redis01.config;
 
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.cache.rediscachewriter;
import org.springframework.data.redis.connection.redisconnectionfactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.jackson2jsonredisserializer;
import org.springframework.data.redis.serializer.redisserializationcontext;
import org.springframework.data.redis.serializer.stringredisserializer;
 
import javax.annotation.resource;
import java.time.duration;
 
@configuration
@enablecaching // 启动缓存
public class redisconfig {
 
    @bean(name = "mykeygenerator")
    public mykeygenerator mykeygenerator() {
        return new mykeygenerator();
    }
 
    @resource(name = "myobjectmapper")
    private objectmapper objectmapper;
 
    /**
     * 选择redis作为默认缓存工具
     */
    @bean
    public cachemanager cachemanager(redisconnectionfactory connectionfactory) {
        rediscachewriter rediscachewriter = rediscachewriter.nonlockingrediscachewriter(connectionfactory);
        rediscacheconfiguration cacheconfiguration = rediscacheconfiguration
                .defaultcacheconfig()
                // 默认缓存时间(秒)
                .entryttl(duration.ofseconds(300l))
                // 序列化key、value
                .serializekeyswith(redisserializationcontext.serializationpair.fromserializer(new stringredisserializer()))
                .serializevalueswith(redisserializationcontext.serializationpair.fromserializer(jackson2jsonredisserializer()))
                // 禁用缓存空值
                .disablecachingnullvalues();
        return new rediscachemanager(rediscachewriter, cacheconfiguration);
    }
 
    /**
     * redistemplate配置
     */
    @bean
    public redistemplate<string, object> redistemplate(redisconnectionfactory factory) {
        redistemplate<string, object> template = new redistemplate<>();
        // 配置连接工厂
        template.setconnectionfactory(factory);
 
        jackson2jsonredisserializer<object> jacksonserializer = jackson2jsonredisserializer();
        stringredisserializer stringredisserializer = new stringredisserializer();
 
        // 使用stringredisserializer来序列化和反序列化redis的key,value采用json序列化
        template.setkeyserializer(stringredisserializer);
        template.setvalueserializer(jacksonserializer);
 
        // 设置hash key 和value序列化模式
        template.sethashkeyserializer(stringredisserializer);
        template.sethashvalueserializer(jacksonserializer);
 
        //支持事务
        template.setenabletransactionsupport(true);
        template.afterpropertiesset();
 
        return template;
    }
 
    private jackson2jsonredisserializer<object> jackson2jsonredisserializer() {
        //使用jackson2jsonredisserializer来序列化和反序列化redis的value值(默认使用jdk的序列化方式)
        jackson2jsonredisserializer<object> jacksonserializer = new jackson2jsonredisserializer<>(object.class);
        jacksonserializer.setobjectmapper(objectmapper);
        return jacksonserializer;
    }
}

3.功能实现

新增、更新、删除、查询数据时,对缓存执行对应相同的操作

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.yzm.redis01.entity;
 
import lombok.allargsconstructor;
import lombok.builder;
import lombok.data;
import lombok.noargsconstructor;
import lombok.experimental.accessors;
 
import java.io.serializable;
import java.time.localdatetime;
import java.util.date;
 
@data
@builder
@noargsconstructor
@allargsconstructor
@accessors(chain = true)
public class user implements serializable {
    private static final long serialversionuid = -2468903864827432779l;
    private integer id;
    private string username;
    private string password;
    private date createdate;
    private localdatetime updatedate;
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.yzm.redis01.service;
 
import com.yzm.redis01.entity.user;
 
import java.util.list;
 
public interface userservice {
 
    user saveuser(user user);
 
    user updateuser(user user);
 
    int deleteuser(integer id);
 
    void deleteallcache();
 
    user getuserbyid(integer id);
 
    list<user> selectall();
    
    list<user> findall(object... params);
}

为了简便,数据不从数据库获取,这里是创建map存储数据实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package com.yzm.redis01.service.impl;
 
import com.yzm.redis01.entity.user;
import com.yzm.redis01.service.userservice;
import lombok.extern.slf4j.slf4j;
import org.springframework.cache.annotation.cacheconfig;
import org.springframework.cache.annotation.cacheevict;
import org.springframework.cache.annotation.cacheput;
import org.springframework.cache.annotation.cacheable;
import org.springframework.stereotype.service;
 
import java.time.localdatetime;
import java.util.*;
 
@slf4j
@service
@cacheconfig(cachenames = "users")
public class userserviceimpl implements userservice {
 
 
    private static final map<integer, user> usermap;
 
    static {
        usermap = new hashmap<>();
        usermap.put(usermap.size() + 1, user.builder()
                .id(usermap.size() + 1).username("root").password("root").createdate(new date()).updatedate(localdatetime.now()).build());
        usermap.put(usermap.size() + 1, user.builder()
                .id(usermap.size() + 1).username("admin").password("admin").createdate(new date()).updatedate(localdatetime.now()).build());
    }
 
    @override
    @cacheput(key = "#result.id", condition = "#result.id gt 0")
    public user saveuser(user user) {
        log.info("保存数据");
        int id = usermap.size() + 1;
        user build = user.builder()
                .id(id)
                .username(user.getusername())
                .password(user.getpassword())
                .createdate(new date())
                .updatedate(localdatetime.now())
                .build();
        usermap.put(id, build);
        return build;
    }
 
    @override
    @cacheput(key = "#user.id", unless = "#result eq null")
    public user updateuser(user user) {
        log.info("更新数据");
        if (usermap.containskey(user.getid())) {
            user update = usermap.get(user.getid());
            update.setusername(user.getusername())
                    .setpassword(user.getpassword())
                    .setupdatedate(localdatetime.now());
            usermap.replace(user.getid(), update);
            return update;
        }
        return null;
    }
 
    @override
    @cacheevict(key = "#id", condition = "#result gt 0")
    public int deleteuser(integer id) {
        log.info("删除数据");
        if (usermap.containskey(id)) {
            usermap.remove(id);
            return 1;
        }
        return 0;
    }
 
    @override
    @cacheevict(allentries = true)
    public void deleteallcache() {
        log.info("清空缓存");
    }
 
    @override
    @cacheable(key = "#id", condition = "#id gt 1")
    public user getuserbyid(integer id) {
        log.info("查询用户");
        return usermap.get(id);
    }
 
    @override
    @cacheable(key = "#root.methodname")
    public list<user> selectall() {
        log.info("查询所有");
        return new arraylist<>(usermap.values());
    }
 
    @override
    @cacheable(keygenerator = "mykeygenerator")
    public list<user> findall(object... params) {
        log.info("查询所有");
        return new arraylist<>(usermap.values());
    }
 
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.yzm.redis01.controller;
 
import com.yzm.redis01.entity.user;
import com.yzm.redis01.service.userservice;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;
 
import java.util.list;
 
@restcontroller
@requestmapping("/user")
public class usercontroller {
 
    private final userservice userservice;
 
    public usercontroller(userservice userservice) {
        this.userservice = userservice;
    }
 
    @getmapping("/saveuser")
    public void saveuser() {
        user user = new user();
        user.setusername("yzm");
        user.setpassword("yzm");
        system.out.println(userservice.saveuser(user));
    }
 
    @getmapping("/updateuser")
    public void updateuser(integer id) {
        user user = new user();
        user.setid(id);
        user.setusername("yzm");
        user.setpassword("123");
        system.out.println(userservice.updateuser(user));
    }
 
    @getmapping("/deleteuser")
    public void deleteuser(@requestparam integer id) {
        system.out.println(userservice.deleteuser(id));
    }
 
    @getmapping("/deleteallcache")
    public void deleteallcache() {
        userservice.deleteallcache();
    }
 
    @getmapping("/getuserbyid")
    public void getuserbyid(@requestparam integer id) {
        system.out.println(userservice.getuserbyid(id));
    }
 
    @getmapping("/selectall")
    public void selectall() {
        list<user> users = userservice.selectall();
        users.foreach(system.out::println);
    }
}

4.缓存注解的使用说明

@cacheconfig:注解在类上,表示该类所有缓存方法使用统一指定的缓存区,也可以作用在方法上

Redis之sql缓存的具体使用

@cacheable:注解在方法上,应用到读数据的方法上,如查找方法:调用方法之前根据条件判断是否从缓存获取相应的数据,缓存没有数据,方法执行后添加到缓存

Redis之sql缓存的具体使用

#id 直接使用参数名
#p0 p0对应参数列表的第一个参数,以此类推
#user.id 参数是对象时,使用对象属性
#root. 可以点出很多方法
#root.methodname
#result 返回值

http://localhost:8080/user/getuserbyid?id=1

Redis之sql缓存的具体使用

http://localhost:8080/user/getuserbyid?id=2

Redis之sql缓存的具体使用

http://localhost:8080/user/selectall

Redis之sql缓存的具体使用

@cacheable运行流程:在调用方法之前判断condition,如果为true,则查缓存;没有缓存就调用方法并将数据添加到缓存;condition=false就与缓存无关了

@cacheput:注解在方法上,应用到写数据的方法上,如新增/修改方法,调用方法之后根据条件判断是否添加/更新相应的数据到缓存:

Redis之sql缓存的具体使用

http://localhost:8080/user/saveuser

Redis之sql缓存的具体使用

condition条件为true,添加到缓存,根据id查询直接从缓存获取
http://localhost:8080/user/getuserbyid?id=3

Redis之sql缓存的具体使用

http://localhost:8080/user/updateuser?id=3
http://localhost:8080/user/getuserbyid?id=3

Redis之sql缓存的具体使用

条件condition=true,执行缓存操作
条件unless=false,执行缓存操作;跟condition相反

@cacheevict 注解在方法上,应用到删除数据的方法上,如删除方法,调用方法之后根据条件判断是否从缓存中移除相应的数据

Redis之sql缓存的具体使用

http://localhost:8080/user/saveuser
http://localhost:8080/user/getuserbyid?id=3
http://localhost:8080/user/deleteuser?id=3

Redis之sql缓存的具体使用

自定义缓存key自动生成器

?
1
2
3
4
5
6
@override
@cacheable(keygenerator = "mykeygenerator")
public list<user> findall(object... params) {
    log.info("查询所有");
    return new arraylist<>(usermap.values());
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@slf4j
public class mykeygenerator implements keygenerator {
 
    private static final string no_param = "[]";
    private static final string null_param = "_";
 
    @override
    public object generate(object target, method method, object... params) {
        stringbuilder key = new stringbuilder();
        key.append(target.getclass().getsimplename()).append(".").append(method.getname()).append(":");
 
        if (params.length == 0) {
            return new simplekey(key.append(no_param).tostring());
        }
 
        return new simplekey(key.append(arrays.tostring(params).replace("null", null_param)).tostring());
    }
}

http://localhost:8080/user/findall

Redis之sql缓存的具体使用

http://localhost:8080/user/findall?id=123

Redis之sql缓存的具体使用

http://localhost:8080/user/findall?username=yzm

Redis之sql缓存的具体使用

@caching
有时候我们可能组合多个cache注解使用;比如用户新增成功后,我们要添加id–>user;username—>user;email—>user的缓存;
此时就需要@caching组合多个注解标签了。

?
1
2
3
4
5
6
7
8
@caching(
    put = {
        @cacheput(value = "users", key = "#user.id"),
        @cacheput(value = "users", key = "#user.username"),
        @cacheput(value = "users", key = "#user.email")
    }
)
public user save(user user) {}

到此这篇关于redis之sql缓存的具体使用的文章就介绍到这了,更多相关redis sql缓存 内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_43654581/article/details/121677623

延伸 · 阅读

精彩推荐
  • Redis详解三分钟快速搭建分布式高可用的Redis集群

    详解三分钟快速搭建分布式高可用的Redis集群

    这篇文章主要介绍了详解三分钟快速搭建分布式高可用的Redis集群,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    万猫学社4502021-07-25
  • RedisRedis Template实现分布式锁的实例代码

    Redis Template实现分布式锁的实例代码

    这篇文章主要介绍了Redis Template实现分布式锁,需要的朋友可以参考下 ...

    晴天小哥哥2592019-11-18
  • RedisRedis集群的5种使用方式,各自优缺点分析

    Redis集群的5种使用方式,各自优缺点分析

    Redis 多副本,采用主从(replication)部署结构,相较于单副本而言最大的特点就是主从实例间数据实时同步,并且提供数据持久化和备份策略。...

    优知学院4082021-08-10
  • Redisredis缓存存储Session原理机制

    redis缓存存储Session原理机制

    这篇文章主要为大家介绍了redis缓存存储Session原理机制详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    程序媛张小妍9252021-11-25
  • Redis《面试八股文》之 Redis十六卷

    《面试八股文》之 Redis十六卷

    redis 作为我们最常用的内存数据库,很多地方你都能够发现它的身影,比如说登录信息的存储,分布式锁的使用,其经常被我们当做缓存去使用。...

    moon聊技术8182021-07-26
  • RedisRedis 6.X Cluster 集群搭建

    Redis 6.X Cluster 集群搭建

    码哥带大家完成在 CentOS 7 中安装 Redis 6.x 教程。在学习 Redis Cluster 集群之前,我们需要先搭建一套集群环境。机器有限,实现目标是一台机器上搭建 6 个节...

    码哥字节15752021-04-07
  • Redis关于Redis数据库入门详细介绍

    关于Redis数据库入门详细介绍

    大家好,本篇文章主要讲的是关于Redis数据库入门详细介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览...

    沃尔码6982022-01-24
  • Redis如何使用Redis锁处理并发问题详解

    如何使用Redis锁处理并发问题详解

    这篇文章主要给大家介绍了关于如何使用Redis锁处理并发问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习...

    haofly4522019-11-26