JPA

Jung·2021년 3월 11일
0

수업

목록 보기
5/20

3-2. 자바 객체와 테이블 매핑, 회원가입 기능 구현

https://youtu.be/69tNvDm-iiI
스프링부트에 JPA를 추가하면 db에 데이터를 추가하고 조회하는 것이 편해진다.

domain패키지를 만들어 데이터를 관리하도록하고 User, Question과 같이 데이터를 관리하는 클래스를 도메인 패키지 하위에 등록하는 것이 일반적이다.
사용자데이터를 관리하는 User클래스에 db와 매핑ㅇ을 하는 annotation을 추가할 것이다. User클래스가 db와 연결되는 놈이라는 것을 인식시키기 위해서 @Entity 애노테이션을 쓸 수 있다.
javax.persistence로 시작하는 애노테이션들을 추가하면 된다.
DB는 각각의 데이터를 고유하게 식별하기 위해 primary key란 것이 있다. 이것ㅇ르 지정하는 애노테이션이 @Id이다. 이 User 데이터베이스의 primary key는 @Id가 붙은 UserId가 된다. 만약 userId가 유일하지 않다면, 또는 숫자를 자동저장해서 primary key를 @Id로 쓴다.
하나의 데이터가 추가될때마다 자동으로 1씩 증가하도록 하는 방식은 @GeneratedValue를 붙이면 된다. 이 애노테이션ㅇ르 쓰면 DB에서 자동으로 1씩 증가시켜준다(마지막 저장 id불러와서 1증가 직접 안시켜줘도)
@Column(nullable = false)로 해주면 다음 값은 null값이 들어갈수없다는 것을 의미한다. column의 nullable 디폴트가 true라서 null 들어갈 수 있는데, false로바꿔줌으로써 null이 못 들어가게 된다. f3누르면 애노테이션의 디폴ㄹ트를 볼 수 있다.
각 필드마다 애노테이션 설정할수있는데 설정하지 않더라도 디폴트설정되어 테이블이 자동으로 만들어지게 되어있다.

DB 연결

DB에 데이터 삽입하려면 인터페이스를 추가해야한다. UserRepository 인터페이스와 같은 것을 추가한다. 또는 UserDAO를 쓴다.
public interface UserRepository extends JpaRepository<User, Long>
<>의 첫번째 값엔 어떤 클래스에 대한 repository냐 해서 User이 오고,
두번째 값엔 User의 primary key가 된다.
이렇게 하면 데이터 추가 꺼내오기가 가능하다.

이 UserRepository 인터페이스에 대해서 DB와 연결을 하고 싶으면 인터페이스 인스턴스를 생성하는 것이 아니라 어딘가 만들어져있다고 생각하고 얘(UserRepository)을 가져다 쓰면 된다.
@AutoWired
private UserRepositoy userRepository;

UserRepository는 스프링부트에서 알아서 생성을 해준다.
UserRepository의 API엔 save가 있다. 기존에 users.add(user)해주던 것을, UserRepository의 save 메서드를 통해 구현하면 된다. 이것이 가능한 이유는 JPARepository에 클래스드들이 save와 같은 메서드를 갖고 있다.(UserRepository의 부모)

model.addAttribute("users", users)를
model.addAttribute("users", userRepository.findAll())로 바꾸면 DB의 모든 데이터를 담아서 넣어주기때문에 users ArrayList가 필요없어진다. -> 지우기

우리가 DB를 쓴 이유가 DB가 서버 시작할떄마다 사라지기 때문이다. 그런데 h2 를 쓰면 디폴트설정이 메모리 db이기 때문에 서버 재시작때마다 초기화되도록 디폴트설정이 되어있다. 지금처럼 db에서 조회되어도 서버 재시작되면 데이터 날라가는 것을 확인할수있다.
h2를 다시 run하면 다 사라진다.
스프링부트가 jpa기본설정할 떄 db 테이블을 드랍하고, 그것을 다시 생성하는 방식으로 동작하기에 메모리에선 이렇게 동작한다. 오늘은 이렇게 데이터 날라가는거 확인하지만 추후에 데이터 안날라가게 설정하고 유지하는 방법 살펴보겠다.

3-4. 개인정보 수정 기능 구현 1

https://youtu.be/D3PjDIYZYW0

list.html에서 body에서 해당하는 부분을 빼서 중복제거했다.
templates 디렉토리로 이동한 것의 문제점은 브라우저에서 직접접근하루없다. 브라우저에선 static에서 찾게 되어있다. 이것을 해결하는 방법은 각 html과 매핑되는 컨트롤러를 구현하는 것이다. 기본적으로MVC패턴에선 모든 뷰를 접근할때 무조건 컨트롤러를 통해 접근을해야한다. 그래서 메인페이지에 해당하는 HomeController의 메소드에 아무런 매핑이 없기 때문에 8080으로 접근했을 때 index를 ㅇ리턴한다.
회원가입도 마찬가지로 /form을 겟매핑해서 /user/form에 접근할수있도록했다.

