반응형

build.gradle 설정

// querydsl 추가
buildscript {
    ext {
        queryDslVersion = "5.0.0"
    }
}

plugins {
    id 'org.springframework.boot' version '2.6.4'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    
    //querydsl 플러그인 추가
    id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"

    id 'java'
}

group = 'com.study'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
    annotationProcessor 'org.projectlombok:lombok'

    implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.8'

    //querydsl 추가
    implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
    implementation "com.querydsl:querydsl-apt:${queryDslVersion}"

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}


tasks.named('test') {
    useJUnitPlatform()
}

//querydsl 추가 시작
def querydslDir = "$buildDir/generated/querydsl"

querydsl {
    jpa = true
    querydslSourcesDir = querydslDir
}
sourceSets {
    main.java.srcDir querydslDir
}
compileQuerydsl{
    options.annotationProcessorPath = configurations.querydsl
}
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
    querydsl.extendsFrom compileClasspath
}
//querydsl 추가 끝

 

반응형
반응형

클라이언트 측에서 넘어온 데이터를 객체에 바인딩할 때 @Valid와 @Validated로 유효성 검사를 할 수 있습니다.

 

우선 각 빌드에 맞게 의존성을 추가합니다.

 

Gradle일 경우, build.gradle에 의존성 추가

dependencies{
    ...
    implementation 'org.springframework.boot:spring-boot-starter-validation'
}

 

Maven일 경우, pom.xml에 의존성 추가

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.6.3</version>
</dependency>

 

유효성 검사를 위한 어노테이션 적용

객체에 유효성 검사를 적용할 필드에 어노테이션을 적용합니다.

 

public class Article {

    private Long id;
    
    @NotEmpty
    private String title;
    
    @NotEmpty
    private String content;
    
    ...

}

 

어노테이션 종류

Anotation 제약조건
@NotNull Null 불가
@Null Null만 입력 가능
@NotEmpty Null, 빈 문자열 불가
@NotBlank Null, 빈 문자열, 스페이스만 있는 문자열 불가
@Size(min= , max= ) 문자열, 배열등의 크기가 만족하는가?
@Pattern(regex= ) 정규식을 만족하는가?
@Max(숫자) 지정 값 이하인가?
@Min(숫자) 지정 값 이상인가
@Future 현재 보다 미래인가?
@Past 현재 보다 과거인가?
@Positive 양수만 가능
@PositiveOrZero 양수와 0만 가능
@Negative 음수만 가능
@NegativeOrZero 음수와 0만 가능
@Email 이메일 형식만 가능
@Digits(integer= , fraction = ) 대상 수가 지정된 정수와 소수 자리 수 보다 작은가?
@DecimalMax(value= )  지정된 값(실수) 이하인가?
@DecimalMin(value= ) 지정된 값(실수) 이상인가?
@AssertFalse false 인가?
@AssertTrue true 인가?

 

Controller에서 유효성 검사

해당 유효성 검사를 할 것인지에 대해 Controller에서 @Valid를 통해 적용할 수 있습니다.

 

@RestController
public class ArticleController {

    ...

    @PostMapping("/article/write")
    public ResponseEntity articleWrite(@RequestBody @Valid Article article) {
        ...
    }

}

 

@Validated

@Validated 어노테이션은 스프링에서 제공하는 @Valid 기능을 확장한 어노테이션이고 그룹핑 목적으로 사용합니다. 예를 들어 위 예제에서 본 Article 클래스에서 @NotEmpty를 통해 게시글 제목과 내용에 null값과 빈 문자열이 들어가지 못하도록 설정했는데 @Valid를 사용하면 필드에 적용된 모든 어노테이션에 대한 검증이 이뤄지므로 특정 필드만 유효성 검사를 하고 싶을 경우에는 필드를 그룹핑하여 일부만 유효성 검사를 할 수 있습니다.

 

그룹을 지정하기 위한 용도의 클래스를 하나 생성하고 그룹별 interface를 클래스 내에 생성합니다.

 

public class ValidationGroups {

    public interface groupA {};
    public interface groupB {};

}

 

 

그리고 적용할 필드에 그룹을 적용하면 그룹핑이 끝납니다.

 

public class Article {

    private Long id;
    
    @NotEmpty(group = {ValidationGroups.groupA.class})
    private String title;
    
    @NotEmpty(group = {ValidationGroups.groupB.class})
    private String content;
    
    ...

}

 

위에서 본 예제 Controller에 유효성 검사 시 게시글 내용만 null값을 체크하고 싶으면 아래 코드처럼 적용하시면 됩니다.

 

@RestController
public class ArticleController {

    ...

    @PostMapping("/article/write")
    public ResponseEntity articleWrite(@RequestBody 
                                       @Validated(ValidationGroup.groupB.class) Article article) {
        ...
    }

}
반응형
반응형

엔티티(Entity) 설계 시 주의사항

1. Setter를 사용하지 말 것

Setter가 모두 열려있을 경우 변경 포인트가 많아서 유지 보수가 어려워집니다.

 

2. 모든 연관 관계는 지연로딩(LAZY)로 설정할 것 * 중요

즉시로딩(EAGER)은 예측이 어렵고 어떤 SQL이 실행될 지 예측하기 어렵습니다. 특히 JPQL을 실행할 때 N+1 문제가 자주 발생하게 됩니다.

 

3. 컬렉션은 필드에서 초기화할 것

컬렉션은 필드에서 바로 초기화해야 NullPointerException으로부터 안전합니다.

반응형
반응형

persistence.xml 설정

resources 디렉토리 밑에 META-INF 디렉토리를 생성하고 그 안에 persistence.xml을 만든 다음 아래 내용을 자신의 개발 환경에 맞게 세팅하시면 됩니다.

 

<?xml version="1.0" encoding="UTF-8" ?>
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/">
    
    <!-- EntityManagerFactory 생성 시 unit name과 일치해야 합니다 -->
    <persistence-unit name="hello">
        <properties>
            <!-- 필수 속성 -->
            <!-- DB Driver -->
            <property name="javax.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver"/>
            
            <!-- DB user info -->
            <property name="javax.persistence.jdbc.user" value="user"/>
            <property name="javax.persistence.jdbc.password" value="password"/>
            
            <!-- DB url -->
            <property name="javax.persistence.jdbc.url" value="jdbc:mariadb://localhost:3306/schema"/>
            
            <!-- DB Dialect 설정 -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MariaDB103Dialect"/>
            
            <!-- 옵션 -->
            <!-- SQL show -->
            <property name="hibernate.show_sql" value="true"/>
            
            <!-- SQL 정렬 -->
            <property name="hibernate.format_sql" value="true"/>
            
            <!-- SQL에 관한 주석 처리 -->
            <property name="hibernate.use_sql_comments" value="true"/>
            
            <!-- application 실행 시 ddl 전략 -->
            <property name="hibernate.hbm2ddl.auto" value="create"/>
        </properties>
        
    </persistence-unit>
</persistence>
반응형

+ Recent posts