Redis和Spring boot SpringCaChe

注意事项

1.数据库列名列的名字绝对不能是不能是一个字母加一个_为开头

原因: set方法 可能设值不成功

2.Redis作缓存使用

3.开启缓存@EnableCaching

Spring boot配置

pom依赖如下

  <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
        </dependency>

2.application.properties配置文件如下

application.properties文件里面的配置信息
// 配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=dalse
spring.datasource.username=root
spring.datasource.password=123456
#// 配置Jackson日期格式和时区
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-date-keys-as-timestamps=false

#logging.level.com.baomidou.ant.test.dao=debug
// 配置MyBatis-Plus
mybatis-plus.configuration.map-underscore-to-camel-case=true// 将数据库字段名中的下划线转换为驼峰式命名
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl// 使用标准输出实现日志记录
mybatis-plus.mapper-locations=classpath:/mapper/*.xml // 指定Mapper接口的XML文件路径
#逻辑删除   删除之前的值是0  之后是1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.logic-delete-value=1

3.配置自动生成

package com.aaa.com;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.fill.Column;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MyTest {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql:///test","root","123456")
                // 全局配置
                .globalConfig((scanner, builder) -> builder
                        .author("xiaowu")
                        .outputDir("D:\\BaiduNetdiskDownload\\js\\demo23\\src\\main\\java")
                )
                // 包配置
                .packageConfig(
                        (scanner, builder) ->
                                builder
                                        .parent("com.aaa")
                                        .pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\BaiduNetdiskDownload\\js\\demo23\\src\\main\\resources\\mapper")))
                // 策略配置
                .strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
                        .controllerBuilder().enableRestStyle().enableHyphenStyle()
                        .entityBuilder().enableLombok().addTableFills(
                                new Column("create_time", FieldFill.INSERT)
                        ).build())
                /*
                    模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker
                   .templateEngine(new BeetlTemplateEngine())
                   .templateEngine(new FreemarkerTemplateEngine())
                 */
                .execute();
// 处理 all 情况

    }
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }
}

运行后 输入数据库已有的表 自动生成

4.Redist的配置

