Kotlin + Spring Boot에서 DB 캐시를 Redis로 시도
18128 단어 spring-bootDBRedis캐시Kotlin
소개
Kotlin + Spring-Boot 애플리케이션에서 Redis를 사용하여 DB (MySQL) 데이터를 캐시 해 보았습니다.
환경
Spring Boot 2.2.6
Kotlin 1.3.71
gradle 6.3
프로젝트의 병아리 만들기
Spring Initializr에서 병아리를 만듭니다.
병아리의 설정은 이런 느낌입니다.
h tps : // s rt. sp 링 g. 이오/
MySQL과 Redis 설정
MySQL과 Redis는 설치되어 있다고 가정합니다.
아래와 같이 application.properties 를 기술합니다.
포트는 모두 기본값입니다.
application.properties#MySQL
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=demouser
spring.datasource.password=password
#Redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=null
spring.redis.database=0
Entity 및 Repository 만들기
예로서 이러한 Entity와 Repository를 만듭니다.
User.ktpackage com.example.demo.domain.entity
import java.io.Serializable
import java.util.*
import javax.persistence.*
@Entity
data class User (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id : Int = 0,
var name : String,
var age : Int
) : Serializable
UserRepository.ktpackage com.example.demo.domain.repository
import com.example.demo.domain.entity.User
import org.springframework.data.jpa.repository.JpaRepository
interface UserRepository : JpaRepository<User, Int> {
}
서비스 만들기
DB와 상호 작용하는 클래스를 정의합니다.
동시에 캐시를 보고 히트하면 캐시에서 데이터를 검색합니다.
UserService.ktpackage com.example.demo.app.service
import com.example.demo.domain.repository.UserRepository
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*
@Service
@Transactional
class UserService{
@Autowired
lateinit var userRepository: UserRepository
fun existsById(id : Int) : Boolean {
return userRepository.existsById(id)
}
@Cacheable(cacheNames = ["User"], key = "'User:' + #id")//キャッシュの参照とミスヒット時の登録
fun findById(id : Int) : Optional<User> {
return userRepository.findById(id)
}
}
@Cacheable
어노테이션이 추가 된 함수는 return하기 전에 캐시를 참조합니다. 지정된 키(ex; User::User:1)의 캐쉬가 존재하면 캐쉬로부터 값을 취득해, return 합니다. 캐시가 없으면 return할 값을 지정된 키에 캐시합니다.
이 예제에서는 설명하지 않지만 @CachePut
어노테이션이 추가된 함수는 return 시 return할 값으로 캐시를 업데이트합니다. 예를 들어 DB의 컬럼을 편집할 때 동시에 캐시를 갱신하거나 하는 용도에 사용합니다.
또한 @cacheEvict
는 return시 지정된 키의 캐시를 삭제합니다. DB의 열을 삭제하고 동시에 캐시도 삭제하고 싶을 때 등에 사용합니다.
이 예제에서는 id를 지정하고 해당 열을 검색할 때 캐시를 참조하고 등록하는 함수를 설명합니다.
컨트롤러 작성
UserController.ktpackage com.example.demo.app.controller
import com.example.demo.app.service.UserService
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.ResponseBody
import java.util.*
import kotlin.system.measureTimeMillis
@Controller
class UserController{
@Autowired
lateinit var userService : UserService
@GetMapping("/users/{id}")
@ResponseBody
fun getUser(@PathVariable id: Int) : String {
lateinit var user: Optional<User>
if (userService.existsById(id)) {
val time = measureTimeMillis {
user = userService.findById(id)
}
var name = user.get().name
var age = user.get().age
return "name=$name, age=$age, time=$time(ms)"
}
return "does not exist id=$id"
}
}
/users/{id}
에 요청하면 id가 있으면 DB 또는 캐시에서 데이터를 검색합니다. 그 때에 걸린 시간(time)을 계측해 둡니다. 응답으로서 User의 name, age와 계측한 시간 time를 포함한 캐릭터 라인을 돌려줍니다. id가 존재하지 않으면 존재하지 않는다는 것을 알려주는 문자열을 반환합니다.
Redis config 클래스 만들기
RedicConfig.ktpackage com.example.demo.app.config
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.lettuce.LettuceConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
import org.springframework.data.redis.serializer.StringRedisSerializer
@Configuration
@EnableCaching
class RedisConfig{
@Bean
fun redisConnectionFactory(): LettuceConnectionFactory {
return LettuceConnectionFactory()
}
@Bean
fun redisTemplateSet() : RedisTemplate<String, Object> {
var redisTemplate = RedisTemplate<String, Object>()
redisTemplate.setConnectionFactory(redisConnectionFactory())
redisTemplate.keySerializer = StringRedisSerializer()
redisTemplate.valueSerializer = JdkSerializationRedisSerializer()
redisTemplate.afterPropertiesSet()
return redisTemplate
}
@Bean
fun redisCacheManager(lettuceConnectionFactory : LettuceConnectionFactory) : RedisCacheManager {
var redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
.cacheDefaults(redisCacheConfiguration).build();
}
}
이 예에서 key : "User::User:1"
의 경우 value는 id : 1의 user 데이터 클래스 (id, name, age)를 캐시합니다. 즉 Object를 저장합니다.
데이터베이스 작성 및 테이블 초기화
init.sqlcreate database if not exists demo;
grant all on demo.* to 'demouser'@'%';
create table if not exists demo.user(
id INT(11) AUTO_INCREMENT not null primary key,
name varchar(30) not null,
age INT(3) not null
);
insert into demo.user(name, age)values('A-san', 20);
mysql -u root -p < init.sql
실행해보기
응용 프로그램을 시작합니다.
./gradlew bootRun
다른 터미널에서 요청을 보냅니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=268(ms)
첫 번째는 캐시되지 않고 DB에서 직접 데이터를 검색하므로 268ms로 약간의 시간이 걸립니다.
그대로 다시 동일한 명령을 입력합니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=9(ms)
두 번째는 캐시가 효과적이기 때문에 상당히 빠르게 데이터를 얻을 수 있습니다.
마지막으로
Kotlin + Spring Boot2에서 redis를 사용하여 DB 캐시했습니다.
이 조합으로 redis를 사용하여 DB 캐시를하려고, 특히 RedisConfig.kt에 기술한 내용으로 빠져 버렸으므로, 참고가 되면 다행입니다. 나도 아직 RedisConfig.kt의 내용을 잘 이해하지 못했기 때문에 이것에 대해 뭔가 교수해 주시면 감사하겠습니다.
여기까지 읽어 주셔서 감사합니다!
Reference
이 문제에 관하여(Kotlin + Spring Boot에서 DB 캐시를 Redis로 시도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/syumiwohossu/items/3139e14ca995027c8fdf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Spring Boot 2.2.6
Kotlin 1.3.71
gradle 6.3
프로젝트의 병아리 만들기
Spring Initializr에서 병아리를 만듭니다.
병아리의 설정은 이런 느낌입니다.
h tps : // s rt. sp 링 g. 이오/
MySQL과 Redis 설정
MySQL과 Redis는 설치되어 있다고 가정합니다.
아래와 같이 application.properties 를 기술합니다.
포트는 모두 기본값입니다.
application.properties#MySQL
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=demouser
spring.datasource.password=password
#Redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=null
spring.redis.database=0
Entity 및 Repository 만들기
예로서 이러한 Entity와 Repository를 만듭니다.
User.ktpackage com.example.demo.domain.entity
import java.io.Serializable
import java.util.*
import javax.persistence.*
@Entity
data class User (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id : Int = 0,
var name : String,
var age : Int
) : Serializable
UserRepository.ktpackage com.example.demo.domain.repository
import com.example.demo.domain.entity.User
import org.springframework.data.jpa.repository.JpaRepository
interface UserRepository : JpaRepository<User, Int> {
}
서비스 만들기
DB와 상호 작용하는 클래스를 정의합니다.
동시에 캐시를 보고 히트하면 캐시에서 데이터를 검색합니다.
UserService.ktpackage com.example.demo.app.service
import com.example.demo.domain.repository.UserRepository
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*
@Service
@Transactional
class UserService{
@Autowired
lateinit var userRepository: UserRepository
fun existsById(id : Int) : Boolean {
return userRepository.existsById(id)
}
@Cacheable(cacheNames = ["User"], key = "'User:' + #id")//キャッシュの参照とミスヒット時の登録
fun findById(id : Int) : Optional<User> {
return userRepository.findById(id)
}
}
@Cacheable
어노테이션이 추가 된 함수는 return하기 전에 캐시를 참조합니다. 지정된 키(ex; User::User:1)의 캐쉬가 존재하면 캐쉬로부터 값을 취득해, return 합니다. 캐시가 없으면 return할 값을 지정된 키에 캐시합니다.
이 예제에서는 설명하지 않지만 @CachePut
어노테이션이 추가된 함수는 return 시 return할 값으로 캐시를 업데이트합니다. 예를 들어 DB의 컬럼을 편집할 때 동시에 캐시를 갱신하거나 하는 용도에 사용합니다.
또한 @cacheEvict
는 return시 지정된 키의 캐시를 삭제합니다. DB의 열을 삭제하고 동시에 캐시도 삭제하고 싶을 때 등에 사용합니다.
이 예제에서는 id를 지정하고 해당 열을 검색할 때 캐시를 참조하고 등록하는 함수를 설명합니다.
컨트롤러 작성
UserController.ktpackage com.example.demo.app.controller
import com.example.demo.app.service.UserService
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.ResponseBody
import java.util.*
import kotlin.system.measureTimeMillis
@Controller
class UserController{
@Autowired
lateinit var userService : UserService
@GetMapping("/users/{id}")
@ResponseBody
fun getUser(@PathVariable id: Int) : String {
lateinit var user: Optional<User>
if (userService.existsById(id)) {
val time = measureTimeMillis {
user = userService.findById(id)
}
var name = user.get().name
var age = user.get().age
return "name=$name, age=$age, time=$time(ms)"
}
return "does not exist id=$id"
}
}
/users/{id}
에 요청하면 id가 있으면 DB 또는 캐시에서 데이터를 검색합니다. 그 때에 걸린 시간(time)을 계측해 둡니다. 응답으로서 User의 name, age와 계측한 시간 time를 포함한 캐릭터 라인을 돌려줍니다. id가 존재하지 않으면 존재하지 않는다는 것을 알려주는 문자열을 반환합니다.
Redis config 클래스 만들기
RedicConfig.ktpackage com.example.demo.app.config
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.lettuce.LettuceConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
import org.springframework.data.redis.serializer.StringRedisSerializer
@Configuration
@EnableCaching
class RedisConfig{
@Bean
fun redisConnectionFactory(): LettuceConnectionFactory {
return LettuceConnectionFactory()
}
@Bean
fun redisTemplateSet() : RedisTemplate<String, Object> {
var redisTemplate = RedisTemplate<String, Object>()
redisTemplate.setConnectionFactory(redisConnectionFactory())
redisTemplate.keySerializer = StringRedisSerializer()
redisTemplate.valueSerializer = JdkSerializationRedisSerializer()
redisTemplate.afterPropertiesSet()
return redisTemplate
}
@Bean
fun redisCacheManager(lettuceConnectionFactory : LettuceConnectionFactory) : RedisCacheManager {
var redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
.cacheDefaults(redisCacheConfiguration).build();
}
}
이 예에서 key : "User::User:1"
의 경우 value는 id : 1의 user 데이터 클래스 (id, name, age)를 캐시합니다. 즉 Object를 저장합니다.
데이터베이스 작성 및 테이블 초기화
init.sqlcreate database if not exists demo;
grant all on demo.* to 'demouser'@'%';
create table if not exists demo.user(
id INT(11) AUTO_INCREMENT not null primary key,
name varchar(30) not null,
age INT(3) not null
);
insert into demo.user(name, age)values('A-san', 20);
mysql -u root -p < init.sql
실행해보기
응용 프로그램을 시작합니다.
./gradlew bootRun
다른 터미널에서 요청을 보냅니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=268(ms)
첫 번째는 캐시되지 않고 DB에서 직접 데이터를 검색하므로 268ms로 약간의 시간이 걸립니다.
그대로 다시 동일한 명령을 입력합니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=9(ms)
두 번째는 캐시가 효과적이기 때문에 상당히 빠르게 데이터를 얻을 수 있습니다.
마지막으로
Kotlin + Spring Boot2에서 redis를 사용하여 DB 캐시했습니다.
이 조합으로 redis를 사용하여 DB 캐시를하려고, 특히 RedisConfig.kt에 기술한 내용으로 빠져 버렸으므로, 참고가 되면 다행입니다. 나도 아직 RedisConfig.kt의 내용을 잘 이해하지 못했기 때문에 이것에 대해 뭔가 교수해 주시면 감사하겠습니다.
여기까지 읽어 주셔서 감사합니다!
Reference
이 문제에 관하여(Kotlin + Spring Boot에서 DB 캐시를 Redis로 시도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/syumiwohossu/items/3139e14ca995027c8fdf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
MySQL과 Redis는 설치되어 있다고 가정합니다.
아래와 같이 application.properties 를 기술합니다.
포트는 모두 기본값입니다.
application.properties
#MySQL
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=demouser
spring.datasource.password=password
#Redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=null
spring.redis.database=0
Entity 및 Repository 만들기
예로서 이러한 Entity와 Repository를 만듭니다.
User.ktpackage com.example.demo.domain.entity
import java.io.Serializable
import java.util.*
import javax.persistence.*
@Entity
data class User (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id : Int = 0,
var name : String,
var age : Int
) : Serializable
UserRepository.ktpackage com.example.demo.domain.repository
import com.example.demo.domain.entity.User
import org.springframework.data.jpa.repository.JpaRepository
interface UserRepository : JpaRepository<User, Int> {
}
서비스 만들기
DB와 상호 작용하는 클래스를 정의합니다.
동시에 캐시를 보고 히트하면 캐시에서 데이터를 검색합니다.
UserService.ktpackage com.example.demo.app.service
import com.example.demo.domain.repository.UserRepository
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*
@Service
@Transactional
class UserService{
@Autowired
lateinit var userRepository: UserRepository
fun existsById(id : Int) : Boolean {
return userRepository.existsById(id)
}
@Cacheable(cacheNames = ["User"], key = "'User:' + #id")//キャッシュの参照とミスヒット時の登録
fun findById(id : Int) : Optional<User> {
return userRepository.findById(id)
}
}
@Cacheable
어노테이션이 추가 된 함수는 return하기 전에 캐시를 참조합니다. 지정된 키(ex; User::User:1)의 캐쉬가 존재하면 캐쉬로부터 값을 취득해, return 합니다. 캐시가 없으면 return할 값을 지정된 키에 캐시합니다.
이 예제에서는 설명하지 않지만 @CachePut
어노테이션이 추가된 함수는 return 시 return할 값으로 캐시를 업데이트합니다. 예를 들어 DB의 컬럼을 편집할 때 동시에 캐시를 갱신하거나 하는 용도에 사용합니다.
또한 @cacheEvict
는 return시 지정된 키의 캐시를 삭제합니다. DB의 열을 삭제하고 동시에 캐시도 삭제하고 싶을 때 등에 사용합니다.
이 예제에서는 id를 지정하고 해당 열을 검색할 때 캐시를 참조하고 등록하는 함수를 설명합니다.
컨트롤러 작성
UserController.ktpackage com.example.demo.app.controller
import com.example.demo.app.service.UserService
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.ResponseBody
import java.util.*
import kotlin.system.measureTimeMillis
@Controller
class UserController{
@Autowired
lateinit var userService : UserService
@GetMapping("/users/{id}")
@ResponseBody
fun getUser(@PathVariable id: Int) : String {
lateinit var user: Optional<User>
if (userService.existsById(id)) {
val time = measureTimeMillis {
user = userService.findById(id)
}
var name = user.get().name
var age = user.get().age
return "name=$name, age=$age, time=$time(ms)"
}
return "does not exist id=$id"
}
}
/users/{id}
에 요청하면 id가 있으면 DB 또는 캐시에서 데이터를 검색합니다. 그 때에 걸린 시간(time)을 계측해 둡니다. 응답으로서 User의 name, age와 계측한 시간 time를 포함한 캐릭터 라인을 돌려줍니다. id가 존재하지 않으면 존재하지 않는다는 것을 알려주는 문자열을 반환합니다.
Redis config 클래스 만들기
RedicConfig.ktpackage com.example.demo.app.config
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.lettuce.LettuceConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
import org.springframework.data.redis.serializer.StringRedisSerializer
@Configuration
@EnableCaching
class RedisConfig{
@Bean
fun redisConnectionFactory(): LettuceConnectionFactory {
return LettuceConnectionFactory()
}
@Bean
fun redisTemplateSet() : RedisTemplate<String, Object> {
var redisTemplate = RedisTemplate<String, Object>()
redisTemplate.setConnectionFactory(redisConnectionFactory())
redisTemplate.keySerializer = StringRedisSerializer()
redisTemplate.valueSerializer = JdkSerializationRedisSerializer()
redisTemplate.afterPropertiesSet()
return redisTemplate
}
@Bean
fun redisCacheManager(lettuceConnectionFactory : LettuceConnectionFactory) : RedisCacheManager {
var redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
.cacheDefaults(redisCacheConfiguration).build();
}
}
이 예에서 key : "User::User:1"
의 경우 value는 id : 1의 user 데이터 클래스 (id, name, age)를 캐시합니다. 즉 Object를 저장합니다.
데이터베이스 작성 및 테이블 초기화
init.sqlcreate database if not exists demo;
grant all on demo.* to 'demouser'@'%';
create table if not exists demo.user(
id INT(11) AUTO_INCREMENT not null primary key,
name varchar(30) not null,
age INT(3) not null
);
insert into demo.user(name, age)values('A-san', 20);
mysql -u root -p < init.sql
실행해보기
응용 프로그램을 시작합니다.
./gradlew bootRun
다른 터미널에서 요청을 보냅니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=268(ms)
첫 번째는 캐시되지 않고 DB에서 직접 데이터를 검색하므로 268ms로 약간의 시간이 걸립니다.
그대로 다시 동일한 명령을 입력합니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=9(ms)
두 번째는 캐시가 효과적이기 때문에 상당히 빠르게 데이터를 얻을 수 있습니다.
마지막으로
Kotlin + Spring Boot2에서 redis를 사용하여 DB 캐시했습니다.
이 조합으로 redis를 사용하여 DB 캐시를하려고, 특히 RedisConfig.kt에 기술한 내용으로 빠져 버렸으므로, 참고가 되면 다행입니다. 나도 아직 RedisConfig.kt의 내용을 잘 이해하지 못했기 때문에 이것에 대해 뭔가 교수해 주시면 감사하겠습니다.
여기까지 읽어 주셔서 감사합니다!
Reference
이 문제에 관하여(Kotlin + Spring Boot에서 DB 캐시를 Redis로 시도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/syumiwohossu/items/3139e14ca995027c8fdf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
package com.example.demo.domain.entity
import java.io.Serializable
import java.util.*
import javax.persistence.*
@Entity
data class User (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id : Int = 0,
var name : String,
var age : Int
) : Serializable
package com.example.demo.domain.repository
import com.example.demo.domain.entity.User
import org.springframework.data.jpa.repository.JpaRepository
interface UserRepository : JpaRepository<User, Int> {
}
DB와 상호 작용하는 클래스를 정의합니다.
동시에 캐시를 보고 히트하면 캐시에서 데이터를 검색합니다.
UserService.kt
package com.example.demo.app.service
import com.example.demo.domain.repository.UserRepository
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*
@Service
@Transactional
class UserService{
@Autowired
lateinit var userRepository: UserRepository
fun existsById(id : Int) : Boolean {
return userRepository.existsById(id)
}
@Cacheable(cacheNames = ["User"], key = "'User:' + #id")//キャッシュの参照とミスヒット時の登録
fun findById(id : Int) : Optional<User> {
return userRepository.findById(id)
}
}
@Cacheable
어노테이션이 추가 된 함수는 return하기 전에 캐시를 참조합니다. 지정된 키(ex; User::User:1)의 캐쉬가 존재하면 캐쉬로부터 값을 취득해, return 합니다. 캐시가 없으면 return할 값을 지정된 키에 캐시합니다.이 예제에서는 설명하지 않지만
@CachePut
어노테이션이 추가된 함수는 return 시 return할 값으로 캐시를 업데이트합니다. 예를 들어 DB의 컬럼을 편집할 때 동시에 캐시를 갱신하거나 하는 용도에 사용합니다.또한
@cacheEvict
는 return시 지정된 키의 캐시를 삭제합니다. DB의 열을 삭제하고 동시에 캐시도 삭제하고 싶을 때 등에 사용합니다.이 예제에서는 id를 지정하고 해당 열을 검색할 때 캐시를 참조하고 등록하는 함수를 설명합니다.
컨트롤러 작성
UserController.ktpackage com.example.demo.app.controller
import com.example.demo.app.service.UserService
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.ResponseBody
import java.util.*
import kotlin.system.measureTimeMillis
@Controller
class UserController{
@Autowired
lateinit var userService : UserService
@GetMapping("/users/{id}")
@ResponseBody
fun getUser(@PathVariable id: Int) : String {
lateinit var user: Optional<User>
if (userService.existsById(id)) {
val time = measureTimeMillis {
user = userService.findById(id)
}
var name = user.get().name
var age = user.get().age
return "name=$name, age=$age, time=$time(ms)"
}
return "does not exist id=$id"
}
}
/users/{id}
에 요청하면 id가 있으면 DB 또는 캐시에서 데이터를 검색합니다. 그 때에 걸린 시간(time)을 계측해 둡니다. 응답으로서 User의 name, age와 계측한 시간 time를 포함한 캐릭터 라인을 돌려줍니다. id가 존재하지 않으면 존재하지 않는다는 것을 알려주는 문자열을 반환합니다.
Redis config 클래스 만들기
RedicConfig.ktpackage com.example.demo.app.config
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.lettuce.LettuceConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
import org.springframework.data.redis.serializer.StringRedisSerializer
@Configuration
@EnableCaching
class RedisConfig{
@Bean
fun redisConnectionFactory(): LettuceConnectionFactory {
return LettuceConnectionFactory()
}
@Bean
fun redisTemplateSet() : RedisTemplate<String, Object> {
var redisTemplate = RedisTemplate<String, Object>()
redisTemplate.setConnectionFactory(redisConnectionFactory())
redisTemplate.keySerializer = StringRedisSerializer()
redisTemplate.valueSerializer = JdkSerializationRedisSerializer()
redisTemplate.afterPropertiesSet()
return redisTemplate
}
@Bean
fun redisCacheManager(lettuceConnectionFactory : LettuceConnectionFactory) : RedisCacheManager {
var redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
.cacheDefaults(redisCacheConfiguration).build();
}
}
이 예에서 key : "User::User:1"
의 경우 value는 id : 1의 user 데이터 클래스 (id, name, age)를 캐시합니다. 즉 Object를 저장합니다.
데이터베이스 작성 및 테이블 초기화
init.sqlcreate database if not exists demo;
grant all on demo.* to 'demouser'@'%';
create table if not exists demo.user(
id INT(11) AUTO_INCREMENT not null primary key,
name varchar(30) not null,
age INT(3) not null
);
insert into demo.user(name, age)values('A-san', 20);
mysql -u root -p < init.sql
실행해보기
응용 프로그램을 시작합니다.
./gradlew bootRun
다른 터미널에서 요청을 보냅니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=268(ms)
첫 번째는 캐시되지 않고 DB에서 직접 데이터를 검색하므로 268ms로 약간의 시간이 걸립니다.
그대로 다시 동일한 명령을 입력합니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=9(ms)
두 번째는 캐시가 효과적이기 때문에 상당히 빠르게 데이터를 얻을 수 있습니다.
마지막으로
Kotlin + Spring Boot2에서 redis를 사용하여 DB 캐시했습니다.
이 조합으로 redis를 사용하여 DB 캐시를하려고, 특히 RedisConfig.kt에 기술한 내용으로 빠져 버렸으므로, 참고가 되면 다행입니다. 나도 아직 RedisConfig.kt의 내용을 잘 이해하지 못했기 때문에 이것에 대해 뭔가 교수해 주시면 감사하겠습니다.
여기까지 읽어 주셔서 감사합니다!
Reference
이 문제에 관하여(Kotlin + Spring Boot에서 DB 캐시를 Redis로 시도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/syumiwohossu/items/3139e14ca995027c8fdf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
package com.example.demo.app.controller
import com.example.demo.app.service.UserService
import com.example.demo.domain.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.ResponseBody
import java.util.*
import kotlin.system.measureTimeMillis
@Controller
class UserController{
@Autowired
lateinit var userService : UserService
@GetMapping("/users/{id}")
@ResponseBody
fun getUser(@PathVariable id: Int) : String {
lateinit var user: Optional<User>
if (userService.existsById(id)) {
val time = measureTimeMillis {
user = userService.findById(id)
}
var name = user.get().name
var age = user.get().age
return "name=$name, age=$age, time=$time(ms)"
}
return "does not exist id=$id"
}
}
RedicConfig.kt
package com.example.demo.app.config
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.lettuce.LettuceConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
import org.springframework.data.redis.serializer.StringRedisSerializer
@Configuration
@EnableCaching
class RedisConfig{
@Bean
fun redisConnectionFactory(): LettuceConnectionFactory {
return LettuceConnectionFactory()
}
@Bean
fun redisTemplateSet() : RedisTemplate<String, Object> {
var redisTemplate = RedisTemplate<String, Object>()
redisTemplate.setConnectionFactory(redisConnectionFactory())
redisTemplate.keySerializer = StringRedisSerializer()
redisTemplate.valueSerializer = JdkSerializationRedisSerializer()
redisTemplate.afterPropertiesSet()
return redisTemplate
}
@Bean
fun redisCacheManager(lettuceConnectionFactory : LettuceConnectionFactory) : RedisCacheManager {
var redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
.cacheDefaults(redisCacheConfiguration).build();
}
}
이 예에서 key :
"User::User:1"
의 경우 value는 id : 1의 user 데이터 클래스 (id, name, age)를 캐시합니다. 즉 Object를 저장합니다.데이터베이스 작성 및 테이블 초기화
init.sqlcreate database if not exists demo;
grant all on demo.* to 'demouser'@'%';
create table if not exists demo.user(
id INT(11) AUTO_INCREMENT not null primary key,
name varchar(30) not null,
age INT(3) not null
);
insert into demo.user(name, age)values('A-san', 20);
mysql -u root -p < init.sql
실행해보기
응용 프로그램을 시작합니다.
./gradlew bootRun
다른 터미널에서 요청을 보냅니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=268(ms)
첫 번째는 캐시되지 않고 DB에서 직접 데이터를 검색하므로 268ms로 약간의 시간이 걸립니다.
그대로 다시 동일한 명령을 입력합니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=9(ms)
두 번째는 캐시가 효과적이기 때문에 상당히 빠르게 데이터를 얻을 수 있습니다.
마지막으로
Kotlin + Spring Boot2에서 redis를 사용하여 DB 캐시했습니다.
이 조합으로 redis를 사용하여 DB 캐시를하려고, 특히 RedisConfig.kt에 기술한 내용으로 빠져 버렸으므로, 참고가 되면 다행입니다. 나도 아직 RedisConfig.kt의 내용을 잘 이해하지 못했기 때문에 이것에 대해 뭔가 교수해 주시면 감사하겠습니다.
여기까지 읽어 주셔서 감사합니다!
Reference
이 문제에 관하여(Kotlin + Spring Boot에서 DB 캐시를 Redis로 시도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/syumiwohossu/items/3139e14ca995027c8fdf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
create database if not exists demo;
grant all on demo.* to 'demouser'@'%';
create table if not exists demo.user(
id INT(11) AUTO_INCREMENT not null primary key,
name varchar(30) not null,
age INT(3) not null
);
insert into demo.user(name, age)values('A-san', 20);
mysql -u root -p < init.sql
응용 프로그램을 시작합니다.
./gradlew bootRun
다른 터미널에서 요청을 보냅니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=268(ms)
첫 번째는 캐시되지 않고 DB에서 직접 데이터를 검색하므로 268ms로 약간의 시간이 걸립니다.
그대로 다시 동일한 명령을 입력합니다.
curl localhost:8080/users/1
#> name=A-san, age=20, time=9(ms)
두 번째는 캐시가 효과적이기 때문에 상당히 빠르게 데이터를 얻을 수 있습니다.
마지막으로
Kotlin + Spring Boot2에서 redis를 사용하여 DB 캐시했습니다.
이 조합으로 redis를 사용하여 DB 캐시를하려고, 특히 RedisConfig.kt에 기술한 내용으로 빠져 버렸으므로, 참고가 되면 다행입니다. 나도 아직 RedisConfig.kt의 내용을 잘 이해하지 못했기 때문에 이것에 대해 뭔가 교수해 주시면 감사하겠습니다.
여기까지 읽어 주셔서 감사합니다!
Reference
이 문제에 관하여(Kotlin + Spring Boot에서 DB 캐시를 Redis로 시도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/syumiwohossu/items/3139e14ca995027c8fdf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Kotlin + Spring Boot에서 DB 캐시를 Redis로 시도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/syumiwohossu/items/3139e14ca995027c8fdf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)