Redis

Redis_Crud_Example

MIN우 2022. 12. 26. 14:46
728x90

Cache란?

"오랜시간이 걸리는 작업" 혹은 "반복적으로 요청하는 작업"의 결과를 메모리에 저장해서 데이터 접근의 시간과 비용을 줄이는 기법을 의미합니다.

 

application.yml

이번 실습에서는 Cache 저장소로는 Database 저장소로는 OracleDB 를 사용하며, ORM은 JPA를 사용합니다.

 

 

spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=URL주소 
spring.datasource.username=아이디
spring.datasource.password=비번

logging.level.org.hibernate=info


##jpa

spring.jpa.database=oracle

spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=false
spring.jpa.show-sql=true
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
spring.jpa.properties.hibernate.format_sql=true

## redis cashe

spring.redis.host=127.0.0.1
spring.redis.port=6379 
spring.redis.pool.max-idle=8 
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1

build.gradle

    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    //롬복
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok:'
    // oracle db설치

    runtimeOnly 'com.oracle.database.jdbc:ojdbc8'

    implementation 'com.oracle.database.security:oraclepki'

    implementation 'com.oracle.database.security:osdt_core'

    implementation 'com.oracle.database.security:osdt_cert'

    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

Application

** EnableCaching을 사용해야합니다

@EnableCaching
@SpringBootApplication
public class RealjpaApplication {

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

}

Entity

Cache를 사용할 entitiy를 아래와 같이 간단히 작성합니다.

JPA를 사용할 것이므로 @Data와 @Entity 어노테이션을 추가했습니다. 기본적인 생성자 및 Getter/Setter는 @Lombok으로 대체했습니다. 마지막으로 Redis에 저장할때는 Hash를 사용하므로, Serializable을 implements 했습니다.

package com.example.realjpa.domain;

import lombok.*;

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

@Data
@Entity
@AllArgsConstructor
@Getter
@Setter
@NoArgsConstructor
public class Person implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="ID")

    private long id;
    private String firstName;
    private String lastName;
    int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
}

Reposiory

public interface PersonRepository extends JpaRepository<Person,String> {

    public Person findByFirstName(String firstName);
    public List<Person> findByAge(int age);
}

Service

서비스는 아래와 같이 구현합니다.

 

package com.example.realjpa.Service;

import com.example.realjpa.domain.Person;
import com.example.realjpa.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class PersonService {


    @Autowired
    private PersonRepository personRepository;

    //create

    public Person create(String firstName, String lastName, int age) {
        return personRepository.save(new Person(firstName, lastName, age));
    }

    //retrieve
    public List<Person> getAll() {
        return personRepository.findAll();
    }

    //get
    public Person getByFirstName(String firstName) {
        return personRepository.findByFirstName(firstName);
    }

    //update
    public Person update(String firstName, String lastName, int age) {
        Person p = personRepository.findByFirstName(firstName);
        p.setLastName(lastName);
        p.setAge(age);
        return personRepository.save(p);
    }

    //delete
    public void deleteAll() {
        personRepository.deleteAll();
    }


}

 Controller

이제 마지막으로 위에서 작성한 Service를 사용할 Controller를 아래와 같이 작성합니다.

 

package com.example.realjpa.controller;


import com.example.realjpa.Service.PersonService;
import com.example.realjpa.domain.Person;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.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.List;

@RestController
public class PersonController {

    // CachePut 등등 Redis에 Cache한다.
    // CachePut: key값으로 return 된 결과값을 Cache에 저장합니다. 동일한 key값이 이미 있는경우 update
    // Cacheable:동일 key값이 Cache에 있는경우 Cache에서 데이터를 return한다.
    // 만약 동일한 key값이 없을경우 해당메서드를 실행하고 반환된 return 결과값를 Cache에 저장
    //CacheEvict :Cache 에서 데이터를 삭제합니다.

    @Autowired
    private PersonService personService;

    private  static final Logger log = LoggerFactory.getLogger(PersonController.class);

    @RequestMapping("/create")
    @ResponseBody
    @CachePut(value = "persons", key = "#firstName")
    public Person create(@RequestParam String firstName, @RequestParam String lastName, @RequestParam int age){
        log.info("create method call");
        Person p = personService.create(firstName, lastName, age);
        return p;
    }
    @RequestMapping("/get")
    @ResponseBody
    @Cacheable(value = "persons" , key = "#firstName")
    public Person getPerson(@RequestParam String firstName){
        log.info("get method call");
        return personService.getByFirstName(firstName);
    }

    @RequestMapping("/getAll")
    @ResponseBody
    @Cacheable(value = "persons")
    public List<Person> getAll(){
        log.info("getAll method call");
        return personService.getAll();
    }

    @RequestMapping("/update")
    @ResponseBody
    @CachePut(value = "persons", key = "#firstName")
    public Person update(@RequestParam String firstName, @RequestParam String lastName, @RequestParam int age){
        log.info("update method call");
        Person p = personService.update(firstName, lastName, age);
        return p;
    }

    @RequestMapping("/deleteAll")
    @CacheEvict(value = "persons", allEntries = true)
    public void deleteAll(){
        log.info("deleteAll method call");
        personService.deleteAll();
    }
}

POSTMAN 테스트

데이터 삽입

 

 

데이터 가져오기

Cash 에서 데이터를 가져오기때문에 수행시간이 14ms 정도밖에 안걸렸다.

마지막 주의사항

 

테스트를 하기전에 Redis서버를 키고 테스트를 하셔야합니다.

 

728x90