오늘 에 목표....
장바구니를 만들어야 한다.!!!
redis는 Key:Value 형태를 지닌 NoSQL이니
조금 더 똑똒한 json저장소라고 생각을 해보겠다..
생각중인 장바구니 형태
Key : cart:{userId} <- cart:4213
Value : {
"storeId": 88,
"items": [
{
"menuId": 1,
"optionIds": [10, 11], <보류
"quantity": 2
},
{
"menuId": 3,
"optionIds": [], <보ㅓ류라서뺌
"quantity": 1
}
]
}
보면 알겠지만 일단 제약조건
도커위에 레디스 올리기는 여차저차 완료했다
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void example() {
// String 자료구조
ValueOperations<String, Object> valueOps = redisTemplate.opsForValue();
valueOps.set("key", "value");
// List 자료구조
ListOperations<String, Object> listOps = redisTemplate.opsForList();
listOps.leftPush("myList", "item1");
listOps.leftPush("myList", "item2");
// Set 자료구조
SetOperations<String, Object> setOps = redisTemplate.opsForSet();
setOps.add("mySet", "item1", "item2");
}
처음에 이거보고 RedisTemplate<String, Cart> 하면되겠네!! 라는 생각ㅇ르 햇는데
https://jforj.tistory.com/424
여기보면 String을 다시 오브젝트로 변환해주고 (역직렬화)
오브젝트를 String으로 변환하는 (직렬화) 함수가 따로있길래
그냥 json 써서 String,String하기로했음.
cart = objectMapper.readValue(ops.get(key), Cart.class);
쓰면 String값 cart로 바꿔주는거아니냐 는 생각..
ValueOperations는 주로 Redis의 간단한 값(또는 문자열)과 관련된 작업을 처리하는 데 사용된다.
ValueOperations<K, V>는 Redis에서 "key" -> "value" 형태의 데이터를 다룰 때 사용하는 인터페이스임
📌 Redis 자료구조 중에서
“String”타입을 다루는 기능만 제공
opsForValue()로 얻을 수 있음.
내부적으로는 Redis의 SET, GET, INCR, APPEND 등의 명령어로 매핑됨.
ValueOperations를 사용하면 이러한 캐시 된 값을 신속하게 검색하고 업데이트할 수 있으므로 성능이 중요하고 데이터 읽기가 많은 애플리케이션에 적합하다.ValueOperations를 사용하여 세션 데이터를 Redis에 저장할 수 있다. 이를 통해 기존 세션관리(로컬 또는 관계형 데이터베이스)가 너무 느리거나 번거로울 수 있는 분산 환경에서 사용자 상태를 유지하는데 필수적인 빠른 세션 검색 및 업데이트가 가능하다.ValueOperations는 이러한 사용 사례에 필수적인 증가 및 감소와 같은 원자적 연산을 제공한다.ValueOperations는 메시지 또는 이벤트 데이터를 빠르게 저장하고 검색하는데 도움이 된다.ValueOperations를 사용하여 이러한 임시 데이터를 효율적으로 관리할 수 있다. Redis에 내장된 만료 기능을 사용하면 이러한 키에 TTL 설정이 간단해진다.간단한 예제
// ValueOperations 객체 얻기
ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
// 저장
valueOps.set("key", "value");
// 조회
String value = valueOps.get("key");
// 만료 시간 설정 (예: 1분)
valueOps.set("tempKey", "value", Duration.ofMinutes(1));

public void addCartItem(Long userId, Long storeId, MenuItem value) {
//기존 장바구니 확인
//가게 아이디 다르면 덮어쓰기
//아니면 뒤로 붙이기
// 붙이기전에 메뉴 중복아이디 있으면 quantity 값만 조절
// 없으면 menus 에 추가
// 다시 Redis에 저장
}
해야할 목록이다
갈길이 겁나머니 이모지같은거 다뺌
1. 기존 장바구니 확인
위에서 redisTemplate.opsForValue().get(key);을 쓰면 해당 키값에 맞는 밸류를 가져오는 것으로 확인
<String, String> 이니깐 String으로 받아주고
null이면 값없는거니깐 새로 장바구니만들고 아니면 장바구니 객체로 만들어서 반환하면 되겠지예
return objectMapper.readValue(json, Cart.class);
오브젝트 매퍼가 참 최고다
public Cart getCartData(Long userId) {
String key = "cart:" + userId;
String json = redisTemplate.opsForValue().get(key);
if (json == null) {
return null;
}
try {
return objectMapper.readValue(json, Cart.class);
} catch (JsonProcessingException e) {
throw new CartException(CartExceptionCode.CART_READ_FAILED);
}
}
이거 >기존 장바구니 확인 하는 함수< 임
그... 장바구니 그냥 읽기에서도 쓸거같아서 따로뺏음
3. 다시 redis에 저장
// 다시 Redis에 저장
String updatedJson;
try {
updatedJson = objectMapper.writeValueAsString(cart);
} catch (JsonProcessingException e) {
throw new CartException(CartExceptionCode.CART_SAVE_FAILED);
}
ops.set(key, updatedJson, Duration.ofHours(24));
redisTemplate.opsForValue().set(key, String.valueOf(value));
저장하려면 직렬화 해줘야하니깐 오브젝터 매퍼써서 cart를 String으로 바꿔줌
참고
많이 쓰는 오브젝트 매퍼 메서드
ㅊㅊ
https://devel-repository.tistory.com/84
https://velog.io/@kimsei1124/Spring-Data-Redis-%EB%A1%9C%EC%BB%AC%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0
https://jforj.tistory.com/424
위에서 뻘짓한거보다 엄청 좋은 방법을 알게됐다
팀원 분이 알려줫다..
이걸 JpaRepository 쓰는것처럼 extends 하면 JPA하는 것 처럼 기본 CRUD를 쉽게할 수 있다고함.............................
@Getter
@NoArgsConstructor
@RedisHash("cart")
public class Cart implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long userid;
private Long storeId;
// TODO 고쳐야 됨
private List<MenuItem> menus = new ArrayList<>();
public Cart(Long userid, Long storeId, MenuItem menuItem){
this.userid = userid;
this.storeId = storeId;
this.menus.add(menuItem);
}
}
@RedisHash("cart") 어노테이션 추가해줬음
userId 기준으로 장바구니가 딱 하나니깐 ....
implements Serializable 적어주면 쌩으로 오브젝트 매퍼써서 jsonString으로 바꿔주던거 아ㅓㄴ해ㅜ저도된다..
private static final long serialVersionUID = 1L;를 해주면
자바가 일관적으로 직렬화/역직렬화를 하는데에 도움이됨..(직렬화 안정성 챙기기용)
1L많이 한다고하니깐 써주기
public interface CartRedisRepository extends CrudRepository<Cart, Long> {
그리고 레퍼지토리 형태좀 바꿔주었다............................
그러면 JPA에서 사용하던 기본적인 함수 다 쓸수있음
정렬 조건 같은건 챙기기 어렵다고한다..
save는 꼬박꼬박써줘야함 끗
레디스 그냥 막 쓰고 있었는데 덕분에 많이 배워가요