
[JPA] Cascade(영속성 전이)에 관해
2022. 11. 27. 00:01
스프링/JPA
Cascade JPA에서는 엔티티끼리 다대일, 일대일 등의 연관관계를 맺어줄 수 있다. [학생 - 학급] 테이블이 양방향 다대일 관계를 이루고 있다고 가정해보자. 만약, 학급을 만들면서 이 학급에 속하는 학생들을 만들고 싶다면 보통의 경우 아래 순서로 이루어질 것이다. 1. 학급 테이블 생성 및 값 세팅 2. 학생 테이블 생성 및 값 세팅 3. 학급 테이블의 학생 속성에 학생 객체를 리스트로 저장 4. 학급 테이블 저장 5. 학생 테이블의 학급 속성에 학급 객체를 저장 6. 학생 테이블 저장 3번 과정에 주목하자. 여기서 우리는 이미 학급 클래스에 학생 객체를 저장한 상태이다. 이것은 학생의 입장에서 자신에게 학급이 배정되었다고도 말할 수 있다. 하지만 엄밀히 따지면 학생 클래스에는 학급 객체가 저장되지..

[Thymeleaf] URL에 파라미터 담아 전달하기
2022. 11. 25. 14:00
스프링/Thymeleaf
이런식으로 th:href 안에 소괄호를 만들어 파라미터값을 전달할 수 있다. @GetMapping("/simpleInfo") public String simpleInfo(@RequestParam String trainerId, Model model) { return "trainer/simpleInfo"; } @RequestParam은 생략 가능하다.

[스프링] Optional [orElse vs orElseGet]
2022. 11. 19. 19:39
스프링
orElse User user = userRepository.findByUsername(username).orElse( userRepository.save(User.builder() .username(username) .password(password) .email(email) .provider(provider) .providerId(providerId) .role(role) .build()) ); return user; Optional의 값 유무와 상관 없이 실행된다. Optional이 null이 아니라면 가져온 값 반환, null이라면 orElse로 실행된 값 반환. 즉, 위 코드에서 user 값이 있더라도 새로운 User 객체가 생성되어 저장된다. orElseGet User user = userRe..

mustache 템플릿 설정
2022. 11. 18. 16:28
스프링
라이브러리 추가 스프링부트 버전과 동일한 머스테치 라이브러리 의존성을 등록해준다. implementation 'org.springframework.boot:spring-boot-starter-mustache:2.7.5' https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mustache/2.7.5 설정파일 생성 현재 머스테치는 .mustache 파일을 인식하게 되어있다. 머스테치가 .html 파일을 인식할 수 있도록 별도의 설정파일을 만들어준다. package com.example.mustache.config; import org.springframework.boot.web.servlet.view.MustacheV..

[자바] Lombok - 부모클래스의 toString 호출하기
2022. 11. 17. 00:42
스프링
매우 간단하므로 두 단계로 끝내겠다. 부모클래스에 ToString 어노테이션 선언 @Getter @MappedSuperclass @ToString public abstract class BaseEntity { private LocalDateTime createdAt; private LocalDateTime modifiedAt; } 자식 클래스에 callSuper 설정 @ToString(callSuper = true) public class Customer extends BaseEntity { private Long id; } 디폴트는 false 이다.

[JPA] dataSourceScriptDatabaseInitializer 빈 생성 오류
2022. 11. 15. 17:51
스프링/JPA
강의듣다가 해당 오류 발생.. 공식 문서 내용 Hibernate and data.sql By default, data.sql scripts are now run before Hibernate is initialized. This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase. If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true. While mixing database initialization technologies i..

