缓存springboot整合redis01

eclipse创建springboot要注意,基本的包名一定要与java中的包名一致,这样才能找到springgboot主程序的入口;
主程序是在com.lazy.cache;那么test的包也要是com.lazy.cache
src/main/java
com.lazy.cache
CacheApplication.java
src/test/java
com.lazy.cahche
UserTest.java
----
注:#开启mybatis驼峰命名,数据字段名与属性名不一致,如:t_id,tId;需要开启这个,不然查询的结果为null
mybatis.configuration.map-underscore-to-camel-case=true
--------------
springboot知识点:
springboot-cache(缓存):
需要引入springboot缓存依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
--------------

1、开启基于注解的缓存,在主程序入口类上面,使用注解@EnableCaching

MapperScan("com.lazy.cache.mapper")//扫描mapper接口
@SpringBootApplication
@EnableCaching
public class CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }

}

2、标注缓存注解(需要的缓存的方法上,将方法返回结果放入缓存中)
@Cacheable 对方法中的返回结果放入缓存中

/**
 * @Cacheable(key-value的形式)
 * 有几个属性:
 * cacheNames/value指定缓存组件的名字,员工放在emp组件中,里面可以放入多个key-value
 * key:缓存中的key名字,默认是方法参数的值,比如这里的id=1,那么key就是1;可以知道SpEL表达式指定key值
 *     #root.args[0]是取方法参数第一个参数等价于#id
    自定义key(名为getEmployeeById[id]): key="#root.method.name+‘[‘+#id+‘]‘";方法名加参数的形式
    自定义key生成器,
 * keyGenerator:key的生成器
 * key/keyGenerator二选一
 * cacheManager:指定缓存管理器
 * condition:指定符合条件的情况下进行缓存
 *     condition="#id>0"
 * unless:符合条件的不缓存,与condition相反
 * #result可以取到结果的返回值
 * sync:缓存是否使用异步
 */
@Cacheable(cacheNames={"emp"})
public Employee getEmployeeById(Integer id) {
    System.out.println("查询"+id+"号信息");
    Employee employee = employeeMapper.getEmployeeById(id);
    return employee;
}

原理:
1、自动配置类:CacheAutoConfiguration
2、缓存的配置类:默认redis
运行流程:
1、方法运行之前,先去查询cache,按照指定的cacheNames指定的名字获取缓存,第一次获取缓存(是为null)会先创建缓存(名为emp,这里的key是默认id)
2、去Cache中查找缓存的内容,使用一个key,默认就是方法的参数;key是按照某种策略生成的;默认是使用keyGenerator生成的,
3、没有查到缓存就调用目标方法
4、将目标方法返回结果,放进缓存中
@Cacheable标注的方法执行之前先检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,如果没有就进入目标方法中,到数据库中查询;数据库查询的结果返回,会将该结果放入到缓存中,下次在进行这个key查询,也会先到缓存中查询,缓存中存在这个key,就直接返回这个结果,不进入方法中。
注:配置前面的直接运行,会出现异常(找不到端口).但开启redis后,可以正常运行。看视频,都能正常运行,也没开rdeis,这是什么原因,还有这样cache的数据是存储在哪里的。版本问题,在1.5springboot版本默认的是SimpleCacheConfiguration,而在2.1版本是默认的是RedisCacheConfiguration缓存生效。所以在缓存需要打开redis服务端,在配置文件配置debug=true;可以看到容器启动加载了多少类。上面的是错误的,默认的还是SimpleCacheConfiguration,造成的原因是导入了redis的starter,它会启动redis的,如果没有导入redis的starter默认的还是SimpleCacheConfiguration。
--------------

@CachePut修改了某数据,更新缓存,同步缓存
/**
 * @CachePut执行时机:是先执行目标方法,然后将方法的返回结果,更新到缓存中
 * key="#employee.id"可以用key="#result.id"
 * 属性基本相同
 */