개인정보수정기능을 구현해보겠다. 시스템 관리자라고 생각하고 사용자목록에서 해당 사용자를 수정할수있도록 해보겠다. 수정버튼을 클릭했을 때 어떤 사용자인지 알아야하므로 ㅏ용자에 해당하는 id를 서버에 전달해서 사용자를 db에서 조회해서 수정가능한 화면으로 이동해야한다.

href="users/{{id}}/form"으로 이동하도록 지정한다.(가입은 "users/form"이다. 지정된 사용자가 없으니까.)
url에서 id를 받아오려면 파라미터변수에 @PathVariable Long id를 넢으면 된다. 받아오려는 변수와 같은 이름을 설정하면된다. DB에서 사용자 조회해 model에 저장해야한다. 찾는방법은
model.addAttribute("user", userRepository.findOne(id)); 와 같이 하면 id에 해당하는 사용자 정보를 조회한 후에 조회된 정보를 updateForm.html에 전달한다.

updateForm.html이 form.html과 다른 점은, 수정이기 때문에 벌써 값이 채워진상태여야 한다.
각 userId, password, name, email의 input에 에 value="{{userId}}"와 같이 value를 넣으면 된다. password를 제외하고 채워준다.
name, password, email등은 User안에 넣은 값이다. 이것을 조회하려면 User에서 꺼내와야한다. 그렇기 때문에 {{userId}} 같이만 쓰면 안되고, 바깥 쪽에 {{#user}} {{/user}}와 같이 감싸줘야한다.

css가 적용이 안되어 예쁘게 안보이고 포맷이 깨지는 문제:
html파일에서 css적용부분이(href ="./css"와 같이) 상대경로로 되어있다.
우리가 url에서 접근할때 /users와 같은 url은 문제가 없었는데, user/{}/form으로 오면서 depth가 달라졌다. (users에서 보여주는 html을 그대로 복붙해줬기때문에 상대경로가 서로 다름. ) 따라서 절대경로로 써주면 된다. ("/css")와 같이.

사용자 정보에 수정을 하면, 그에 해당하는 사용자정보를 서버로 전달해 수정하는 작ㅇㅂ을 해야한다.

3-5. 개인정보 수정 기능 구현 2

https://www.youtube.com/watch?v=V2AhIjdfcMg

form action = "/users/update"와 같아야한다.
해당 사용자를 알아야하기 때문에 id에 해당하는 사용자를db에서 조회해야한다. 보여주기 싫으면

'<form name="question" ~ action="/users/{{id}}/update">
와 같이 써주고 아래에
'와 같이 써주면 된다.

이렇게 id를 전달하고
'<form name="question" ~ action="/users/{{id}}"> 와 같이 id 를 넘기면 굳이 hidden으로 안써도 되니까 아래 '<input~~>어쩌고 지워주면된다.

id에 대해 포스트로 넘기면
@PostMapping("/{id}")
public String update(@PathVariable Long id){

}포스트 방식으로 요청왔고 해당 id에 대해 포스트 보내면 수정하는 것인데, 이때 위에 userRepository.findOne(id);로 사용자 조회한다. 수정한 정보들을 읽어와야하는데, 파라미터에 user로 매핑할수있다. 파라미터에 받는 User updateUser은 새롭게 수정된 데이터이고,
User user = userRepository.findOne(id);에서의 user은 원래 기존 데이터이다.
user.update(updateUser);와 같이 기존 user을 새로운 데이터로 update하도록 update메서드 만들면 됨. 그럼 User클래스 가서 update메서드 만들수있다.
update(User newUser)에서 this.email = newUser.email; 식으로 수정하면 된다.
update(~~); 후에 userRepository.save(user)하면 정상적으로 저장이 된다. save하면 userRepository에선, id값이 없으면 insert하고, id값이 있어서 기존 사용자면 update된다.


와 같이 get post만 쓰는 이유는 html이 이것을 지원하기 때문이고, 원래는 http메서드가 put, 등도 있다. 사용정보수정할때 put을 사용하는 것이 더 명확할 것이다. 그럼 html에서 put을 사용하기 위해서 쓰이는 대중적인 꼼수는? 표준화된 꼼수 ㅋㅋ method는 어차피 get post밖에 없기 때문에 post로 보내는 그대로 두고, 인자를 하나 더 추가한다 을 지정하면 된다. 얜 서버에서는 _method란 인자가 전달되면 value값을 통해서 어떤 method로 호출할 것인지 결정한다. 컨트롤러에서는 @PutMapping으로 매핑해주면 된다. html에선 실제로 post를 쓰는거고, 추가적 정보를 통해서 서버상에서는 put을 받을수있도록 하는 것이다. 삭제는 콘트롤러에선 deleteMapping해주고, html에선 value="delete"로 해주면 된다.

0개의 댓글