1 Springboot에서 redis를 사용하여 자동 캐시, 업데이트, 삭제

첫 번째 편은springboot에서redis의 기본적인 사용법을 기록하고 새로 추가된 데이터를 자동으로 캐시하며 자동으로 수정하고 삭제합니다.
이 컴퓨터에 mysql와redis를 설치합니다.springboot의 웹 프로젝트를 새로 만듭니다. 새 프로젝트를 만들 때 Redis, mysql를 선택하십시오.
pom 파일은 다음과 같습니다.
<?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>

	<groupId>com.tianyalei</groupId>
	<artifactId>demo0</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demo0</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</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-web</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.18</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

데이터베이스 연결 탱크에 사용되는druid는spring-boot-starter-data-redis를 사용하는데 이 의존만으로도 충분합니다. 시스템은 Redis를 식별하고 응용할 수 있습니다.dao 도구용 jpa, 기본적으로hibernate가 통합되어 있습니다.
다음은 응용 프로그램을 설정합니다.yml.다음과 같습니다.
spring:
  jpa:
    database: mysql
    show-sql: true
    hibernate:
      ddl-auto: update
  datasource:
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/tx2
      username: root
      password:

show-sql을true로 설정합니다. 표를 찾을 때의 캐시 효과를 보기 위해서입니다.리디스의 IP는 포트 따위가 어울리지 않고 시스템에 기본값이 있으니 이따가 보면 알 수 있을 거예요. 
자바빈을 만듭니다.
package com.tianyalei.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;

/**
 * Created by wuwf on 17/4/21.
 */
@Entity
public class Post implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String content;

    private Integer weight;

    public Integer getId() {
        return id;
    }

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }
}

repository 만들기
package com.tianyalei.repository;

import com.tianyalei.domain.Post;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created by wuwf on 17/4/20.
 */
@CacheConfig(cacheNames = "post")
public interface PostRepository extends PagingAndSortingRepository<Post, Integer> {
    @Cacheable(key = "#p0")
    Post findById(int id);

    /**
     *       
     */
    @CachePut(key = "#p0.id")
    @Override
    Post save(Post post);

    @Transactional
    @Modifying
    int deleteById(int id);
}
이 안에는 CacheConfig이 있고,cacheNames가 설치되어 있습니다.
findById 방법에 @Cacheable (key="#p0") 을 추가했습니다. #p0은 첫 번째 인자, 즉 id를 대표합니다.이 말을 더하면findById를 호출할 때, 먼저 Redis의post 캐시 대상에서 키가 전송된 id와 같은 값을 조회합니다.없으면 시계를 찾아라.
save 방법에 CachePut을 추가하면 캐시에 값을 추가합니다. 키는 매개 변수post의 id 속성입니다. 이렇게 하면 우리가 save의 Post 대상을 저장할 때 Redis는 id를 키로 하는 Post 대상을 추가합니다.업데이트 작업이라면, Redis는 id와 같은 Post 대상의 값을 덮어쓰고 업데이트를 완료합니다.더 많은 라벨http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html#cache-spel-context
이렇게 하면post에 대한 추가와 수정 시 리디스에 자동으로 캐시됩니다.
다음은 검증해 보겠습니다.
서비스 추가
package com.tianyalei.service;

import com.tianyalei.domain.Post;
import com.tianyalei.repository.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


/**
 * Created by wuwf on 17/4/20.
 */
@Service
public class PostService {
    @Autowired
    private PostRepository postRepository;

    public Post findById(int id) {
        return postRepository.findById(id);
    }

    public Post save(Post post) {
        return postRepository.save(post);
    }

    public int delete(int id) {
        return postRepository.deleteById(id);
    }
}
컨트롤러 주세요.
package com.tianyalei.controller;

import com.tianyalei.domain.Post;
import com.tianyalei.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * Created by wuwf on 17/4/20.
 */
@RestController
public class PostController {
    @Autowired
    private PostService postService;

    @RequestMapping("/query/{id}")
    public Object query(@PathVariable int id) {
        return postService.findById(id);
    }

    @RequestMapping("/save")
    public Object save(@ModelAttribute Post post) {
        return postService.save(post);
    }

    @RequestMapping("/delete/{id}")
    public Object delete(@PathVariable int id) {
        return postService.delete(id);
    }