@CachePut(value="emp",key="#employee.id")
public Employee updateEmployee(Employee employee) {
    System.out.println("更新员工:"+employee);
    employeeMapper.updateEmployee(employee);
    return employee;
}
@CacheEvict清除缓存
/**
 * 删除缓存
 * allEntries默认是false,
 * @CacheEvict(value="emp",allEntries=true)")清除emp组件中所有缓存
 * beforeInvocation默认是false,清除缓存在方法之后执行。
 *     设置为true,可以在方法前执行,尽管方法中出现异常也可以清除数据库
 */
@CacheEvict(value="emp",key="#id",allEntries=true)
public void DeleteEmployee(Integer id) {
    System.out.println("将缓存中的数据清除!,这里并没有把数据库中的数据删除");
}
----------
/**
 * 组合成复杂的缓存,
 * @Cacheable(value="emp",key="#lastName")执行目标方法前
 * @CachePut(value="emp",key="#result.id"),
 * 将执行方法后以key="#result.id",key="#result.email存入缓存中
 * @param lastName
 * @return
 * 出现异常信息
 */
/*@Caching(
    cacheable = {
            @Cacheable(value="emp",key="#lastName")
    },
    put = {
            @CachePut(value="emp",key="#result.id"),
            @CachePut(value="emp",key="#result.email")
    }
)*/
public Employee getEmpByLastName(String lastName) {
    Employee employee = employeeMapper.getEmpByLastName(lastName);
    return employee;
}

springboot整合redis
1、使用docker安装redis,这里使用widows版本,可以在redis官方文档中有详细的信息
2、引入redis的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3、在配置文件中配置redis(不需要指定端口,默认的是6379)
spring.redis.host=127.0.0.1

public class RedisTest {

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;//key-value是字符串形式
    @Autowired
    private RedisTemplate redisTemplate;//key-value是Object-Object的形式
    @Autowired
    private RedisTemplate<Object, Employee> empRedisTemplate;//自定义的redis模板,以json序列化

    /**
     * 以stringRedisTemplate操作redis
     * redis可以存储五种类型的数据结构,String类型,hash类型,set,list,zset
     * stringRedisTemplate.opsForValue()是操作String类型的
     * stringRedisTemplate.opsForHash()是操作hash类型
     * stringRedisTemplate.opsForSet()是操作Set类型
     * stringRedisTemplate.opsForZSet()是操作ZSet类型
     * stringRedisTemplate.opsForList()是操List类型
     */
    @Test
    public void demoRedis(){
        //向redis中添加一个string类型的数据
        //stringRedisTemplate.opsForValue().append("msg", "hello");
        //获取redis中的元素
        //String msg = stringRedisTemplate.opsForValue().get("msg");
        //System.out.println(msg);
        //添加一个list数据,是从左边插入的,
        //stringRedisTemplate.opsForList().leftPush("mylist", "first");
        //stringRedisTemplate.opsForList().leftPush("mylist", "second");
        //获取list的数据
        String result = stringRedisTemplate.opsForList().leftPop("mylist");
        System.out.println(result);
    }

    /**
     * 使用redisTemplate操作存储对象
     */
    @Test
    public void testRedis(){
        Employee employee = employeeMapper.getEmployeeById(1);
        //这里存放到redis是jdk序列化的数据,不是像json的数据类型
        //如果要对象在redis中以json数据呈现,需要设置配置类,序列化(使用json Serializable)
        //redisTemplate.opsForValue().set("emp01", employee);
        empRedisTemplate.opsForValue().set("emp01", employee);
    }
}
----------------
@Configuration
public class MyRedisConfig {

    @Bean
    public RedisTemplate<Object,Employee> empRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
                    throws UnknownHostException {
        RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>();
        template.setConnectionFactory(redisConnectionFactory);
        //设置序号化形式,以json
        Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer<>(Employee.class);
        template.setDefaultSerializer(serializer);
        return template;
    }

}

