Springboot使用Redis进行数据缓存

1.以往都是在后台直接读取数据库,如果操作过快会给数据库不小的压力,因此java引入了非关系型数据库Redis进行数据缓存,减轻了数据库的负担!

使用测试Redis非关系型数据库,通过查询关系型数据库,查看Redis缓存情况

首先引入pom.xml中的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<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://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.redis</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Redis</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </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-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

实体类

package com.redis.demo.model;


import javax.persistence.*;
import java.io.Serializable;

/**
 * Description
 *
 * @Author: xuxin
 * @Date: 2019/4/15 20:24
 * @Version 1.0
 */
@Entity
@Table(name = "redis_user")
public class User implements Serializable {
    private static final long serialVersionUID = -6522574256668461033L;
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "username")
    private String username;
    @Column(name = "password")
    private String password;
    @Column(name = "email")
    private String email;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public User(String username, String password, String email) {
        this.username = username;
        this.password = password;
        this.email = email;
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

 

 

 

2.JPA连接Mysql数据库读取数据

package com.redis.demo.dao;

import com.redis.demo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * Description
 *
 * @Author: xuxin
 * @Date: 2019/7/5 15:31
 * @Version 1.0
 */
public interface UserDao extends JpaRepository<User, Long> {
}

注释:UserEntity是实体类

3.Service层

package com.redis.demo.service;


import com.redis.demo.dao.UserDao;
import com.redis.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 * Description
 *
 * @Author: xuxin
 * @Date: 2019/4/15 20:29
 * @Version 1.0
 */
@Service
public class UserService {

    private UserDao userDao;

    @Autowired
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * @param id
     * @return
     * @Cacheable 应用到数据的方法上,先从缓存中读取,如果没有再从DB中读取
     * unless 表示条件表达式成立的话不放入缓存
     */
    @Cacheable(value = "user", key = "#id", unless = "#result eq null")
    public User getUserById(Long id) {
        return userDao.findById(id).orElse(null);
    }

    /**
     * CachePut 应用到写数据的方法上,如新增修改方法,调用方法时会自动把相应数据放入缓存
     *
     * @param user
     * @return
     */
    @CachePut(value = "user")
    public User createUser(User user) {
        return userDao.save(user);
    }

    /**
     * @param id
     * @return
     * @CacheEvict 应用到删除数据的方法上,调用方法时会从缓存中删除对应key的数据,
     * 直接运行数据库,结果返回为true,表示删除缓存中id那条目录
     */
    @CacheEvict(value = "user", key = "#id", condition = "#result eq true")
    public boolean deleteById(Long id) {
        userDao.deleteById(id);
        return true;
    }

    @CachePut(value = "user", key = "#user.id")
    public User modifyUser(User user) {
        return userDao.save(user);
    }
}

 

4.controller层

package com.redis.demo.controller;


import com.redis.demo.model.User;
import com.redis.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


/**
 * Description
 *
 * @Author: xuxin
 * @Date: 2019/4/15 19:48
 * @Version 1.0
 */
@RestController
@RequestMapping("/user")
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    //增加
    @PostMapping("/add")
    public User createUser(User user) {
        return userService.createUser(user);
    }

    //删除
    @DeleteMapping("/delete")
    public boolean deleteById(Long id) {
        return userService.deleteById(id);
    }

    //修改
    @PutMapping("/modify")
    public User modifyUser(User user) {
        return userService.modifyUser(user);
    }

    //查询
    @GetMapping("/find")
    public User getUserById(Long id) {
        return userService.getUserById(id);
    }


}

5.application.yml中配置Redis参数

#application.yml

server:
  port: 8080

spring:
  data:
    redis:
      repositories:
        enabled: false #关闭spring data 的redis仓库
  datasource:
    name: test
    url: jdbc:mysql://localhost:3306/test?serverTimezone=PRC&useSSL=false
    username: root
    password: admin
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    properties:
      hibernate:
        globally_quoted_identifiers: true
    show-sql: true
  jackson:
    default-property-inclusion: ALWAYS
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  redis:
    database: 0 #Redis数据索引(默认0)
    host: 127.0.0.1 #f服务器地址
    port: 6379 #Redis服务端口
    password:  #服务连接密码,默认为空

    jedis:
      pool:
        max-active: 8 #连接池最大连接数(使用负值表示没有限制)
        # max-wait: -1 #使用负值表示没有限制
        max-idle: 8 #连接池中最大空闲连接
        min-idle: 0 #连接池中的最小空闲连接

      # lettuce:
      #shutdown-timeout: 1200 #连接超时时间(毫秒)

6.设置Redis项目支持缓存

package com.redis.demo.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.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.StringRedisSerializer;

import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Author:ZhuShangJin
 * Date:2018/6/25
 */
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        template.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    //    redis缓存和EhCache缓存不能同时存在
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//        RedisCacheManager cacheManager = RedisCacheManager.create(redisConnectionFactory);

// 生成一个默认配置,通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.entryTtl(Duration.ofMinutes(1))     // 设置缓存的默认过期时间,也是使用Duration设置
                .disableCachingNullValues();     // 不缓存空值

        // 设置一个初始化的缓存空间set集合
        Set<String> cacheNames = new HashSet<>();
        cacheNames.add("timeGroup");
        cacheNames.add("user");

        // 对每个缓存空间应用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("timeGroup", config);
        configMap.put("user", config.entryTtl(Duration.ofSeconds(120)));

        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)     // 使用自定义的缓存配置初始化一个cacheManager
                .initialCacheNames(cacheNames)  // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }
}

springboot 整合redis一些注解

 

@Cacheable 可用在方法或者类上,用在类上所有的方法起作用。该注解主要用于缓存执行后的结果。可以指定三个属性,value,key,condition。value用于指定作用的缓存对象名称,可以有多个,key指定缓存的键,可以取方法的参数

@Cacheable(value=”users”,key=”#id”) 

public User find(Integer id){};

 

@Cacheable(value=”users”,key=”#p0”)

public User find(Integer id)

@Cacheablle(value=”users”,key=”#user.id”)

public User find(User user)

 

@Cacheable(value=“users”,key=”#p0.id”)

public User find(User user){};

 

也可以写两个value值 @Cacheable(value={“cache1”,“cache2”})

 

condation属性指定发生的条件

       有时候并不希望缓存一个方法所有的返回结果,通过condation属性可以实现这一功能,condation默认为空,表示将缓存所有的调用情形,其值通过springEL表达式来指定,true表示进行缓存处理;false不进行缓存处理,即每次调用该方法时,都会执行一次

@Cacheable(value={“users”},key=”#user.id”,condition=”user.id%2==0”)只有为偶数才缓存

 

@CachePut

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

@CachePut(“users”) //每次都会执行该方法,并将结果存入到制定缓存

public user find(Integer id){};

 

3/ CacheEvict

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

allEntries 属性

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

@CacheEvict(value=”users”,allEntries=true)

public void delete(integer id){}

 

@beforeInvocation属性

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

@CacheEvict(value=”users”,beforeInvocation=true)

publiv void delete(Integer id){}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值