QueryDSL이란 ? 먼저 JPQL에 대해서 뭔지 알아야 한다. JPQL은 엔티티를 조회하기 위한 객체지향 쿼리로, 특징은 문자로 쿼리를 작성한다는 점이다. 한번 회원 이름이 kim인 엔티티를 조회하는 쿼리를 작성해보자. String jpql = "select m from Member as m where m where m.username = 'kim'"; 이런식으로 SQL을 추상화해서 특정 데이터베이스(h2, mysql 등등)에 의존하지 않는다. 여기까지만 알아보고, 그럼 왜 QueryDSL이 탄생했는지 알아보자. 어떠한 새로운 것이 탄생하게 된 배경은 기존의 것이 문제가 있기 때문이다. JPQL은 문자로 작성한다는 점이 단점이다. 예를 들어 JPQL에서 다음과 같은 코드를 작성해봤다고 가정해보자. s..
백기선님은 테스트코드, TDD에 대해서 다음과 같이 말한다. 테스트코드를 잘 짜는 개발자의 코드를 신뢰한다. 테스트코드를 짜지 않는 개발자는 좋은 개발자라고 생각하지 않는다. TDD를 짜지 않는다는 것은, 개발자로서 성장하고자 하는 노력을 하지 않은거라고 생각한다. 나도 한 때 TDD에 대해서 살짝 맛봤던적이 있다. 하지만 API 로직을 다 짜놓고 테스트코드를 작성하자니 너무 귀찮았다. "이미 잘 작동하는데 굳이 테스트를 해야하나?" 라고 생각한 것이다. 그리고 컨트롤러에 대한 테스트코드는 어렵다고 생각을 했고, 또 API로직을 짜면서 테스트까지 할 시간이 없었고.. 점점 변명을 만들어가면서 모르는척 넘어갔었다. 백기선님이 영상을 시작하고 첫부분에 짚고 넘어간 부분이 있는데, 바로 밑에 사진이다. 작년 ..
백기선님의 유튜브를 보다가 더 나은 개발자를 위한 팁이란 영상으로 컨텐츠 비슷하게 올려두신게 있어 봤다. 읽어보니 잘못된 행동이 완전히 내가 하던 행동과 똑같았다. 그래서 이 카테고리 글들에서는 백기선님이 유튜브에 올려두신 영상을 바탕으로 글을 써볼 생각이다. 즉 이 내용의 대부분의 출처는 백기선님의 유트브 영상이다. 이번 포스팅에서 이야기할 것은 에러메세지에 대한 내용이다. 에러메세지를 잘못 생각하고 있는 사람들 에러메세지를 두려워하는 사람들은 먼저 에러메세지를 읽지도 않고 그 전에 작성했던 코드를 삭제해본다. 그리고 다시 실행해서 정상 작동이 되면 아마 이렇게 생각할 것이다. "아.. 이걸 넣으면 안되는거구나?" 이렇게 넘어가버리면 절대로 실력이 늘지 않는다. 내 경험 나는 에러가 나면 위 과정을 똑..
나는 대부분 프로젝트를 생성할 때 Spring Initalizr 라는 사이트를 이용한다. 이때 패키징으로 Jar와 War중 정하는 부분이 있는데 둘 중 무엇을 골라야 할지 몰라서 default값인 Jar로 사용하였다. 그럼 Jar와 War가 뭔지 알아보자. JAR Java Archive의 약자로, 자바의 리소스와 속성 파일, 라이브러리 및 기타 부가적인 파일들이 담겨있다. 쉽게 생각해서 자바 에플리케이션이 동작할 수 있게 자바 프로젝트를 압축한 파일이라고 생각하면 된다. WAR Web Application Archive의 약자로, 쉽게 말해서 jar파일에다가 웹 컨테이너, Servlet Context 등 웹 관련 자원을 포함한다. 정리 결론은 꼭 외부 WAS를 쓴다던가 JSP로 뷰를 만들어야 한다면 WA..
1. 양방향 연관관계 엔티티들은 대부분 다른 엔티티와 연관관계가 있다. 회원은 팀에 소속될 수 있기 때문에 회원 엔티티와 팀 엔티티에 관계를 맺어야 한다. 이 부분은 JPA가 생겨난 이유와 패러다임의 불일치 포스팅에서 자세히 나와있다. 참고하자. 간단하게 다시 말하자면 객체는 참조를 사용해서 관계를 맺고 테이블은 외래 키를 사용해서 관계를 맺는다. 객체와 테이블이 관계를 맺을 때 완전히 다르게 맺는 것이다. 그래서 우리는 객체의 참조와 테이블의 외래 키를 매핑하는 것이 이 장의 목표이다. 회원과 팀을 양방향 관계로 매핑해보자. //매핑한 회원 엔티티 @Entity public class Member { @Id @Column(name = "member_id") private String id; privat..
아래는 DB에 저장된 게시글을 다 꺼내서 List로 조회하는 로직이다. 이것을 스트림을 이용하면 단 3줄로 줄일 수 가 있다. 위 코드에서는 스트림의 map과 collect, 람다의 메서드참조를 사용하였다. 어떻게 첫번째 사진이 두번째 사진으로 될 수 있는지 파헤쳐보자. stream 먼저 boardRepository.findAll()은 DB에 있는 게시글들을 List형태로 리턴해준다. 여기에 .stream()을 붙여서 스트림을 얻었다. 이렇게 게시글 리스트에다가 stream 메서드를 호출함으로써 map, filter, limit, collect 등 데이터 처리 연산을 할 수 있게 된다. map 람다를 이용해서 한 요소를 다른 요소로 변환하거나 정보를 추출해준다. 위 코드에서는 람다의 메서드 참조를 이용해..
이번 포스팅에서는 완성된 예제를 가지고 하나하나 돌려보면서 동작과정을 알아보겠다. 완성된 예제는 깃허브링크에 있어 동작과정에서 놓친 코드가 있다면 참고하자. 그리고 꼭 코드를 구현하고 어떻게 동작되는건지 이해가 가지 않을 때 이 포스팅을 참고하는 것이 좋다. 코드를 구현하는 포스팅은 여기로 가면 된다. 먼저 회원가입이다. localhost:8080/member/join에서 이메일과 닉네임, 나이, 비밀번호를 입력한다. Send를 누르면 만들어놓은 컨트롤러에서 저장을 한다. 서비스로직은 다음과 같다. 먼저 Postman에서 요청한 DTO중에 이메일을 findByEmail로 DB에 비어있는지 확인한다. 비어있지 않다면 이미 가입한 계정이라는 뜻이기 때문에, 또 가입할 수 없게 처리한 것이다. 그리고 이메일은..
오류 요청에서 Header에 토큰을 넣었는데도 서버에서 Header에 있는 토큰을 가져오지 못하는 상황이 발생했다. 헤더 키 값을 다르게 했더니 나타나는 반응이 다른것을 보니까 키값을 읽어들이는 건 제대로 작동되는 것 같다. 키값 다르게 했을 때 더이상 콘솔이 찍히지 않음 키값을 같게 했을 때 밑에 콘솔이 뭐가 더 찍힌다. 하지만 토큰값은 가져오질 않는다.. 해결 1. getHeader("여기") 에 직접 적어주는 것이 아니고 명시적으로 필드에 작성했다. 2. 로그를 찍을 때는 메세지 이후에 쉼표가 아닌 플러스로 해야 콘솔에 값이 뜬다. 첫줄은 값이 뜨지만 두번째 줄은 값이 뜨지 않는다. + 와 ,의 차이는 띄어쓰기밖에 없는것 같았지만 아니었다. ,로 찍기 위해선 "헤더에서 받아온 토큰 값 = {}", ..
오류 Spring Security를 구현하고 있을 때 회원가입을 시도했을때의 오류다. 이 예외는 내가 UserDetailsService를 커스텀한 UserDetailsService에서 로그인요청할 때 입력한 아이디가 DB에 존재하지 않을 때 터트리는 예외였다. 분명 회원가입을 하는데 로그인을 할 때 실행되어야 할 클래스가 왜 터질까 ? 해결 문제는 내가 회원가입 요청할때 Header에 자꾸 토큰을 넣고 요청했기 때문이다. 이건 내 추측인데, 헤더에 토큰을 넣고 요청을 보낼 때 JwtAuthenticationFilter에서 헤더에 토큰이 있는 것을 보고 처리한 것이다. 즉, 사용자가 요청을 보내면 JwtAuthenticationFilter -> UsernamePasswordAuthenticationFIlt..
이번 포스팅에서는 실제로 코드를 통해 회원가입 및 JWT를 이용해 토큰을 발급해주고, 페이지 권한까지 해보는 시간을 가지도록 하겠다. 메인 기능인 로그인 구현을 하기 전에 간단하게 회원가입 로직을 짜보자. 로그인 구현에 중점을 두기 때문에 설명은 생략하고 코드만 보여주도록 하겠다. 회원가입 패키지 구조 Member public class Member extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String email; private String nickname; private int age; private String password; @Enumerated(En..
- Total
- Today
- Yesterday