[스프링] Querydsl - 동적쿼리 구현 방법
2022. 10. 19. 17:05
스프링
BooleanBuilder public void dynamicQuery_BooleanBuilder() { String usernameParam = "member1"; Integer ageParam = null; List result = searchMember(usernameParam, ageParam); } private List searchMember(String usernameCond, Integer ageCond) { BooleanBuilder builder = new BooleanBuilder(); if (usernameCond != null) builder.and(member.username.eq(usernameCond)); } if (ageCond != null) { builder.and(me..

[스프링] @RestControllerAdvice 이용한 예외처리 방법
2022. 10. 14. 14:37
스프링
@RestControllerAdvice 스프링에서 예외처리를 하는 대표적인 방법으로 @ExceptionHandler 어노테이션이 있다. 하지만 이 어노테이션은 각각의 메서드에 따로 적용되기 때문에, 필요한 메서드마다 일일이 달아줘야 하는 번거로움이 있다. 우리는 RestControllerAdvice 어노테이션을 이용해 그 불편함을 줄일 수 있다. 바로 코드로 설명하겠다. @RestControllerAdvice public class GlobalExceptionHandler { @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 500 error @ExceptionHandler(Exception.class) // public Exception handlerAllE..

[스프링] 톰캣(Tomcat) 서버 시작 속도 개선
2022. 10. 6. 19:35
스프링
스프링 어플리케이션으로 서버를 시작하다가, 톰캣으로 직접 서버를 구동할 일이 생겼는데 실행 속도 때문에 미칠지경이었다. 도저히 안되겠다 싶어 구글링한 결과 개선방법을 찾았다. 톰캣 폴더 내 conf 폴더에 있는 catalina.properties, context.xml 두 파일에 약간의 설정값을 넣어줄 것이다. catalina.properties 파일을 열면 표시된 것 처럼 tomcat.util.scan.StandardJarScanFilter.jarsToSkip= 라고 쓰인 부분이 있다. 이 곳에 *.jar 를 추가하자. 톰캣 구동 시 util에 있는 jar 파일 스캐닝을 스킵한다고 한다. 따라서 현재 내 프로젝트에 사용해도 되는지 검증이 필요하며, 나중에 문제가 생겼을 때 원인 파악을 위해 수정 사항을..

[스프링] 접속 IP 주소 IPv4 형태로 가져오기 (인텔리제이)
2022. 10. 6. 18:24
스프링
HttpServletRequest의 getRemoteAddr 메서드를 이용해 IP주소를 가져올 수 있다. @RequestMapping("/") public String index(HttpServletRequest request) { String remoteAddr = request.getRemoteAddr(); System.out.println("remoteAddr = " + remoteAddr); return "index"; } 단, 주소 형태는 IPv6가 디폴트다. IPv4 형태로 주소를 가져올 수 있도록 IDE에서 세팅해줘야 한다. VM option에 아래 코드 두 줄을 추가해주면 된다. -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses..

[Spring Data JPA] EntityGraph 사용해서 쿼리 조회 최적화
2022. 9. 26. 21:15
스프링/JPA
EntityGraph 지연로딩 간단 개념 엔티티를 설계할 때 연관관계 매핑에서 FetchType을 보통 LAZY로 설정해주는 게 일반적이다. 지연로딩이라고 흔히 부르는 이 설정은 다양한 연관관계로 매핑되어 있는 엔티티를 호출할 때 셀렉트 쿼리의 최적화를 위해 다른 엔티티를 프록시 객체로 생성하는 것을 말한다. ex) Member와 Team이 N:1(다대일) 관계일 때 Member 엔티티를 호출하면 Team 엔티티는 프록시 객체로 생성되고 Member에만 select 쿼리를 날린다. 쿼리 최적화를 위해 지연로딩 설정을 해주지만 오히려 이런 설정이 최적화에 불리할 때가 있다. Member(N) : Team(1) 엔티티 관계를 예로 들겠다. Member를 생성하면 Team은 프록시 객체다. 그렇기에 Team ..

[Spring Data JPA] 사용자 정의 레파지토리 생성
2022. 9. 26. 20:40
스프링/JPA
레파지토리에 구현한 메서드만으로 해결이 어려운 복잡한 쿼리, 동적 쿼리 등은 보통 사용자 정의 레파지토리를 만들어서 해결한다. 그리고 핵심 비즈니스 로직이 담긴 쿼리와 그 외 특정 용도로 만든 쿼리를 분리해주는게 베스트 인 것도 이유가 된다. 바로 알아보겠다. 사용자 정의 레파지토리 생성 public interface MemberRepositoryCustom { List findMemberCustom(); } 사용자 정의 레파지토리를 생성한다. 일반적인 인터페이스로 생성하면 되며, 별도의 어노테이션은 기본적으로 없어도 된다. 임의의 클래스 만들어서 사용자 정의 레파지토리 상속받기 @RequiredArgsConstructor public class MemberRepositoryImpl implements ..