>  기사  >  데이터 베이스  >  SpringBoot가 Redis 캐시를 통합하는 방법

SpringBoot가 Redis 캐시를 통합하는 방법

尚
앞으로
2020-05-12 09:19:022604검색

SpringBoot가 Redis 캐시를 통합하는 방법

원격 액세스 활성화:

redis에서 redis.conf 파일을 찾아서 편집하세요(설치 경로에서 찾으세요)

vim ./redis.conf

1. 바인딩 127.0.0.1을 찾아 주석 처리하세요

기본값 127.0.0.1 로컬에서만 액세스할 수 있으므로 IP 액세스를 위해 주석 처리합니다

2. 보호 모드 속성 값을 no로 수정합니다

주석 처리하고 IP 액세스에 대한 보호 모드를 비활성화합니다

3. yes

daemonize를 yes로 설정하면 백그라운드 작업이 시작됩니다

4. 열린 포트 6379

/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT

6379는 기본적으로 공개되지 않습니다

5. redis 시작

redis-server /myconf/redis.conf

redis-server 기본값은 /usr/local/입니다. bin 경로, redis.conf는 redis에 설치됩니다.

6. 연결 테스트

redis-cli -h 192.168.126.129 -p 6379

redis-cli -h redis 서버 IP -p 6379 -a 비밀번호(redis 비밀번호가 설정되지 않은 경우 공백으로 두지 마십시오) 그렇지 않으면 오류가 보고됩니다)

SpringBoot가 Redis 캐시를 통합하는 방법

Java 코드 작성:

프로젝트 소스 코드 구조

SpringBoot가 Redis 캐시를 통합하는 방법

A 사용자 테이블

SpringBoot가 Redis 캐시를 통합하는 방법

코드:

pom.xml 파일(또는 추가할 수 있음) 필요에 따라 수정하세요)

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

        <!-- mybatis 与 spring boot 2.x的整合包 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--mysql JDBC驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</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-data-redis</artifactId>
        </dependency>

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

다음은 springboot 구성 파일 application.yml입니다. redis 구성(내부에 주석과 설명이 있습니다)

server:
  port: 8081
 
#数据库连接
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mytest_springboot_cache?useUnicode=true
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: lzh
 
  ## Redis 配置
  redis:
    ## Redis数据库索引(默认为0)
    database: 0
    ## Redis服务器地址
    host: 192.168.126.129
    ## Redis服务器连接端口
    port: 6379
    ## Redis服务器连接密码(默认为空)
    password:
    jedis:
      pool:
        ## 连接池最大连接数(使用负值表示没有限制)
        #spring.redis.pool.max-active=8
        max-active: 8
        ## 连接池最大阻塞等待时间(使用负值表示没有限制)
        #spring.redis.pool.max-wait=-1
        max-wait: -1
        ## 连接池中的最大空闲连接
        #spring.redis.pool.max-idle=8
        max-idle: 8
        ## 连接池中的最小空闲连接
        #spring.redis.pool.min-idle=0
        min-idle: 0
    ## 连接超时时间(毫秒)
    timeout: 1200
 
  #将themilef的默认缓存禁用,热加载生效
  thymeleaf:
    cache: false
 
  #mybatis的下划线转驼峰配置
  configuration:
    map-underscore-to-camel-case: true
 
    #另外一种打印语句的方式
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 
#打印sql时的语句
logging:
  level:
    com:
      acong:
        dao: debug
  file: d:/logs/bsbdj.log

그 다음에는 엔터티 클래스가 있는데 비교적 간단하므로 생략하겠습니다. 세부 사항으로 들어가지 마세요

package com.lzh.springbootstudytest.bean;
 
import java.io.Serializable;
 
/**
 * @author lzh
 * create 2019-09-18-22:32
 */
public class User implements Serializable {
 
