일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 유니티기초
- 타입스크립트 기본문법
- 스프링게시판프로젝트
- spring jpa 사이드프로젝트
- jpa 게시판
- python 괄호 회전하기
- typescript 기초문법
- 타입스크립트 기초문법
- 파이썬 기초
- 스프링부트 게시판만들기
- 스프링부트 미니프로젝트
- 스프링부트 회원가입
- springboot 미니프로젝트
- 유니티
- springboot 사이드프로젝트
- 스프링부트 update
- 유니티Material
- 스프링 게시판 만들기
- 타입스크립트 기초
- springboot 게시판만들기
- springboot 게시판 프로젝트
- 프로그래머스 괄호 회전하기 python
- 괄호 회전하기 파이썬
- 스프링부트 블로그
- springboot 게시판
- JS기초
- 스프링부트 블로그만들기
- spring jpa 게시판
- 파이썬 괄호 회전하기
- 유니티Cube
- Today
- Total
Digking's cave
My First Blog Project (8) : Update / Delete / 더티체킹 / @Transactional 본문
My First Blog Project (8) : Update / Delete / 더티체킹 / @Transactional
디깅 2022. 12. 16. 17:42DummyControllerTest.java
package com.cos.blog.test;
import com.cos.blog.model.RoleType;
import com.cos.blog.model.User;
import com.cos.blog.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;
import javax.transaction.Transactional;
import java.util.List;
import java.util.function.Supplier;
@RestController
public class DummyControllerTest {
@Autowired
private UserRepository userRepository;
// 회원 가입
@PostMapping("/dummy/join")
public String join(User user){
user.setRoles(RoleType.USER);
userRepository.save(user);
return "회원가입 완료";
}
// 회원 모두 조회
@GetMapping("/dummy/users")
public List<User> list(){
return userRepository.findAll();
}
@GetMapping("/dummy/user/{id}")
public User detail(@PathVariable int id){
//IllegalArgumentException 을 return
User user = userRepository.findById(id).orElseThrow(new Supplier<IllegalArgumentException>() {
@Override
public IllegalArgumentException get() {
return new IllegalArgumentException("id "+id+" : 해당 유저는 없습니다.");
}
});
return user;
}
// 한 페이지 당 2건의 데이터를 리턴 (페이징)
@GetMapping("/dummy/user")
public List<User> pageList(@PageableDefault(size = 2,sort = "id",direction = Sort.Direction.DESC)Pageable pageable){
Page<User> pagingUser =userRepository.findAll(pageable);
List<User> users =pagingUser.getContent();
return users;
}
@Transactional //함수 종료시 자동 commit
@PutMapping("/dummy/user/{id}")
public User updateUser(@PathVariable int id,@RequestBody User requestUser){
User user = userRepository.findById(id).orElseThrow(()-> {
return new IllegalArgumentException("수정에 실패하였습니다..");
});
user.setPassword(requestUser.getPassword());
user.setEmail(requestUser.getEmail());
return user;
}
@DeleteMapping("/dummy/user/{id}")
public String delete(@PathVariable int id){
try{
userRepository.deleteById(id);
} catch (EmptyResultDataAccessException e){
return "없는 id라서 삭제 실패";
}
return "id : "+id + " 삭제 되었습니다.";
}
}
@Transactional //함수 종료시 자동 commit
@PutMapping("/dummy/user/{id}")
public User updateUser(@PathVariable int id,@RequestBody User requestUser){
User user = userRepository.findById(id).orElseThrow(()-> {
return new IllegalArgumentException("수정에 실패하였습니다..");
});
user.setPassword(requestUser.getPassword());
user.setEmail(requestUser.getEmail());
// userRepository.save(requestUser);
return user;
}
@RequestBody User requestUser
- json 데이터를 요청했는데 Java Object 로 변환
- MessageConvert의 Jackson 라이브러리가 변환해서 받아줘요
# save 사용 하는 경우
@PutMapping("/dummy/user/{id}")
public User updateUser(@PathVariable int id,@RequestBody User requestUser){
User user = userRepository.findById(id).orElseThrow(()-> {
return new IllegalArgumentException("수정에 실패하였습니다..");
});
user.setPassword(requestUser.getPassword());
user.setEmail(requestUser.getEmail());
userRepository.save(user);
return user;
}
save로 하면 null값이 생긴다. --> save는 insert 할 때만 주로 사용한다.
+ save로 하려면 아래처럼 user를 찾아준 후, set으로 변경값을 변경후에 다시 save 한다.
save는 id를 전달하지 않으면 insert
save는 id를 전달하면 해당id에 대한 데이터가 있으면 update
save는 id를 전달하면 해당id에 대한 데이터가 없으면 insert
#
@Transactional
더티 체킹
save하지 않아도, 변화된 값만 update 쓴다.
@Transactional //함수 종료시 자동 commit
@PutMapping("/dummy/user/{id}")
public User updateUser(@PathVariable int id,@RequestBody User requestUser){
User user = userRepository.findById(id).orElseThrow(()-> {
return new IllegalArgumentException("수정에 실패하였습니다..");
});
user.setPassword(requestUser.getPassword());
user.setEmail(requestUser.getEmail());
return user;
}
영속성컨텍스트
1.
JPA 에 영속성컨텍스트 가 있다.
Controller에서 user객체 만들어서 save하면 영속성컨텍스트 안에 1차캐시 안에 쌓인다.
쌓인 user객체를 실제 table에 넣는다. (실제 table에 data를 밀어넣는걸 flush라고한다.)
단! flush 해도 1차캐시가 비워지지 않는다.
그래서 이후에 controller가 해당 data를 가져올 때, 영속화 된 1차캐시에서 data를 가져온다.
2.
2번 data의 password/email을 update를 하려고 한다.
table에서 2번 data를 가져와서 1차캐시에 영속화를 하고, controller로 가져온다.
영속화 된 data에 값을 변경한다.
변경 후 save 하면 영속화 된 1차캐시에 값이랑 비교한다.
비교했더니 같은 값이니까 영속화 된 1차캐시에 값을 update한다.
1차캐시를 flush해서 table을 update한다.
3.
@Transactional 이 있으면 transaction이 update 함수 시작과 종료에 따라 시작/종료 된다.
종료되면 자동으로 commit 된다.
find해서 user에 담을 때 영속화 된다.
이후 set으로 값을 변경하면 변경 인식하고 flush 된다.
더티체킹 = 변경감지하고 DB 에 flush 하는 것
# Delete
@DeleteMapping("/dummy/user/{id}")
public String delete(@PathVariable int id){
try{
userRepository.deleteById(id);
} catch (EmptyResultDataAccessException e){
return "없는 id라서 삭제 실패";
}
return "id : "+id + " 삭제 되었습니다.";
}
출처 : 29강
https://www.youtube.com/watch?v=dDsI1J4QC6g&list=PL93mKxaRDidECgjOBjPgI3Dyo8ka6Ilqm&index=31
'Spring > My First Blog Project' 카테고리의 다른 글
My First Blog Project (10) : 블로그 메인 / 로그인 / 회원가입 화면 (0) | 2022.12.17 |
---|---|
My First Blog Project (9) : Exception 처리 (0) | 2022.12.16 |
My First Blog Project (7) : 전체 user Select / ID로 Select / 페이징 (1) | 2022.12.16 |
My First Blog Project (6) : 회원가입 구현 (Insert / ENUM 사용) (0) | 2022.12.16 |
My First Blog Project (5) : 테이블 만들기(User,Board,Reply) / JPA 설정 / JPA 연관관계매핑 /양방향매핑 (0) | 2022.12.16 |