上面的是测试:现在在项目中运用,保存对象时,还是默认的jdk序列化。要保存json的话:
1、引入redis的starter,cacheMananger变为RedisCacheManager
2、默认创建的RedisCacheManager操作redis的时候使用的是RedisTemplate<Object,Object>,
3、RedisTemplate<Object,Object>默认使用是JDK序列化,
4、自定义CacheMananger,

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;//key-value是字符串形式
    @Autowired
    private RedisTemplate redisTemplate;//key-value是Object-Object的形式
    //@Autowired
    //private RedisTemplate<Object, Employee> empRedisTemplate;//自定义的redis模板,以json序列化

    /**
     * 以stringRedisTemplate操作redis
     * redis可以存储五种类型的数据结构,String类型,hash类型,set,list,zset
     * stringRedisTemplate.opsForValue()是操作String类型的
     * stringRedisTemplate.opsForHash()是操作hash类型
     * stringRedisTemplate.opsForSet()是操作Set类型
     * stringRedisTemplate.opsForZSet()是操作ZSet类型
     * stringRedisTemplate.opsForList()是操List类型
     */
    @Test
    public void demoRedis(){
        //向redis中添加一个string类型的数据
        //stringRedisTemplate.opsForValue().append("msg", "hello");
        //获取redis中的元素
        //String msg = stringRedisTemplate.opsForValue().get("msg");
        //System.out.println(msg);
        //添加一个list数据,是从左边插入的,
        //stringRedisTemplate.opsForList().leftPush("mylist", "first");
        //stringRedisTemplate.opsForList().leftPush("mylist", "second");
        //获取list的数据
        String result = stringRedisTemplate.opsForList().leftPop("mylist");
        System.out.println(result);
    }

    /**
     * 使用redisTemplate操作存储对象
     */
    @Test
    public void testRedis(){
        Employee employee = employeeMapper.getEmployeeById(1);
        //这里存放到redis是jdk序列化的数据,不是像json的数据类型
        //如果要对象在redis中以json数据呈现,需要设置配置类,序列化(使用json Serializable)
        //redisTemplate.opsForValue().set("emp01", employee);
        redisTemplate.opsForValue().set("emp01", employee);
    }
}
------------
@Configuration
public class MyRedisConfig {
    /**
     * 直接使用模板操作redis需要这样设置
     * @param redisConnectionFactory
     * @return
     * @throws UnknownHostException
     */
    @Bean
    public RedisTemplate<Object,Employee> empRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
                    throws UnknownHostException {
        RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>();
        template.setConnectionFactory(redisConnectionFactory);
        //设置序号化形式,以json
        Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer<>(Employee.class);
        template.setDefaultSerializer(serializer);
        return template;
    }
    /**
     * 这是在项目中,将对象存入redis中以json形式,
     *,2.x版本没有new RedisCacheManager(RedisTemplate)构造方法
     * 使用这个的话new RedisCacheManager(RedisTemplate),
     * 在项目中需要给每个存储对象都写RedisTemplate<Object,Object);
     * 下面这个设置可以通用
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.
                SerializationPair.fromSerializer(jsonSerializer);
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(pair);

        return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
    }

     /**
     * 缓存管理器
     */
   /* @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        //设置CacheManager的值序列化方式为json序列化
        RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
                                                    .fromSerializer(jsonSerializer);
        RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig()
                                                    .serializeValuesWith(pair);
        //设置默认超过期时间是30秒
        defaultCacheConfig.entryTtl(Duration.ofSeconds(30));
        //初始化RedisCacheManager
        return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
    }*/
}

注:可以使用两种方法进行redis缓存,一种是注入RedisTemplate模板操作,这种操作比较复杂,但比较灵活,在程序指定的位置进行放入。
第二种方式使用注解方式,@Cachalbe,等等
----------
不使用注解:
注入缓存管理器
Cache dept = deptCacheManager.getCache("dept");//dept是上面注解的@Cacheable(value="dept")形式
dept.put("dept:1",department);

