数据库技术:Redis之sql缓存的具体使用

目录1.环境搭建2.redis配置3.功能实现4.缓存注解的使用说明1.环境搭建 <!– redistemplate –> <dependency> <gro

目录
  • 1.环境搭建
  • 2.redis配置
  • 3.功能实现
  • 4.缓存注解的使用说明

1.环境搭建

%ignore_pre_1%

  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配置

  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));          }      }  }  

  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());      }  }

  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.功能实现

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

  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;  }    

  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存储数据实现

  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());      }    }  

  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自动生成器

      @override      @cacheable(keygenerator = "mykeygenerator")      public list<user> findall(object... params) {          log.info("查询所有");          return new arraylist<>(usermap.values());      }  

  @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组合多个注解标签了。

  @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缓存 内容请搜索<猴子技术宅>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<猴子技术宅>!

需要了解更多数据库技术:Redis之sql缓存的具体使用,都可以关注数据库技术分享栏目—猴子技术宅(www.ssfiction.com)

本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ssfiction.com/sqljc/967276.html

发表评论

邮箱地址不会被公开。 必填项已用*标注