    @RequestMapping("/queryPage")
    public Object query(String name, int pageNum, int count) {
        //  weight      
//        Pageable pageable = new PageRequest(pageNum, count, Sort.Direction.DESC, "weight");
//        return userRepository.findByName(name, pageable);
        return null;
    }
}
그리고 Application을 시작합니다. 시작하기 전에 @EnableCaching 주석을 붙여야 캐시가 정상적으로 작동합니다.
package com.tianyalei;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Demo0Application {

	public static void main(String[] args) {
		SpringApplication.run(Demo0Application.class, args);
	}
}
시작 후 액세스http://localhost:8080/save?content=1&weight=1
이렇게 하면 컨트롤러에 insert 문구가 있는 기록을 추가합니다.
그리고 조회에 방문하면,http://localhost:8080/query/1
id가 1인 이 기록을 조회했고 컨트롤러가 select 조회 문구를 걷지 않았습니다. 즉, 데이터베이스에 접근하지 않고 Redis 캐시에서 직접 가져간 값입니다.
다음은 Redis에 동기화되는지 확인하기 위한 업데이트 작업입니다.http://localhost:8080/save?content=1&weight=2&id=1
weight를 2로 바꾸고 주소를 방문해서 결과를 보세요.
콘솔에서 두 개의 문장을 인쇄했다
Hibernate: select post0_.id as id1_0_0_, post0_.content as content2_0_0_, post0_.weight as weight3_0_0_ from post post0_ where post0_.id=? Hibernate: update post set content=?, weight=? where id=?
데이터가 업데이트되었다는 뜻이다.그리고 다시 조회http://localhost:8080/query/1
검색한 데이터가 바뀌었고, 컨트롤러가 select 문구를 걷지 않았습니다. 업데이트할 때, Redis가 업데이트되었음을 의미합니다.
다음은 삭제 작업을 하면 데이터베이스에서 이 기록을 직접 삭제하거나 브라우저 방문을 통해 삭제할 수 있다.http://localhost:8080/delete/1
컨트롤러가 갔습니다. delete 문장을 삭제합니다.다시 방문하여 주소를 조회하다.이 기록, 즉db의 삭제가 성공했지만 리디스는 삭제하지 않았습니다.
그럼 어떻게db에서 삭제할 때,redis와 관련된 기록도 삭제합니까?
CacheEvict로
@CacheConfig(cacheNames = "post")
public interface PostRepository extends PagingAndSortingRepository<Post, Integer> {
    @Cacheable(key = "#p0")
    Post findById(int id);

    /**
     *       
     */
    @CachePut(key = "#p0.id")
    @Override
    Post save(Post post);

    @Transactional
    @Modifying
    @CacheEvict(key = "#p0")
    int deleteById(int id);
}
이 라벨을 추가한 후 deleteById 방법을 사용하면 키가 id인 Redis 기록을 삭제합니다.다시 시작할 수 있습니다.http://localhost:8080/delete/1
그리고 다시 검색하면 id가 1인 값을 찾을 수 없습니다.
이렇게 해서 우리는 가장 간단한 리디즈를 통합한 데모를 완성했다.단일 대상에 대한 추가 삭제와 수정을 위한 캐시가 포함되어 있습니다.
그러면 다음 몇 가지 질문을 드리겠습니다.
1. 왜 Redis의 주소,port,비밀번호를 설정하지 않습니까?
위의 기본 Redis에 대한 동작은 Springboot에 통합된 RedisTemplate에서 유래한 것입니다.template에서는 기본적으로 JedisConnectionFactory를 사용하여 기본 연결 속성 설정을 합니다.
이 안에는 제디스의 연결 주소와 제디스폴에 대한 초기화 작업이 이루어져 있습니다. 기본값입니다.시스템은 이 기본값을 사용하여 Redis를 조작할 것입니다.
다음에 우리는 Connection에 대해 사용자 정의를 하고value의 서열화 방식을 설정하며 연결 주소를 수정할 것입니다. 그러면 사용자 정의 설정을 사용할 것입니다.
2. 위의 방법으로 집합을 저장할 수 있습니까?예를 들어 모든 포스트 집합은 새로 추가될 때 집합도 바뀐다?
안 돼요. 만약에ListfindAll에 캐시를 만들었다면 다음 조회 때 표를 찾을 필요가 없지만, 대상을 추가하거나 수정하거나 삭제할 때 이 캐시의 집합은 변하지 않습니다.
모든 수정할 수 있는 대상에 CacheEvict, 키를 집합한 키로 추가하지 않으면, 모든 수정은 집합 대상의 캐시를 삭제하고, 다음에 다시 검사할 때 캐시를 할 수 있습니다.대부분의 경우 집합 대상은 끊임없이 변화하는데 도시 목록 같은 변하지 않는 것을 제외하고는 이런 캐시 방식을 사용하기에 적합하지 않다.큰 대상을 빈번하게 만들 수 있고, 대부분의 경우 전체 집합을 찾지 않고 페이지를 나누기도 한다.
3. 어떻게 Redis로 집합 조회, 페이지 조회, 심지어 조건 페이지 조회를 합니까?
이것도 문제2의 연장선이다. 뒷편에서 이야기할 것이다.

좋은 웹페이지 즐겨찾기