原文地址:https://www.cnblogs.com/lazyli/p/10804264.html

时间: 2024-11-15 11:58:29

缓存springboot整合redis01的相关文章

SpringBoot 整合 Redis缓存

在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. SpringBoot整合Redis是非常方便快捷的,我用的是Mybatis,这里就不说Springboot整合Mybatis了网上有很多,同样非常简单. 下面进入正题: 原文地址:https://www.cnblogs.com/yueguanguanyun/p/9756058.html

SpringBoot整合Shiro 涉及跨域和@Cacheable缓存/@Transactional事务注解失效问题(五)

1. 跨域(多出现在前后端分离项目中) (1) 跨域介绍可参考:跨域(CORS) (2) SpringBoot中解决跨域方式有: A. 使用@CrossOrigin注解: B. 实现Filter类,重写doFilter方法 package com.ruhuanxingyun.config; import cn.hutool.core.util.StrUtil; import org.springframework.context.annotation.Configuration; import

SpringBoot整合Shiro 集成Redis缓存(六)

简介:由于考虑到项目后期分布式部署,所以缓存由ehcache改为redis,而redis既有单机版部署,也有分布式部署,所以二者需要兼容. 1. maven依赖 <dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis</artifactId> <version>3.1.0</version> </dependency> 2. 设

SpringBoot系列十二:SpringBoot整合 Shiro

1.概念:SpringBoot 整合 Shiro 2.具体内容 Shiro 是现在最为流行的权限认证开发框架,与它起名的只有最初的 SpringSecurity(这个开发框架非常不好用,但是千万不要 以为 SpringSecurity 没有用处,它在 SpringCloud 阶段将发挥重大的作用).但是现在如果要想整合 Shiro 开发框架有一点很遗憾, SpringBoot 没有直接的配置支持,它不像整合所谓的 Kafka.Redis.DataSource,也就是说如果要想整合 Shiro 开

九、springboot整合redis二之缓冲配置

1.创建Cache配置类 @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSupport { @Value("${redis.cache.expiration}") private Long expiration; /** * * 管理缓存 */ @Bean public CacheManager cacheManager(RedisTemplate<Obje

Spring Boot入门系列六( SpringBoot 整合thymeleaf)

SpringBoot 整合thymeleaf 一.什么是Thymeleaf模板 Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎.类似JSP,Velocity,FreeMaker等,它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎.与其它模板引擎相比,Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用.它的功能特性如下: @Controller中的方法可以直接返回模板名称,接下来Thyme

SpringBoot整合Jsp和Thymeleaf (附工程)

前言 本篇文章主要讲述SpringBoot整合Jsp以及SpringBoot整合Thymeleaf,实现一个简单的用户增删改查示例工程.事先说明,这两个是单独整合的,也就是两个工程.如需其中一个,只需看相应部分的介绍即可.若需工程源代码,可以直接跳到底部,通过链接下载工程代码. SpringBoot整合Jsp 开发准备 环境要求 JDK: 1.7或以上 SQL: MySql 这里我们需要在mysql中建立一张用户表,用于存储用户的信息. 数据库脚本如下: CREATE TABLE `t_user

SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统

1.前言本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例. 使用技术:SpringBoot.mybatis.shiro.thymeleaf.pagehelper.Mapper插件.druid.dataTables.ztree.jQuery 开发工具:intellij idea 数据库:mysql.redis 2.表结构还是是用标准的5张表来展现权限.如下图:image 分别为用户表,角色表,资源表,用户角色表,角色资源表.在这个demo中使用了mybat

SpringBoot整合集成redis

Redis安装:https://www.cnblogs.com/zwcry/p/9505949.html 1.pom.xml <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: