소규모의 경우에는 이렇게 하지 않아도 될 수 있으나, 데이터가 많고 읽는 경우가 많을때 이 방식을 많이 쓴다.
메인DB로 Postgresql 을 사용하는 이유는 성능도 좋지만 무료이고, 검증되었기 때문이라고 본다.
SpringBoot 설정에서 캐시 설정을 Redis로 해 놓으면 캐시에서 조회하는것도, 캐시를 갱신하는것도 다 자동으로 해 준다.
1. Gradle 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.postgresql:postgresql'
2. yaml 설정
- db 접속 정보는 대부분 env 파일로 따로 빼 낸 다음 불러오거나 AWS를 이용하므로 참고. (https://dean83.tistory.com/322 여기 하단부 참고)
spring:
application:
name: 이름
datasource:
url: jdbc:postgresql://localhost:5432/테이블명
username: 유저명
password: 비밀번호
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: none # 운영 환경에서는 validate 또는 none 권장
show-sql: true # 실행되는 SQL 출력. product 에서는 false
properties:
hibernate:
format_sql: true # SQL 보기 좋게 정렬
highlight_sql: true # (Hibernate 5.5+) ANSI 색상 강조
use_sql_comments: true # JPQL -> SQL 변환 시 주석 추가
# 사용할 데이터베이스 방언(Dialect) 지정
dialect: org.hibernate.dialect.PostgreSQLDialect
database-platform: org.hibernate.dialect.PostgreSQLDialect
open-in-view: false # OSIV 비활성화 (서비스 계층에서만 영속성 사용)
sql:
init:
mode: never # schema.sql, data.sql 실행 여부 (never, embedded, always)
# defer-datasource-initialization: true
# ↑ JPA가 스키마 생성 후 data.sql 실행하도록 보장 (Spring Boot 2.5+)
logging:
level:
root: DEBUG
org.hibernate.SQL: DEBUG # 실행되는 SQL 로그
org.hibernate.type.descriptor.sql: TRACE # SQL에 바인딩되는 파라미터 값 출력
3. Redis Cache 커스텀 설정
- 굳이 커스텀 설정을 하지 않아도 가능한데, 캐시 시간 변경이나, json serialize를 할 경우 설정을 변경해야 한다.
@Configuration
@EnableCaching // 캐시 기능 활성화
public class RedisConfig {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(5)) // 캐시 TTL: 5분
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()
)
);
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.build();
}
}
4. 활용 예
//엔티티
@Entity
@Table(name = "users")
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
....
//리파지토리
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
...
//서비스
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
@Cacheable(value = "userCache", key = "#id")
public User getUser(Long id) {
// Redis에 캐시가 없을 때만 DB 조회
System.out.println("DB 조회 발생 for id=" + id);
return userRepository.findById(id).orElseThrow();
}
@CacheEvict(value = "userCache", key = "#user.id")
public User updateUser(User user) {
// DB 갱신 + 캐시 무효화
return userRepository.save(user);
}
}
...
//컨트롤러
@RestController
@RequiredArgsConstructor
@RequestMapping("/users")
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUser(id);
}
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
return userService.updateUser(user);
}
}
- 개발자가 따로 뭘 하지 않아도 서비스의 메서드가 호출될 때 @Cachable 로 인해 자동으로 캐시에서 내용을 찾고, 없을경우만 쿼리 조회 한다.
- 캐시 갱신 등 관리도 자동으로 한다.
- 쓰기 작업을 할때 @CacheEvict (해당 캐시 키 삭제) 를 반드시 해야한다. 내용이 변경되었기 때문에 무효화를 해주어야 한다.
- 혹은 @CachePut (value = "userCache", key = "#user.id") 를 통해 갱신을 해 주어야 한다.
'Backend > SpringBoot' 카테고리의 다른 글
| @Controller exception 처리 (@ControllerAdvice, @RestControllerAdvice) (0) | 2025.09.15 |
|---|---|
| Controller 에서 각종 파라메터 받기 + Cookie (0) | 2025.09.12 |
| yaml 이나 env 에서 설정값 가져오기 (0) | 2025.09.03 |
| 설정(Configuration) 오버라이딩 하기 (0) | 2025.09.02 |
| 커스텀 Event 발생 -> 수신 (0) | 2025.09.02 |