SpringBoot整合Redis(一)

拜拜、爱过 提交于 2019-12-01 04:59:18

docker启动redis

docker run -p 6379:6379 --name myredis redis

查看容器

[root@topcheer ~]# docker ps -lCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES14b1139f889d        f7302e4ab3a8        "docker-entrypoint..."   20 hours ago        Up 20 hours         0.0.0.0:6379->6379/tcp   myredis[root@topcheer ~]#

注:本文只讲整合,后面补充docker及redis知识

整合Redis

application.yml 配置文件

spring:  datasource:    username: scott    password: tiger    url: jdbc:oracle:thin:@//localhost:1521/ORCL    driver-class-name: oracle.jdbc.driver.OracleDriver  redis:    host: 192.168.180.113    port: 6379

pom.xml (选取开发所需的依赖)

        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-jdbc</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-cache</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid</artifactId>            <version>1.1.18</version>        </dependency>​        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>            <optional>true</optional>        </dependency>​        <dependency>            <groupId>com.baomidou</groupId>            <artifactId>mybatis-plus-boot-starter</artifactId>            <version>3.2.0</version>        </dependency>​        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-data-redis</artifactId>        </dependency>​       <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>1.2.33</version>        </dependency>​        <dependency>            <groupId>com.oracle</groupId>            <artifactId>ojdbc8</artifactId>            <version>12.2.0.1.0</version>        </dependency>

启动类加上注解

 /* 整合redis作为缓存 * Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 *  1、安装redis:使用docker; *  2、引入redis的starter *  3、配置redis *  4、测试缓存 *      原理:CacheManager===Cache 缓存组件来实际给缓存中存取数据 *      1)、引入redis的starter,容器中保存的是 RedisCacheManager; *      2)、RedisCacheManager 帮我们创建 RedisCache 来作为缓存组件;RedisCache通过操作redis缓存数据的 *      3)、默认保存数据 k-v 都是Object;利用序列化保存;如何保存为json *              1、引入了redis的starter,cacheManager变为 RedisCacheManager; *              2、默认创建的 RedisCacheManager 操作redis的时候使用的是 RedisTemplate<Object, Object> *              3、RedisTemplate<Object, Object> 是 默认使用jdk的序列化机制 *      4)、自定义CacheManager; * */@MapperScan("com.topcheer.*.*.dao")@SpringBootApplication@EnableCaching    //开启缓存public class Oss6Application {​    public static void main(String[] args) {        SpringApplication.run(Oss6Application.class, args);    }​}​

Web层

/** * @author WGR * @create 2019/9/7 -- 15:14 */​@RestController@RequestMapping("/sys/user")@Slf4jpublic class UserController {​    @Autowired    UserService userService;​    //根据主键查询    @GetMapping("/findById")    public  R findById(Integer id) {        return userService.findById(id);    }​​}

Service层

/** * @author WGR * @create 2019/9/7 -- 15:14 */@Servicepublic class UserService {​    @Autowired(required = false)    UserMapper userMapper;​    /**     *  缓存的数据能存入redis;     *  第二次从缓存中查询就不能反序列化回来;     *  存的是dept的json数据;CacheManager默认使用RedisTemplate<Object, Employee>操作Redis     *     *     * @param id     * @return     */    @Cacheable(cacheNames = "user",key="#root.methodName+'['+#id+'}'")    public R findById(Integer id) {       return R.ok().addData(               userMapper.selectById(id)       );    }}

注解JSR107缓存说明(当pom加入redis时,生效的是RedisCacheConfiguration)

 将方法的运行结果进行缓存;以后再要相同的数据,直接从缓存中获取,不用调用方法;      CacheManager管理多个Cache组件的,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字;     ​           原理:        1、自动配置类;CacheAutoConfiguration        2、缓存的配置类        org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration        org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration        org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration        org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration        org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration        org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration        org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration        org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration        org.springframework.boot.autoconfigure.cache.GuavaCacheConfiguration        org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration【默认】        org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration        3、哪个配置类默认生效:SimpleCacheConfiguration;             4、给容器中注册了一个CacheManager:ConcurrentMapCacheManager        5、可以获取和创建ConcurrentMapCache类型的缓存组件;他的作用将数据保存在ConcurrentMap中;             运行流程:        @Cacheable:        1、方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取;           (CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。        2、去Cache中查找缓存的内容,使用一个key,默认就是方法的参数;           key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key;               SimpleKeyGenerator生成key的默认策略;                       如果没有参数;key=new SimpleKey();                       如果有一个参数:key=参数的值                       如果有多个参数:key=new SimpleKey(params);        3、没有查到缓存就调用目标方法;        4、将目标方法返回的结果,放进缓存中             @Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,        如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据;             核心:           1)、使用CacheManager【ConcurrentMapCacheManager】按照名字得到Cache【ConcurrentMapCache】组件           2)、key使用keyGenerator生成的,默认是SimpleKeyGenerator                  几个属性:           cacheNames/value:指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存;                key:缓存数据使用的key;可以用它来指定。默认是使用方法参数的值  1-方法的返回值                   编写SpEL; #i d;参数id的值   #a0  #p0  #root.args[0]                   getEmp[2]                keyGenerator:key的生成器;可以自己指定key的生成器的组件id                   key/keyGenerator:二选一使用;                     cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器                condition:指定符合条件的情况下才缓存;                   ,condition = "#id>0"               condition = "#a0>1":第一个参数的值》1的时候才进行缓存                unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断                   unless = "#result == null"                   unless = "#a0==2":如果第一个参数的值是2,结果不缓存;           sync:是否使用异步模式

 