package com.aaa.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@EnableCaching
@Configuration
public class Redisconfig extends CachingConfigurerSupport {
    /**
     * RedisTemplate
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }
    /**
     * 缓存处理
     * @param factory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

5.关于本项目Application的配置

// 定义Demo23Application类,作为Spring Boot应用的主入口
@SpringBootApplication
// 使用@MapperScan注解,扫描com.aaa.mapper包下的Mapper接口
@MapperScan("com.aaa.mapper")
// 使用@EnableCaching注解,开启缓存功能
@EnableCaching
public class Demo23Application {
    // 定义main方法,作为程序的入口
    public static void main(String[] args) {
        // 调用SpringApplication的run方法,启动Spring Boot应用
        SpringApplication.run(Demo23Application.class, args);
    }
}

6.简单的测试运行

在controler层写下如下代码,运行获取表中信息

// 使用@RestController注解标识这是一个处理HTTP请求的控制器类
@RestController
// 使用@RequestMapping注解指定该控制器处理的URL路径前缀为"/student"
@RequestMapping("/student")
public class StudentController {
    // 使用@Resource注解注入IStudentService实例(接口),用于处理学生相关的业务逻辑
    @Resource
    private IStudentService studentService;
    // 使用@GetMapping注解指定该方法处理GET请求,并映射到"/student"路径下
    @GetMapping
    public List<Student> findAll() {
        // 调用studentService的list方法获取所有学生信息,并将结果存储在list变量中
        List<Student> list = studentService.list();
        // 返回包含所有学生信息的list
        return list;
    }
}

集成 Spring Cache

@Cacheable

注解一般写service层

注解一般放在查询上面

spring缓存注解

Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。所以在使用Spring Cache的时候我们要保证我们缓存的方法对于相同的方法参数要有相同的返回结果。

使用Spring Cache需要我们做两方面的事:

1. 声明某些方法使用缓存

2. 配置Spring对Cache的支持

基于注解的支持

@Cacheable

@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。

@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@Cacheable可以指定三个属性,value、key和condition。

参数

解释

example

value

缓存的名称,在 spring 配置文件中定义,必须指定至少一个

例如:

@Cacheable(value=”mycache”)

@Cacheable(value={”cache1”,”cache2”}

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@Cacheable(value=”testcache”,key=”#userName”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@Cacheable(value=”testcache”,condition=”#userName.length()>2”)

value属性指定Cache名称

value其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

  @RestController
@RequestMapping("/student")
public class StudentController {
    @Resource
    private IStudentService studentService;
    @GetMapping
    //condition 表示条件,满足条件 为true 才缓存
    @Cacheable(value = "student")
    public List<Student> findAll() {
        List<Student> list = studentService.list();
        return list;
    }
}
使用key属性自定义key(可以不写)

key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。

自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。

   @Cacheable(value="users", key="#id")
   public User find(Integer id) {
      return  null;
   }
#p param 参数 0 第一个
   @Cacheable(value="users", key="#p0")
   public User find(Integer id) {
      returnnull;
   }
   @Cacheable(value="users", key="#user.id")
   public User find(User user) {
      returnnull;
   }
   @Cacheable(value="users", key="#p0.id")
   public User find(User user) {
      returnnull;
   }
@GetMapping("test")
    //condition 表示条件,满足条件 为true 才缓存
    @Cacheable(value = "student",key = "#sname",condition = "#sname.length()>2")
    public List<Student> findAll2(String sname) {
        List<Student> list = studentService.list();
        return list;

除了上述使用方法参数作为key之外,Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。

属性名称

描述

示例

methodName

当前方法名

#root.methodName

method

当前方法

#root.method.name

target

当前被调用的对象

#root.target

targetClass

当前被调用的对象的class

#root.targetClass

args

当前方法参数组成的数组

#root.args[0]

caches

当前被调用的方法使用的Cache

#root.caches[0].name

当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。如:

   @Cacheable(value={"users", "xxx"}, key="caches[1].name")
   public User find(User user) {
      returnnull;
   }
condition属性指定发生的条件

有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。如下示例表示只有当user的id为偶数时才会进行缓存。

   @GetMapping("test")
    //condition 表示条件,满足条件 为true 才缓存
    @Cacheable(value = "student",key = "#sname",condition = "#sname.length()>2")
    public List<Student> findAll2(String sname) {
        List<Student> list = studentService.list();
        return list;

@CachePut(一般用于修改)

在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

一般使用在保存,更新方法中。

@CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟 @Cacheable是一样的。

// 使用@PutMapping注解,表示这是一个处理HTTP PUT请求的方法
@PutMapping
// 使用@Cacheable注解,表示这个方法的结果会被缓存,缓存的名称为"upStudent",缓存的键为传入的student对象的id属性
@Cacheable(value = "upStudent", key = "#student.id")
// 定义一个名为updateStudent的方法,接收一个Student类型的参数student
public String updateStudent(Student student) {
    // 调用studentService的updateById方法,传入student对象,返回值赋给布尔变量b
    boolean b = studentService.updateById(student);
    // 打印布尔变量b的值
    System.out.println(b);
    // 将布尔变量b转换为字符串并返回
    return b + "";
}

测试结果

数据库学生名称被修改了

@CacheEvict(一般用于删除)

@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与@Cacheable对应的属性类似。即value表示清除操作是发生在哪些Cache上的(对应Cache的名称);key表示需要清除的是哪个key,如未指定则会使用默认策略生成的key;condition表示清除操作发生的条件。下面我们来介绍一下新出现的两个属性allEntries和beforeInvocation。

1、 allEntries属性(同时清除redis的缓存)

allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。

// 使用@DeleteMapping注解,表示这是一个处理HTTP DELETE请求的方法
@DeleteMapping
// 使用@CacheEvict注解,表示在执行此方法后,需要清除名为"delStudent"的缓存中的数据
// value属性指定了要清除的缓存的名称,key属性指定了缓存中的键值,allEntries属性设置为true表示清除所有匹配的缓存项
@CacheEvict(value = "delStudent", key = "#id", allEntries = true)
// 定义一个名为deleteStudent的方法,接收一个Integer类型的参数id
public String deleteStudent(Integer id) {
    // 调用studentService的removeById方法,传入id参数,返回一个布尔值
    boolean b = studentService.removeById(id);
    // 打印布尔值b
    System.out.println(b);
    // 将布尔值b转换为字符串并返回
    return b + "";
}

缓存已被清除

2、 beforeInvocation属性

清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

@CacheEvict(value="users",key = "#id", beforeInvocation=true)
public void delete(Integer id) {
   System.out.println("delete user by id: " + id);
}

SpringTask(定时任务)

当有超过执行额度的任务量时,分批解决,以避免崩溃

1.在Application中加入如下注解,使开启定时任务

2.建立TaskService代码如下

@Service
public class TaskService {
    @Scheduled(cron = "*/2 * * * * * ")
    public void testTask() {
        System.out.println("这是一个定时任务,两秒一次");
    }
}

3.执行

执行结果

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值