PlayData 백엔드 부트캠프 정리

다시 시작하는 부트 캠프 하루 후기 4일차

효건 2024. 10. 18. 08:59

일정변동으로 인해 원래는 팀플해야하는데 2일 밀렸다고 합니다. 뭐 대체 공휴일이나 이런것 때문에.... 

 

완전 럭키 비키 상황 더 배울수 있어 오히려 좋아 마인드로 해보겠습니다.

 

 

<스프링 JPA>

 

1. 초기설정 

 application.properties -> yml 파일로 바꿔서 사용한다.

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/jpa?serverTimezone=Asia/Seoul
    username: root
    password: mysql
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
      database: mysql
      database=database-platform: org.hibernate.dialect.MySQL8Dialect

server:
  port:8181

 

위와 같이 application.yml 파일에 저장한다. 여기서 hirvernate를 추가하면 어느 정도 설정이 완료 된다 .

스프링 처음부터 진입 장벽인 높다 ;;;

 

jpa: 안에 database=database-platform: org.hibernate.dialect.MySQL8Dialect 아래에  hibernate를 아래와 같이 작성한다.

hibernate:
  ddl-auto: create

sql에 만들지 업데이트 할지 안말들지 에러에 대한 피드백을 줄지에 대한 것을 만든다.

단, 실무에서는 None를 많이 쓴다고 합니다. 그래야 sql이 안정성을 보장받을 수있습니다. sql 자꾸 바뀌면 자바로직이 계속 바뀔수도 있고... ㅎㅎ ;;;겨

따라서 아래와 같이 yml을 완성한다.

server:
  port:8181

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/jpa?serverTimezone=Asia/Seoul
    username: root
    password: mysql
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database: mysql
    database-platform: org.hibernate.dialect.MySQL8Dialect
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        format_sql: true
        
 //로그설정       
 # log level setting
logging:
  level:
    root: info
    com:
      spring:
        jpa: debug
    org:
      hibernate:
        SQL: debug

 

단 여기서 ddl-auto의 create를 실행후에 계속두면 sql을 drop 했다가 create 했다가 서버 실행때매다 하게 된다. 따라서 

확인하고 Update로 바꾸는 게 좋을 듯하다.

 

<영속성 컨텍스트>

1. Entity Manager

 

  • persist(Object entity): 엔티티를 영속성 컨텍스트에 저장.
  • remove(Object entity): 엔티티를 삭제.
  • find(Class<T> entityClass, Object primaryKey): 엔티티를 기본 키로 조회.
  • merge(Object entity): 준영속 상태의 엔티티를 영속 상태로 변환.

위와 같은 메서드로 영속성을 만들수 있다. 

 

이렇게 영속성을 만들게 되면 아래와 같은 장점이 있다.

  • 동일성 보장: 동일한 트랜잭션 내에서 동일한 엔티티에 대한 참조를 반환.
  • 트랜잭션을 지원하는 쓰기 지연: 엔티티의 변경 사항은 트랜잭션이 커밋될 때까지 즉시 반영되지 않고, 쓰기 지연으로 효율적인 쿼리 처리가 가능합니다.
  • 더티 체킹 (Dirty Checking): 엔티티의 변경 사항을 자동으로 감지하여 데이터베이스에 반영.
  • 지연 로딩 (Lazy Loading): 연관된 엔티티를 실제 필요할 때만 조회하여 성능을 최적화.

 

 

<SpringBoot 와 SQL 연동>

1. hibernate 이용시

yml 에

#    properties:
#      hibernate:
#        format_sql: true
# log level setting

이것을 추가한다. 

 

2.P6SpySqlFormatter 이용시

import com.p6spy.engine.logging.Category;
import com.p6spy.engine.spy.P6SpyOptions;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
import jakarta.annotation.PostConstruct;
import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.springframework.context.annotation.Configuration;

import java.util.Locale;


@Configuration
public class P6SpySqlFormatter implements MessageFormattingStrategy {

    @PostConstruct
    public void setLogMessageFormat() {
        P6SpyOptions.getActiveInstance().setLogMessageFormat(this.getClass().getName());
    }

    @Override
    public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
        sql = formatSql(category, sql);
        return String.format("[%s] | %d ms | %s", category, elapsed, formatSql(category, sql));
    }

    private String formatSql(String category, String sql) {
        if (sql != null && !sql.trim().isEmpty() && Category.STATEMENT.getName().equals(category)) {
            String trimmedSQL = sql.trim().toLowerCase(Locale.ROOT);
            if (trimmedSQL.startsWith("create") || trimmedSQL.startsWith("alter") || trimmedSQL.startsWith("comment")) {
                sql = FormatStyle.DDL.getFormatter().format(sql);
            } else {
                sql = FormatStyle.BASIC.getFormatter().format(sql);
            }
            return sql;
        }
        return sql;
    }

}

 

위와 같이 다시 자바 클래스를 만들어서 사용할수있다. 

 

<JPA 이용 쿼리문 사용하기 >

repository 파일을 이용하여 만들어 내서 SQL쿼리를 만들어달라고 하고 이용하면된다. 


public interface StudentRepository extends JpaRepository<Student, String> {

    List<Student> findByName(String name);

    List<Student> findByCityAndMajor(String city, String major);

    // WHERE major LIKE '%major%'
    List<Student> findByMajorContaining(String major);

    // WHERE major LIKE 'major%'
    List<Student> findByMajorStartingWith(String major);

    // WHERE major LIKE '%major'
    List<Student> findByMajorEndingWith(String major);

 

혹시라도 nativeSQL을 사용하기로 했다면 

@Query(value = "SELECT *FROM tbl_student WHERE stu_name = ? OR city = ?")
List<Student> getStudentsByNameOrCity(@Param("nm") String name, @Param("city") String city);

 

사실상 mybatis를 이용한것과 비슷하게 만들면 된다.

쿼리문은 상당히 많은 곳에서 사용되니 지속적으로 공부하고 숙달해야겠습니다.