docker pull redis
docker run -d -p 6379:6379 --name docker_redis redis
docker ps
docker exec -it docker_redis redis-cli
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
spring:
data:
redis:
host: localhost
port: 6379
public interface ShortUrlRedisRepository extends CrudRepository<ShortUrlResponseDto, String> {
}
@Component
public class RedisTemplateTest {
private final RedisTemplate<String,String> redisTemplate;
@Autowired
public RedisTemplateTest(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void test() {
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
valueOperations.set("Redis에 저장할 키","키값에 저장시킬 값");
}
}
@Configuration
public class RedisCacheConfig implements CacheConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
@Bean
public RedisTemplate<?,?> redisTemplate() {
RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
@RestController
@RequestMapping("/short-url")
public class ShortUrlController {
private final ShortUrlService shortUrlService;
@Autowired
public ShortUrlController(ShortUrlService shortUrlService) {
this.shortUrlService = shortUrlService;
}
@PostMapping("/generate")
public ShortUrlResponseDto generateShortUrl(@RequestBody ShortUrlResponseDto shortUrlResponseDto) {
return shortUrlService.generateShortUrl(shortUrlResponseDto);
}
@GetMapping("/get")
public ShortUrlResponseDto getShortUrl(@RequestParam String originalUrl) {
return shortUrlService.getShortUrl(originalUrl);
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@RedisHash(value = "shortUrl", timeToLive = 60)
public class ShortUrlResponseDto implements Serializable {
private static final long serialVersionUID = -1L;
@Id
private String originalUrl;
private String shortUrl;
}
public interface ShortUrlService {
ShortUrlResponseDto generateShortUrl(ShortUrlResponseDto shortUrlResponseDto);
ShortUrlResponseDto getShortUrl(String originalUrl);
}
@Service
public class ShortUrlServiceImpl implements ShortUrlService {
private final ShortUrlRedisRepository shortUrlRedisRepository;
@Autowired
public ShortUrlServiceImpl(ShortUrlRedisRepository shortUrlRedisRepository) {
this.shortUrlRedisRepository = shortUrlRedisRepository;
}
@Override
public ShortUrlResponseDto generateShortUrl(ShortUrlResponseDto shortUrlResponseDto) {
shortUrlRedisRepository.save(shortUrlResponseDto);
return shortUrlResponseDto;
}
@Override
public ShortUrlResponseDto getShortUrl(String originalUrl) {
return shortUrlRedisRepository.findById(originalUrl)
.orElse(new ShortUrlResponseDto("캐시를 사용하지 않고 생성된 객체", "캐시를 사용하지 않고 생성된 객체"));
}
}
만약 RedisTemplate 사용한다면..
Interface:
public interface ShortUrlServiceByRedisTemplate { ShortUrlResponseDto generateShortUrl(ShortUrlResponseDto shortUrlResponseDto); ShortUrlResponseDto getShortUrl(String originalUrl); }
Implementation:
@Service public class ShortUrlServiceByRedisTemplateImpl implements ShortUrlServiceByRedisTemplate { private final RedisTemplate<String, ShortUrlResponseDto> redisTemplate; @Autowired public ShortUrlServiceByRedisTemplateImpl(RedisTemplate<String, ShortUrlResponseDto> redisTemplate) { this.redisTemplate = redisTemplate; } @Override public ShortUrlResponseDto generateShortUrl(ShortUrlResponseDto dto) { // ✅ Redis에 직접 데이터 저장 (Key: originalUrl, Value: ShortUrlResponseDto) redisTemplate.opsForValue().set(dto.getOriginalUrl(), dto); return dto; } @Override public ShortUrlResponseDto getShortUrl(String originalUrl) { // ✅ Redis에서 데이터 조회 ShortUrlResponseDto result = redisTemplate.opsForValue().get(originalUrl); 
if (result != null) {
System.out.println("✅ Redis에서 데이터 조회 성공: " + result.getShortUrl());
return result;
} else {
System.out.println("❌ Redis에 데이터가 없습니다. DB에서 조회하거나 캐싱 필요");
return new ShortUrlResponseDto("캐시를 사용하지 않고 생성된 객체", "캐시를 사용하지 않고 생성된 객체");
}
}
}
---
## ✅ 5. Swagger 추가 및 설정
### 5.1 build.gradle에 의존성 추가
```gradle
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
springdoc:
swagger-ui:
path: /swagger-ui.html
api-docs:
path: /v3/api-docs
명령어 | 설명 |
---|---|
SET key value | 문자열 데이터를 저장 |
GET key | 문자열 데이터를 조회 |
DEL key | 특정 키를 삭제 |
HSET key field value | 해시(Hash)에 필드와 값을 저장 |
HGET key field | 해시(Hash)의 특정 필드를 조회 |
HGETALL key | 해시(Hash)의 모든 필드와 값을 조회 |
LPUSH key value | 리스트(List)의 왼쪽에 값 추가 |
RPUSH key value | 리스트(List)의 오른쪽에 값 추가 |
LPOP key | 리스트(List)의 왼쪽에서 값 제거 및 반환 |
RPOP key | 리스트(List)의 오른쪽에서 값 제거 및 반환 |
SADD key value | 셋(Set)에 값 추가 (중복 불가) |
SMEMBERS key | 셋(Set)의 모든 요소 조회 |
ZADD key score member | Sorted Set에 점수와 요소 추가 |
ZRANGE key start stop | Sorted Set의 범위 조회 |
ZRANK key member | Sorted Set에서 특정 요소의 순위 조회 |
EXPIRE key seconds | 특정 키의 TTL 설정 |
KEYS * | 모든 키 조회 |
POST /short-url/generate
호출 시:HGETALL shortUrl:example.com
명령어로 확인 가능GET /short-url/get
호출 시:HGETALL
명령어의 결과는 짝수 개의 요소로 반환되며, 홀수 번째 요소는 필드 이름입니다._class
필드는 Spring Data Redis가 직렬화 시 자동으로 추가하는 클래스 정보입니다.