스프링부트 with JPA -insert, update, delete

최준호·2024년 2월 8일

JPA insert

회원가입

먼저 테스트용으로 컨트롤러 생성한다.

  • 유저라는 변수는 model의 user 클래스를 가져와 사용할 수 있습니다.

  • 포스트맨을 활용하여 form태그와 같은 환경으로 url접속하여 각 변수명에 값을 넣어준다

  • 테스트 성공!

JPA에 활용하여 데이터를 넣기위해서는 Repesitory 생성해야합니다.

package com.junho.blog.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.junho.blog.model.User;

//DAO
// 자동으로 bean 등록이 된다.
// @Repository 생략가능
// 기본적인 CRUD 가 가능하다.
public interface UserRepository extends JpaRepository<User,Integer> {

}
  • Repository를 생성하고, JPA레파지토리를 상속받으면됩니다.
    JpaRepository<테이블,프라이머리 키 타입> 으로 설정해주시면 됩니다.

이대로 실행하면 잘 됩니다.

  • 하지만 role 값이 들어가지가 않았죠?
    이거는

  • Insert 할때 null값으로 넣기때문입니다.
    db에서 디폴트 값이 있다고 한들 null을 넣어버리면 그 값이 들어갑니다 따라서 null을 넣는 과정을 빼야합니다.

  • 먼저 자바에서 Enum를 생성해서 타입명에 헷갈리지 않도록 해줍니다.

  • RoleType으로 설정해주고
  • Controller 도 수정시켜줍니다.

  • 출력되는걸 확인 할 수 있었습니다

다른 방법으로는 @DynamicInsert 어노테이션을 활용하여 null인 필드를 제외시키는 방법이 있습니다. 하지만 어노테이션을 늘리는 건 좋은 방법이 되지는 않습니다. 나중에 개별로 처리하기가 어려워지기 때문입니다.


id값으로 select

조건 select

// {id} 주소로 파마레터를 전달 받을 수 있음
	// http://localhost:8080/blog/dummy/user/3
	@GetMapping("/dummy/user/{id}")
	public User detail(@PathVariable int id ) { // 주소의 id값을 받아서 사용 할 수 있음
		// user/4을 찾으면 내가 데이터베이스에서 못찾아오게 되면 user가 null이 될 수 있음
		// 그럼 return null이 되니 프로그램 오류가 발생함.
		// Optional로 User 객체를 감싸서 가져오는 방식으로 null인지 아닌지 판단해서 return 하는 게 나을 것입니다.
		
		User user = userRepository.findById(id).orElseThrow(new Supplier<IllegalArgumentException>() {
			@Override
			public IllegalArgumentException get() {
				// TODO Auto-generated method stub
				return new IllegalArgumentException("해당 유저는 없습니다. id : "+id);
			}
		});
		
		return user;
	}
  • User라는 클래스에 값을 넣을 경우 null일 수도 있으니 null일 경우 IllegalArgumentException으로 날려버립니다.

내부 FindById 메소드에서도 null일경우 IllegalArgumentException 로 날려버리라는 참고 내용이 있습니다.

IllegalArgumentException 은 메세지를 생성해주는 메소드입니다.

  • 유저가 있을경우

  • 유저가 없을경우입니다.

여기서 웹브라우저는 json타입으로 받았는데, 그 이유가 뭘까요?

_요청 : 웹브라우저
user 객체가 자바 오브젝트 변환 (웹브라이저가 이해할 수 있는 데이터) -> json(Gson 라이브러리) 이 순서를 원래 걸처야합니다
하지만 스프링부트는 MessageConverter라는 애가 응답시에 자동 작동하여 만약에 자바 오브젝트를 리턴하게 되면 MessageConverter 가 Jackson 라이브러리를 호출해서 user 오브젝트를 json으로 변환해서 브라우저에게 던져줍니다.


회원수정

update

// email,password 수정
	@PutMapping("/dummy/user/{id}")
	public User updateUser(@PathVariable int id, @RequestBody User requestUser) { 
		// @RequestBody : body에 붙어온 json 데이터를 -> java Object 변환
		
		System.out.println("id : "+id);
		System.out.println("password : "+requestUser.getPassword());
		System.out.println("email : "+requestUser.getEmail());
		
		User user = userRepository.findById(id).orElseThrow(new Supplier<IllegalArgumentException>() {
			@Override
			public IllegalArgumentException get() {
				return new IllegalArgumentException("수정에 실패하였습니다.");
			}
		});
		user.setPassword(requestUser.getPassword());
		user.setEmail(requestUser.getEmail());
		
		userRepository.save(user);
		// save메소드에 user 값이 프라이머리 키인 id값이 있을경우 update 
		// save메소드에 user 값에 id가 없을경우 insert를 합니다
		return null;
	}
  • JPA update를 사용하기 위해선 save 메소드를 사용할 수 있습니다. save메소드는 파라미터 객체에 프라이머리 키가 존재한다면 update, 없다면 insert하는 특징이 있습니다.

@Transactional

@Transactional

  • @Transactional 를 사용하면 자동으로 save함수가 사용한 걸로 볼 수 있습니다.

  • @Transactional는 변경을 감지합니다. 위 그림에서 영속성 컨텍스트에 영속화된 user라는 객체의 값이 달라진걸 확인하고 update문을 실행하는 것입니다.
  • 이를 더티 체킹이라고합니다.

delete

delete

//localhost:8080/blog/dummy/user/{id}
	// user 삭제
	@DeleteMapping("/dummy/user/{id}")
	public String deleteUser(@PathVariable int id) {
		try {
			userRepository.deleteById(id);
		}catch(Exception e){
			return "삭제에 실패하였습니다. 해당 id는 DB에 없습니다.";
		}
		
		return "삭제되었습니다. "+ id;
	}
  • delete 는 id값을 기준으로 삭제를 할 수 있습니다. 혹시 모를 예외상황을 위해 예외처리를 해주 것이 좋습니다
profile
변화를 두려워하는 사람이 가장 불행한 사람이다.

0개의 댓글