Dao层

/** * @author WGR * @create 2019/9/7 -- 15:10 */public interface UserMapper extends OssMapper<User> {}​

Bo类

@AllArgsConstructor@NoArgsConstructor@Data@TableName("Z010_USER")@KeySequence(value="SEQ_Z010_USER",clazz=Integer.class)public class User implements Serializable{​    private static final long serialVersionUID = 1L;​    @TableId    private Integer id;                // 主键    private String account;            // 账号,唯一,可供登录(同时作为密码的盐值)    private String name;               // 姓名    @JSONField(serialize=false)    private String password;           // 密码,MD5盐值加密    @Code    private String gender;             // 性别,字典    private Date birthday;             // 出生日期    @Code    private String certType;           // 证件类型,字典    private String certNumber;         // 证件号码    private String telNumber;          // 固定电话    private String mobNumber;          // 手机号码    private String faxNumber;          // 传真号码    private String email;              // 电子邮件,唯一,可供登录    private String empId;              // 工号,唯一,可供登录    @Code    private String position;           // 职位    private Integer managerId;         // 直属上级   20180417    @JSONField(format="yyyy-MM-dd")    private Date loginLastTime;        // 最后登录时间    private Integer loginSuccessCount; // 登录成功次数(成功登录时+1)    private String passwordStatus;     // 密码状态,0-临时密码 1-永久密码(临时密码登录提示修改密码)    private Integer passwordTryCount;  // 密码尝试次数(错误累计,成功登录清零)    @JSONField(format="yyyy-MM-dd")    private Date passwordTryLastTime;  // 密码最后尝试时间    @JSONField(format="yyyy-MM-dd")    private Date passwordExpiryDate;   // 密码过期日期(密码即将过期提示, 已经过期强制修改密码)    private String wxOpenid;           // 微信公众号openId        private String headPic;            // 用户头像        private String createUser;         // 创建人员    @JSONField(format="yyyy-MM-dd")    private Date createTime;           // 创建时间    private String modifyUser;         // 修改人员    @JSONField(format="yyyy-MM-dd")    private Date modifyTime;           // 修改时间    @Code    private String status;             // 状态, 0-禁用 1-启用    @TableLogic    @JSONField(serialize=false)    private String delFlag;            // 数据删除标记, 0-已删除 1-有效    private String remark;             // 备注        @TableField(exist=false)    private String permType;           // 权限类型​​}

Fastjosn进行序列化及Redis配置

/** * @author WGR * @create 2019/10/10 -- 23:47 */public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {​    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");​    private Class<T> clazz;​    static {    //开启白名单,不能序列化的时候会报错        ParserConfig.getGlobalInstance().addAccept("com.topcheer.oss.");    }​    public FastJson2JsonRedisSerializer(Class<T> clazz) {        super();        this.clazz = clazz;    }​    public byte[] serialize(T t) throws SerializationException {        if (t == null) {            return new byte[0];        }        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);    }​    public T deserialize(byte[] bytes) throws SerializationException {        if (bytes == null || bytes.length <= 0) {            return null;        }        String str = new String(bytes, DEFAULT_CHARSET);        return (T) JSON.parseObject(str, clazz);    }​}
/** * @author WGR * @create 2019/10/10 -- 23:33 */@Configurationpublic class RedisConfig extends CachingConfigurerSupport {​    @Bean("redisCacheManager")    @Primary    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {        //初始化一个RedisCacheWriter        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);        FastJson2JsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJson2JsonRedisSerializer<>(Object.class);        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer);        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);        //设置过期时间 30天        defaultCacheConfig = defaultCacheConfig.entryTtl(Duration.ofDays(30));        //初始化RedisCacheManager        RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);​        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);       // ParserConfig.getGlobalInstance().addAccept("com.topcheer.oss.");        return cacheManager;    }​    @Bean(name = "redisTemplate")    @SuppressWarnings("unchecked")    @ConditionalOnMissingBean(name = "redisTemplate")    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {        RedisTemplate<Object, Object> template = new RedisTemplate<>();        //使用fastjson序列化        FastJson2JsonRedisSerializer fastJsonRedisSerializer = new FastJson2JsonRedisSerializer(Object.class);        // value值的序列化采用fastJsonRedisSerializer        template.setValueSerializer(fastJsonRedisSerializer);        template.setHashValueSerializer(fastJsonRedisSerializer);        // key的序列化采用StringRedisSerializer        template.setKeySerializer(new StringRedisSerializer());        template.setHashKeySerializer(new StringRedisSerializer());        template.setConnectionFactory(redisConnectionFactory);        return template;    }​}​

结果:

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!