
Redis์ ๊ธฐ๋ณธ ์๋ฃํ์ ์ตํ๋ค๋ฉด, ์ด์ ์ค์ ๋ฐฑ์๋ ์๋น์ค(Spring Boot)์ Redis๋ฅผ ์ฐ๋ํด ๋ณผ ์ฐจ๋ก์ ๋๋ค. Spring์์ Redis๋ฅผ ์ฌ์ฉํ๋ ๋ ๊ฐ์ง ์ฃผ์ ๋ฐฉ๋ฒ์ธ RedisRepository์ RedisTemplate์ ์์๋ณด๊ฒ ์ต๋๋ค.
Spring Initializr์์ ํ๋ก์ ํธ ์์ฑ ์ ๋ค์ ์์กด์ฑ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
Spring Data Redis, LombokJPA์ ๋งค์ฐ ์ ์ฌํ ๋ฐฉ์์ผ๋ก, Java ๊ฐ์ฒด๋ฅผ Redis์ Hash ์๋ฃํ์ผ๋ก ์์ฝ๊ฒ ๋งคํํ์ฌ CRUD๋ฅผ ์ํํ ์ ์์ต๋๋ค.
JPA์ @Entity ๋์ @RedisHash ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํฉ๋๋ค.
@Getter @Setter @Builder
@NoArgsConstructor @AllArgsConstructor
@RedisHash("item") // Redis์ Key prefix ์ค์
public class Item implements Serializable {
@Id
private Long id;
private String name;
private String description;
private Integer price;
}
public interface ItemRepository extends CrudRepository<Item, Long> {}
@Test
public void createTest() {
Item item = Item.builder()
.id(1L)
.name("keyboard")
.description("Mechanical Keyboard Expensive")
.build();
itemRepository.save(item);
}
๐ Redis ๋ด๋ถ์์๋ ์ด๋ป๊ฒ ์ ์ฅ๋ ๊น?
ํ
์คํธ ์ฑ๊ณต ํ Redis CLI์์ KEYS *๋ฅผ ์
๋ ฅํด ๋ณด๋ฉด ์ฌ๋ฏธ์๋ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
item (Set ์๋ฃํ): ํ์ฌ ์ ์ฅ๋ ์์ดํ
๋ค์ ID ๋ชฉ๋ก์ ๊ด๋ฆฌํ๋ ์ธ๋ฑ์ค ์ญํ ์ ํฉ๋๋ค.item:1 (Hash ์๋ฃํ): ์ค์ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๊ฐ ๋ด๊ธด ํค์
๋๋ค. HGETALL item:1 ๋ช
๋ น์ด๋ก ์กฐํํด ๋ณด๋ฉด ํ๋๋ณ๋ก ๊ฐ์ด ์์๊ฒ ๋ค์ด์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.@Test
public void readOneTest() {
Item item = itemRepository.findById(1L)
.orElseThrow();
System.out.println(item.getDescription());
}
@Test
public void updateTest() {
Item item = itemRepository.findById(1L)
.orElseThrow();
item.setDescription("On Sale!!!");
itemRepository.save(item);
item = itemRepository.findById(1L)
.orElseThrow();
System.out.println(item.getDescription());
}
@Test
public void deleteTest() {
itemRepository.deleteById(1L);
}
Key๋ฅผ ์ง์ ์ค์ ํ๊ฑฐ๋ Redis์ ๋ค์ํ ์๋ฃํ ๊ธฐ๋ฅ์ ์ธ๋ฐํ๊ฒ ์ ์ดํ๊ณ ์ถ๋ค๋ฉด RedisTemplate์ ์ฌ์ฉํฉ๋๋ค.
๋ฌธ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ Bean์
๋๋ค. ๊ฐ ์๋ฃํ์ ๋ง๋ Operations ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void stringValueOpsTest() {
// Redis String ์๋ฃํ ์ฌ์ฉ
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
ops.set("simplekey", "simplevalue");
System.out.println(ops.get("simplekey"));
}
@Test
public void stringSetOpsTest() {
// Redis Set ์๋ฃํ ์ฌ์ฉ
SetOperations<String, String> setOps = stringRedisTemplate.opsForSet();
setOps.add("hobbies", "games", "coding", "alcohol");
System.out.println(setOps.size("hobbies"));
}
โ๐ป ์ฃผ์ํ ์ !
StringRedisTemplate์ Redis์ String ๋ฐ์ดํฐ ํ์ ๋ง ๋ค๋ฃจ๋ ๋๊ตฌ๊ฐ ์๋๋๋ค. ์ ํํ๋ Redis์ ์ํตํ ๋ Java์ String ์๋ฃํ์ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋๋ค๋ ์๋ฏธ์ ๋๋ค. ์ฆ, Redis์ List๋ Set์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ ๋๋ Java์ ๋ฌธ์์ด(String)์ ์ ๋ฌํ๊ณ ์ถ๋ค๋ฉด ์ด ํ ํ๋ฆฟ์ ์ฌ์ฉํฉ๋๋ค.
EXPIRE, DEL ๊ฐ์ ๊ณตํต ๊ธฐ๋ฅ์ Template ์์ฒด ๋ฉ์๋๋ก ์คํํฉ๋๋ค.
stringRedisTemplate.expire("simplekey", 5, TimeUnit.SECONDS);
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, ItemDto> itemRedisTemplate(
RedisConnectionFactory connectionFactory
) {
// 1
RedisTemplate<String, ItemDto> template = new RedisTemplate<>();
// 2
template.setConnectionFactory(connectionFactory);
// ๋ฐ์ดํฐ ๊ฐ๋
์ฑ์ ์ํด Key๋ String, Value๋ JSON์ผ๋ก ์ง๋ ฌํ
// 3-a
template.setKeySerializer(RedisSerializer.string());
// 3-b
template.setValueSerializer(RedisSerializer.json());
// 4
return template;
}
}
String, ItemDto๋ก ์ค์ ํ๋๋ฐ Key๋ Java์ String, Value๋ ItemDto๋ฅผ ์ฌ์ฉํ์ฌ Redis์ ์ํตํ ๊ฒ์ด๋ค๋ผ๋ ์๋ฏธ์
๋๋ค.RedisConnectionFactory๋ฅผ template์ ์ ๋ฌํฉ๋๋ค. ์ด๋ RedisConnectionFactory์ ๊ฒฝ์ฐ application.yaml ํ์ผ์ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ๋ด๋ถ์ ์ผ๋ก ๋ง๋ค์ด Bean ๊ฐ์ฒด๋ก ๋ฑ๋ก๋ฉ๋๋ค.template์ ๋ฐํํ๋ฉด Bean ๊ฐ์ฒด๋ก ๋ฑ๋ก๋ฉ๋๋ค.@Test
public void itemRedisTemplateTest() {
ValueOperations<String, ItemDto> ops = itemRedisTemplate.opsForValue();
ops.set("my:keyboard", ItemDto.builder()
.name("Mechanical Keyboard")
.price(300000)
.build());
}
Repository: ๋จ์ CRUD ์์ ๋ฐ JPA ์คํ์ผ์ ์ต์ํ ๋ ์ ๋ฆฌํฉ๋๋ค.
Template: ์๋ฃํ์ ์์ธ ๊ธฐ๋ฅ์ ํ์ฉํ๊ฑฐ๋ ์ธ๋ฐํ Key ์ค๊ณ๊ฐ ํ์ํ ๋ ์ฌ์ฉํฉ๋๋ค.
์ํฉ์ ๋ง๋ ์ ์ ํ ๋ฐฉ์์ ์ ํํ์ฌ Redis์ ์ฑ๋ฅ์ ๊ทน๋ํํด ๋ณด์ธ์! ๐