본문 바로가기

프로젝트/개인

4. JSON 사용법+ 회원가입 위한 INSERT 테스트

JSON은 한마디로, 공용어(영어) 같은 존재.

다른 컴퓨터 언어끼리도 JSON 으로 데이터 통신 쉽게 할 수 있음.

또 HTML에 있는 데이터를 자바 오브젝트로 받을때도 중간 데이터는 JSON.

우리는 리퀘스트로 오는 데이터, 중간데이터를 이제 무조건 JSON 으로 받아서 자바 오브젝트로 바꿀거임. 즉 중간 데이터의 MIME TYPE이 전부 JSON인거. 

리스폰스할때도 자바오브젝트를 JSON 으로 변환해서 응답해줌.

1.연관관계 만들기

@ManyToOne

@OneToMany

@OneToOne

@ManyToMany

ManyToMany는 사용하지 않는다. 그 이유는 서로의 primary key로만 중간 테이블을 생성해주는데, 날짜나 시간 다른 필드들이 필요할 수 있기 때문에, 내가 중간 테이블을 직접만들고 @OneToMany, @OneToMany를 사용한다.

https://ict-nroo.tistory.com/127

 

[JPA] @ManyToMany, 다대다[N:M] 관계

다대다[N:M] 실무에선 사용하지 않는 것을 추천한다. 사용하면 안되는 이유를 학습하자. 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다. 연결 테이블(조인 테이블)�

ict-nroo.tistory.com

2. 더미 데이터 insert

 

package com.cos.blog.test;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DummyControllerTest {
//    http://localhost:8000/blog/dummy/join(요청)
//    http의 body에 username, password, email 데이터를 가지고 (요청)
    @PostMapping("/dummy/join")
//    public String join(@RequestParam("") String username, String password, String email){

    public String join(String username, String password, String email){//key=value(스프링 약속된 규칙)
        System.out.println("username = " + username + ", password = " + password + ", email = " + email);
        return "회원가입이 완료되었습니다.";
    }
}

x-www => 마임타입이 key& value로 되어있음

   public String join(User user){//key=value(스프링 약속된 규칙)보다 더 강력한, 오브젝트로 받아옴
        return "회원가입이 완료되었습니다.";
    }

 

 

JpaRepository<User, Integer>

JPA에서 제공하는 REPOSITORY, 이거 EXTEND하면 기본 CRUD 구현가능

기본으로 함수 제공함. 이거 EXTEND한 클래스가 DAO역할한다고 보면 됨

@RestController
public class DummyControllerTest {

    @Autowired//의존성주입(DI)
    private UserRepository userRepository;

//    http://localhost:8000/blog/dummy/join(요청)
//    http의 body에 username, password, email 데이터를 가지고 (요청)
    @PostMapping("/dummy/join")
//    public String join(String username, String password, String email){//key=value(스프링 약속된 규칙)
    public String join(User user){//key=value(스프링 약속된 규칙)
//        System.out.println("username = " + username + ", password = " + password + ", email = " + email);
        System.out.println("id = " + user.getId());
        System.out.println("username = " + user.getUsername());
        System.out.println("password = " + user.getPassword());
        System.out.println("email = " + user.getEmail());
        System.out.println("role = " + user.getRole());
        System.out.println("createDate = " + user.getCreateDate());

        userRepository.save(user);
        return "회원가입이 완료되었습니다.";
    }
}

이렇게 실행하면, enum 타입은 role은 null로 들어옴. 

그래서 그 다음인 createDate도 null로. 

이럴때, save 함수를 쓰면서 role을 빼고 나머지만 넣고싶다면?

@DynamicInsert: insert할때 null 인 필드 제외

user entity에 어노테이션달아줌
그럼 쿼리가 이렇게 role을 제외하고 실행되고

 

데이터가 잘 들어간다

근데 이런식으로 하나씩 넣다보면 끝도 없음.. 좋은 방법이 아님!

다시 @dynamic을 주석처리하고

user객체의 role 디폴트값을 주석처리해줌

 

model 패키지에 enum하나 만들어줌
잘들어감!

enum은 데이터의 도메인(범위)를 만들때 사용. 

4. 더미 데이터 select 및 응답

ddl-auto update => create로 바꿔서 데이터 리셋

db 데이터 한번 지우고 , 

postman으로 세개의 데이터 넣어줌

 

User user = userRepository.findById(id).orElseThrow(new Supplier<IllegalArgumentException>() {
			@Override
			public IllegalArgumentException get() {
				return new IllegalArgumentException("해당 사용자가 없습니다.");
			}
		});

id로 찾을때 없는 id를 입력했을 경우를 처리하기 위한 메소드, 오버라이딩 하는 이유는  orElseThrow의 매개변수 타입이 Supplier(이거 인터페이스, 제네릭 타입은 T)이기 때문에 new 해주려면 오버라이딩해서 익명함수를 만들어줘야함

