블로그-V3. 조회수 카운팅
게시글 상세보기 할 때랑, 게시글 목록을 볼 때 둘 다 방문자수를 올려줘야 한다.
1. 상세보기 /user/1/post
1번 user의 visit update
2. 목록 /post/1
포스트 아이디 1로 findById 해서, 그 오브젝트에 있는 user의 id로 visit update
게시글 목록을 볼 때마다 visit을 업데이트 해야하는데 이게 맞나?
아직 save 된 게 없는데 업데이트한다는 게 이상하다.
회원 가입할 때 visit을 무조건 INSERT 시켜버리면 된다. 디폴트 데이터로!
회원가입 로직에 추가해주면 되겠다.
@Transactional
public void 회원가입(User user) {
// 1. save 한번
String rawPassword = user.getPassword(); // 1234
String encPassword = bCryptPasswordEncoder.encode(rawPassword); // 해쉬 알고리즘
user.setPassword(encPassword);
User userEntity = userRepository.save(user);
// 2. save 두번
Visit visit = new Visit();
visit.setTotalCount(0L); // longtime
visit.setUser(userEntity);
visitRepository.save(visit);
}
- System.out.println
화면(모니터)에 출력
- logger (log4j)
화면(모니터)에 출력
레벨별로 담길 수 있는 로그
1. info (정상)
2. debug : 개발환경에서만 로그가 뜨고 배포되고 나면 뜨지 않음
3. error
4. warning (경고) : 프로그램이 돌아가는데 문제는 없지만 나중에 문제가 생길 수 있으니 체크해봐
@Slf4j 어노테이션을 달아주면 레벨별 로그를 설정해줄 수 있다.
@Transactional
public PostRespDto 게시글목록보기(Integer pageOwnerId, Pageable pageable) {
Page<Post> postsEntity = postRepository.findByUserId(pageOwnerId, pageable);
List<Category> categorysEntity = categoryRepository.findByUserId(pageOwnerId);
List<Integer> pageNumbers = new ArrayList<>();
for (int i = 0; i < postsEntity.getTotalPages(); i++) {
pageNumbers.add(i);
}
PostRespDto postRespDto = new PostRespDto(
postsEntity,
categorysEntity,
pageOwnerId,
postsEntity.getNumber() - 1,
postsEntity.getNumber() + 1,
pageNumbers);
// 방문자 카운트 증가
Optional<User> pageOwnerOp = userRepository.findById(pageOwnerId);
if(pageOwnerOp.isPresent()) {
User pageOwnerEntity = pageOwnerOp.get();
Optional<Visit> visitOp = visitRepository.findById(pageOwnerEntity.getId());
if(visitOp.isPresent()) {
Visit visitEntity = visitOp.get();
visitEntity.setTotalCount(visitEntity.getTotalCount() + 1);
} else {
log.error("미친 심각", "회원가입할 때 Visit이 안만들어지는 심각한 오류가 있습니다.");
// sms 메시지 전송
// email 전송
// file 쓰기 : 파일에 로그 남기기
throw new CustomException("일시적 문제가 발생하였습니다. 관리자에게 문의해주세요.");
}
} else {
throw new CustomException("해당 블로그는 없는 페이지입니다.");
}
return postRespDto;
}
@Transactional // 더티체킹
public Post 게시글상세보기(Integer id) {
Optional<Post> postOp = postRepository.findById(id);
if (postOp.isPresent()) {
Post postEntity = postOp.get();
// 방문자 카운트 증가
Optional<Visit> visitOp = visitRepository.findById(postEntity.getUser().getId());
if(visitOp.isPresent()) {
Visit visitEntity = visitOp.get();
visitEntity.setTotalCount(visitEntity.getTotalCount() + 1);
} else {
log.error("미친 심각", "회원가입할 때 Visit이 안만들어지는 심각한 오류가 있습니다.");
// sms 메시지 전송
// email 전송
// file 쓰기 : 파일에 로그 남기기
throw new CustomException("일시적 문제가 발생하였습니다. 관리자에게 문의해주세요.")
}
return postEntity;
} else {
throw new CustomException("해당 게시글을 찾을 수 없습니다");
}
}
새로고침 하거나, 해당 페이지 접속할 때 (/user/1/post, /post/1)
방문자 수 증가를 한 번만 할 수 있도록 수정해야 한다.
request 객체 안에 ip 주소가 있는데 그걸 가지고 오늘 방문한 사람인지 아닌지 확인하려면 테이블이 하나 필요하다.
id lastConnectedDate userId(pageOwner) ipAddress
1 4월 28일 1 210.10.8.7
2 4월 28일 2 210.10.8.7
3 4월 29일 1 210.10.8.7
서버에 접속할 때가 기준이 아닌 해당 페이지 블로그 접속했을 때 확인하여
해당 ip에서 해당 유저 오너 페이지에 해당 날짜에 접속한 기록이 있는지 체크한다.
나만 들어가는 게 아니기 때문에 데이터가 엄청 많이 들어가겠다.
이때 필요한 게 DB 파티셔닝이다. 오늘만 체크할 거니까!!
수평적 분할 -> 전날 데이터를 잘라서 다른 테이블로 옮긴다.
그러면 SELECT 할 때 좋다.
SELECT는 기본적으로 풀스캔이니까!!
AND
게시글 삭제
[출처]
https://cafe.naver.com/metacoding
메타 코딩 유튜브
https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9