    private static final long serialVersionUID = 1L;
    private int uid;
    private String userName;
    private String passWord;
    private int salary;
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    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 int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
    public User(int uid, String userName, String passWord, int salary) {
        super();
        this.uid = uid;
        this.userName = userName;
        this.passWord = passWord;
        this.salary = salary;
    }
    public User() {
        super();
    }
} 

이것은 인터페이스 액세스를 노출하는 데 사용되는 컨트롤러 클래스입니다

package com.lzh.springbootstudytest.controller;
 
import com.lzh.springbootstudytest.bean.User;
import com.lzh.springbootstudytest.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * @author lzh
 * create 2019-09-18-22:36
 */
@RestController
public class TestController {
 
    @Autowired
    private UserService userService;
 
    @RequestMapping("/queryAll")
    public List<User> queryAll(){
        List<User> lists = userService.queryAll();
        return lists;
    }
 
    @RequestMapping("/findUserById")
    public Map<String, Object> findUserById(@RequestParam int id){
        User user = userService.findUserById(id);
        Map<String, Object> result = new HashMap<>();
        result.put("uid", user.getUid());
        result.put("uname", user.getUserName());
        result.put("pass", user.getPassWord());
        result.put("salary", user.getSalary());
        return result;
    }
 
    @RequestMapping("/updateUser")
    public String updateUser(){
        User user = new User();
        user.setUid(1);
        user.setUserName("cat");
        user.setPassWord("miaomiao");
        user.setSalary(4000);
 
        int result = userService.updateUser(user);
 
        if(result != 0){
            return "update user success";
        }
 
        return "fail";
    }
 
    @RequestMapping("/deleteUserById")
    public String deleteUserById(@RequestParam int id){
        int result = userService.deleteUserById(id);
        if(result != 0){
            return "delete success";
        }
        return "delete fail";
    }
}

재구성 템플릿 직렬화 구성

package com.lzh.springbootstudytest.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.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.StringRedisSerializer;
 
import java.time.Duration;
 
/**
 * @author lzh
 * create 2019-09-24-15:07
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
 
    /**
     * 选择redis作为默认缓存工具
     * @param redisConnectionFactory
     * @return
     */
    /*@Bean
    //springboot 1.xx
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
        return rcm;
    }*/
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
        return RedisCacheManager
                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                .cacheDefaults(redisCacheConfiguration).build();
    }
 
    /**
     * retemplate相关配置
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
 
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);
 
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jacksonSeial = 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);
        jacksonSeial.setObjectMapper(om);
 
        // 值采用json序列化
        template.setValueSerializer(jacksonSeial);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
 
        // 设置hash key 和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();
 
        return template;
    }
 
    /**
     * 对hash类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }
 
    /**
     * 对redis字符串类型数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForValue();
    }
 
    /**
     * 对链表类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForList();
    }
 
    /**
     * 对无序集合类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForSet();
    }
 
    /**
     * 对有序集合类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForZSet();
    }
}

그리고 Mapper 지속성 레이어 Dao가 있습니다. 여기에서 주석을 사용하여 작성하는 것이 더 편리합니다. mybatis의 xml 구성 파일을 사용하여 SQL 문

package com.lzh.springbootstudytest.mapper;
 
import com.lzh.springbootstudytest.bean.User;
import org.apache.ibatis.annotations.*;
 
import java.util.List;
 
/**
 * @author lzh
 * create 2019-09-18-22:32
 */
@Mapper
public interface UserDao {
 
    @Select("select * from user")
    List<User> queryAll();
 
    @Select("select * from user where uid = #{id}")
    User findUserById(int id);
 
    @Update("UPDATE USER SET username = CASE WHEN (#{userName} != NULL) AND (#{userName} != &#39;&#39;) THEN #{userName},PASSWORD = CASE WHEN (#{passWord} != NULL) AND (#{passWord} != &#39;&#39;) THEN #{passWord},salary = CASE WHEN (#{salary} != 0) THEN #{salary} WHERE uid = #{uid}")
    int updateUser(@Param("user") User user);
 
    @Delete("delete from user where uid = #{id}")
    int deleteUserById(int id);
 
}

service 레이어를 작성합니다. 여기서는 주로 Redis 템플릿을 사용하여 작성합니다

package com.lzh.springbootstudytest.service;
 
import com.lzh.springbootstudytest.bean.User;
import com.lzh.springbootstudytest.mapper.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
 
import java.util.List;
import java.util.concurrent.TimeUnit;
 
/**
 * @author lzh
 * create 2019-09-18-22:33
 */
@Service
public class UserService {
 
    @Autowired
    private UserDao userDao;
 
    @Autowired
    private RedisTemplate redisTemplate;
 
    public List<User> queryAll() {
        return userDao.queryAll();
    }
 
    /**
     * 获取用户策略:先从缓存中获取用户,没有则取数据表中 数据,再将数据写入缓存
     */
    public User findUserById(int id) {
        String key = "user_" + id;
 
        ValueOperations<String, User> operations = redisTemplate.opsForValue();
 
        //判断redis中是否有键为key的缓存
        boolean hasKey = redisTemplate.hasKey(key);
 
        if (hasKey) {
            User user = operations.get(key);
            System.out.println("从缓存中获得数据:"+user.getUserName());
            System.out.println("------------------------------------");
            return user;
        } else {
            User user = userDao.findUserById(id);
            System.out.println("查询数据库获得数据:"+user.getUserName());
            System.out.println("------------------------------------");
 
            // 写入缓存
            operations.set(key, user, 5, TimeUnit.HOURS);
            return user;
        }
    }
 
    /**
     * 更新用户策略:先更新数据表,成功之后,删除原来的缓存,再更新缓存
     */
    public int updateUser(User user) {
        ValueOperations<String, User> operations = redisTemplate.opsForValue();
        int result = userDao.updateUser(user);
        if (result != 0) {
            String key = "user_" + user.getUid();
            boolean haskey = redisTemplate.hasKey(key);
            if (haskey) {
                redisTemplate.delete(key);
                System.out.println("删除缓存中的key-----------> " + key);
            }
            // 再将更新后的数据加入缓存
            User userNew = userDao.findUserById(user.getUid());
            if (userNew != null) {
                operations.set(key, userNew, 3, TimeUnit.HOURS);
            }
        }
        return result;
    }
 
    /**
     * 删除用户策略:删除数据表中数据,然后删除缓存
     */
    public int deleteUserById(int id) {
        int result = userDao.deleteUserById(id);
        String key = "user_" + id;
        if (result != 0) {
            boolean hasKey = redisTemplate.hasKey(key);
            if (hasKey) {
                redisTemplate.delete(key);
                System.out.println("删除了缓存中的key:" + key);
            }
        }
        return result;
    }
 
} 

여기에서는 주로 RedisTemplate을 사용하여 원격 Redis를 작동합니다. 데이터가 Redis Cache에 존재하며, 존재하지 않는 경우에는 데이터베이스에서 데이터를 읽어서 Redis Cache에 저장하면 됩니다.

이렇게 하면 매번 SQL 문을 실행할 필요가 없어져 액세스 속도가 향상될 수 있습니다. 하지만 캐시에 데이터를 저장할 때 키와 값을 설정하고 시간 제한을 두고 삭제하세요. 캐시를 삭제하기 위해 시간 초과를 너무 오랫동안 설정하지 않으면 서버에 부담이 가해집니다.

스프링 부트 시작 클래스를 실행하고, http://localhost:8081/findUserById?id=1

SpringBoot가 Redis 캐시를 통합하는 방법

다시 http://localhost:8081/findUserById?id=1을 방문하여 저장된 데이터를 가져옵니다. 캐시 데이터

SpringBoot가 Redis 캐시를 통합하는 방법

더 많은 Redis 지식을 알고 싶다면 redis 튜토리얼 칼럼을 주목해주세요.

위 내용은 SpringBoot가 Redis 캐시를 통합하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제