재실행전 ddl auto update로 바꿔주기!!!!

get은 postman으로 테스트 안해도됨.

존재하는 아이디는 잘 나옴

aop를이용, 저 exception을 가로채서 사용자에겐 다른 페이지 보여주는게 최종형태!

근데 이렇게 exception을 넣기 위해서 매개변수타입확인, 제네릭타입확인, 오버라이딩  => 너무 귀찮음!!

람다식으로 깔끔하게 처리할 수도 있음. 이러면 리턴타입이 뭔지 몰라도됨!

//        람다식
        User user= userRepository.findById(id).orElseThrow(()->{
            return new IllegalArgumentException("해당 사용자는 없습니다.");
        });
        return user;

하지만 일단 이번 프로젝트에는 위의 방식을 사용

그리고 여기서, 우리가 return으로 객체타입 data(return user)를 던져줬는데, 웹브라우저가 어떻게 이해했을까?

그 답은 바로 아래~~~~~

// 리턴타입 user(자바 오브젝트), restController니까 data 리턴하는디, 웹브라우저가 user 당연히 이해 못함!
// 변환(웹브라우저가 이해할 수 있는 데이터)-> json(스프링에서 Gson 라이브러리 사용해서 변환했었음)
// 그러나 스프링부트에서는 MessageConverter가 응답시에 자동 작동! 알아서 json을 리턴해줌
// 만약에 자바 오브젝트를 리턴하게 되면 MessageConverter jackson 라이브러리르 호출해서 user오브젝트를 json으로 변환해서 브라우저에 던져줌

 


이제 한건의 데이터가 아니라 여러건의 데이터를 리턴받아보자.

 

나오긴하는데 보기 안좋음.

크롬 확장프로그램에서 jsonview를 깔아줌

이뿌덩!!!!!!!!!!!11

 

 	@GetMapping("/dummy/users")
    public List<User> list(){
        return userRepository.findAll();
    }

    @GetMapping("/dummy/user")
//    스프링 부트의 자동 페이징기능
//    2건씩 들고오고, id기준 최신순 정렬
    public List<User> pageList(@PageableDefault(size = 2, sort = "id",direction = Sort.Direction.DESC)Pageable pageable) {
//        나중에 여기서 로직 추가 가능
        Page<User> pagingUser = userRepository.findAll(pageable);

//        getContent : 페이징 완료한 컨텐츠만 보임
        List<User> users = pagingUser.getContent();
        return users;
    }

페이징한 주소를 user로 , list의 주소를 users로 고침

 

페이징 정보가 담긴 건 빼고 , content만 볼 수 있게 pageingUser.getContent

나중에 페이징에 로직 더 추가할 수 있으므로 pagingUsers 남겨줌

 

5. 더미 데이터 update

https://ict-nroo.tistory.com/130

 

[JPA] 영속성 컨텍스트와 플러시 이해하기

영속성 컨텍스트 JPA를 공부할 때 가장 중요한게 객체와 관계형 데이터베이스를 매핑하는 것(Object Relational Mapping) 과 영속성 컨텍스트를 이해하는 것 이다. 두가지 개념은 꼭 알고 JPA를 활용하자.

ict-nroo.tistory.com

 

update

1. save함수 이용

//    save함수는 id를 전달하지 않으면 insert를 해주고,
//    id를 전달하면 해당 id에 대한 데이터가 있으면 update를 해주고,
//    id를 전달하면 해당 id에 대한 데이터가 없으면 insert를 해준다.
//    email, password
      @PutMapping("/dummy/user/{id}")
  	  public User updateUser(@PathVariable int id, @RequestBody User requestUser){
        //RequestBody : json데이터를 요청 => java object(메시지컨버터의 jackson라이브러리가 변환해서 받아줌)
        System.out.println("id = " + id + ", password = " + requestUser.getPassword());
        System.out.println("email" + requestUser.getEmail());

        User user = userRepository.findById(id).orElseThrow(()->{
            return new IllegalArgumentException("수정에 실패하였습니다.");
        });
      

        user.setPassword(requestUser.getPassword());
        user.setEmail(requestUser.getEmail());

        userRepository.save(user);
        return null;
    }

2.@Transactional 이용(더티체킹)

    @Transactional
    @PutMapping("/dummy/user/{id}")
    public User updateUser(@PathVariable int id, @RequestBody User requestUser){
        //RequestBody : json데이터를 요청 => java object(메시지컨버터의 jackson라이브러리가 변환해서 받아줌)
        System.out.println("id = " + id + ", password = " + requestUser.getPassword());
        System.out.println("email" + requestUser.getEmail());

        User user = userRepository.findById(id).orElseThrow(()->{
            return new IllegalArgumentException("수정에 실패하였습니다.");
        });

        user.setPassword(requestUser.getPassword());
        user.setEmail(requestUser.getEmail());

        return null;
    }

 

간단한 더티체킹 설명 : 여기!

참고 

https://dublin-java.tistory.com/32