Gradle Spring cloud config, JPA Setting

두별·2023년 1월 15일
1

TIL

목록 보기
33/46

새로 시작한 토이프로젝트는 드디어 JPA를 사용한다!
기존 MyBatis 방식에서 JPA는 어떤 점이 더 편리해졌는지 찬찬히 알아가보자.
오늘은 Spring cloud config와 JPA config 셋팅을 추가했고
사용자 조회하는 테스트 컨트롤러까지 만들어봤다.

1. build.gradle

디펜던시 추가

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'com.mysql:mysql-connector-j'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	implementation 'org.springframework.cloud:spring-cloud-starter-config:3.1.5'
	implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.5'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'mysql:mysql-connector-java'
}

2. application.yml

spring:
  application:
    name: 프로젝트명
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database: mysql
    hibernate:
        ddl-auto: none
    generate-ddl: false
    show-sql: true
  • spring.jpa.hibernate.ddl-auto
    • create : SessionFactory 시작시 스키마를 삭제하고 다시 생성
    • create-drop : SessionFactory 종료 시 스키마를 삭제
    • update : SessionFactory 연결된 DB와 비교하여 추가된 항목은 추가 만약 같은 변수명이면 오류발생
    • validate : SessionFactory 시작시 객체구성과 스키마가 다르다면 예외 발생
    • none: 아무것도 안함
  • spring.jpa.generate-ddl
    true로 설정 시, Entity 어노테이션(@Entity)이 명시된 클래스를 찾아서 ddl을 생성하고 실행

개발자 인생이 끝장나고 싶지 않다면 ddl-auto는 none으로 해두는 것이 좋다. create나 update는 운영 환경에서 쓰이면 데이터를 날릴 위험이 크기 때문에 test 환경에서만 사용한다.

3. Entity

@Entity : 어노테이션은 테이블과 1:1로 매칭되는 객체
@Id : 객체의 인스턴스를 구분하기 위한 유일한 키, Primary key와 같은 의미
@Column : 테이블의 컬럼과 1:1 매칭되는 멤버 변수 (필요한 컬럼만 작성해도 됨)
@GeneratedValue : PK의 값 자동 생성 전략 - AUTO(default), IDENTITY, SEQUENCE, TABLE_

@Entity
@Table(name = "user_info")
@ToString
@Getter
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private Long userSeq;
}

4. MySQL 대소문자 구분안하기

이제 JPA로 데이터 조회좀 때려볼려고 했더니 아래와 같은 에러 등장

caused by: java.sql.sqlsyntaxerrorexception: table '데이터베이스명.테이블명' doesn't exist

SQL에서 직접 해당 테이블 조회 쿼리 날려보니 같은 에러가 났는데
나의 경우는 MySQL에서 대소문자를 구분하게 셋팅되어 있어서 발생하는 에러였다.

docker 볼륨 설정을 해야해서 옵션값 설정해주고 이미지 다시 run함..

docker run --name mysql -e MYSQL_ROOT_PASSWORD=패스워드 -v /home/ubuntu/mysql/conf:/etc/mysql/conf.d -v /home/ubuntu/mysql/data:/var/lib/mysql -d -p 3306:3306 mysql:latest

config 파일 수정

cd /etc/mysql/conf.d
vi mysql.cnf

[mysqld] 밑에
lower_case_table_names = 1
요거를 넣어주고 mysql 재시작
$ service mysql restart

5. Controller 생성

공통으로 사용되는 API 어노테이션 생성

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@RestController
@RequestMapping("/api")
public @interface ApiController {
}
  • SOURCE : 어노테이션을 사실상 주석처럼 사용하는 것. 컴파일될때 메모리를 버림
  • CLASS : 컴파일될때 어노테이션의 메모리를 가져가지만 런타임시에는 사라짐
  • RUNTIME : 어노테이션을 런타임시까지 사용할 수 있음. JVM이 자바 바이트코드가 담긴 class 파일에서 런타임 환경을 구성하고 런타임을 종료할 때까지 메모리는 살아있다.

User 조회 Controller

@ApiController
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;

    @GetMapping("/user/{userSeq}")
    public UserDto getUser(@PathVariable Long userSeq) {
        return userService.findUser(userSeq);
    }
}

User 조회 Service

@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;

    public UserDto findUser(Long userSeq) {
        Optional<User> userOpt = userRepository.findById(userSeq);
        User user = userOpt.orElse(null);
        return UserDto.from(user);
    }
}

결과 테스트

읽어보면 좋은 포스팅
https://youtu.be/SWZcrdmmLEU
https://kyu9341.github.io/java/2020/04/14/java_springBootDBinit/
https://www.icatpark.com/entry/JPA-%EA%B8%B0%EB%B3%B8-Annotation-%EC%A0%95%EB%A6%AC
https://sas-study.tistory.com/329

0개의 댓글