Develop/spring-data

jpa, querydsl 적용 시 로깅 비교. querydsl로 작성한 쿼리 DBMS에서 쉽게 돌리는 방법. 1탄!

에디개발자 2020. 11. 10. 12:15
반응형

jpa, querydsl가 type-safe로 장점이 뚜렸하였지만 단점도 존재하였습니다. 이 글에선 다양한 쿼리 로그 방법에 대해서 알아보겠습니다. 각 로그방식의 설명과 불편한 점을 다루도록 하겠습니다. 

작성된 글의 소스 코드는 github에 올려두었습니다.

JPA, Querydsl 설정 방법은 아래 링크를 참조해주시면 됩니다!

 

JPA에 대해서 궁금하시면?

Querydsl에 대해서 궁금하시면?

 

기존 프로젝트에서는 Mapper.xml을 사용하였습니다. 쿼리문이 mapper.xml에 작성되어있기 때문에 DataGrip(DBMS)에서 복붙해서 바로 실행할 수 있는 간단함이 있었습니다. 하지만 querydsl로 작성한 쿼리는 DBMS에서 복붙할 수 없었습니다. ( java code 이므로.. )

// querydsl로 작성한 쿼리
jpaQueryFactory
    .select(Projections.fields(StaffVo.class,
		staff.id
		, staff.age
		, staff.name
	))
	.from(store)
	.join(staff)
		.on(store.id.eq(staff.storeId))
	.where(store.name.eq(name))
.fetch();

 

그럼 실제 운영에서 쿼리관련 에러가 발생하면 위 코드를 DBMS로 옮기는 데 시간이 더 걸리겠다!!

그래서 찾아본 방법이 쿼리 로그 였습니다. querydsl로 작성한 쿼리의 대한 JUnit 케이스를 만들어서 필요한 쿼리를 실행하여 로그로 Sql문을 얻어서 DBMS에 사용하는 방법입니다. 로그 방법은 총 3가지이며 제가 생각하기에 가장 좋은 로그 방법도 정리하겠습니다.

  • jpa.properties.hibernate.show_sql
  • logging.level.org.hibernate.SQL
  • p6spy

 

jpa.properties.hibernate.show_sql

application.yaml에 작성합니다.

  jpa:
    properties:
      hibernate:
        show_sql: true

적용 후 결과

Hibernate: select staff1_.id as col_0_0_, staff1_.age as col_1_0_, staff1_.name as col_2_0_ from store store0_ inner join staff staff1_ on (store0_.id=staff1_.store_id) where store0_.name=?

너무 보기 불편합니다. 

 

보기 좋게 바꿔주도록 합니다. application.yaml을 수정합니다.

  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true		// 추가

적용 후 결과

Hibernate: 
    select
        staff1_.id as col_0_0_,
        staff1_.age as col_1_0_,
        staff1_.name as col_2_0_ 
    from
        store store0_ 
    inner join
        staff staff1_ 
            on (
                store0_.id=staff1_.store_id
            ) 
    where
        store0_.name=?

보기 편해졌네요!

DataGrip에 DBMS에 붙혀 사용해봅니다.

DataGrip에서 결과값 조회

Alias 때문에 보기 불편하네요.

 

sql문 comment들도 사용하도록 추가

  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true
        use_sql_comments: true		// 추가

적용 후 결과

Hibernate: 
    /* select
        staff.id,
        staff.age,
        staff.name 
    from
        Store store   
    inner join
        Staff staff with store.id = staff.storeId 
    where
        store.name = ?1 */ select
            staff1_.id as col_0_0_,
            staff1_.age as col_1_0_,
            staff1_.name as col_2_0_ 
        from
            store store0_ 
        inner join
            staff staff1_ 
                on (
                    store0_.id=staff1_.store_id
                ) 
        where
            store0_.name=?

주석 처리로 ( /* */ ) 설명이 붙었네요. 

하지만 어떤 파라미터를 넘겼는지 결과값으로 어떤값이 나왔는지 확인하기 어렵네요.

그리고 역시 DBMS에서 사용하기에는 불편하네요. 아래 설정을 추가로 파라미터 값도 로그에 보여줍니다.

 

logging.level.org.hibernate.sql

application.yaml에 적용합니다.

logging:
  level:
    org:
      hibernate:
        SQL: DEBUG
        type:
          trace

적용 후 결과

2020-11-09 10:57:55.825 DEBUG 95037 --- [           main] org.hibernate.SQL                        : select staff1_.id as col_0_0_, staff1_.age as col_1_0_, staff1_.name as col_2_0_ from store store0_ inner join staff staff1_ on (store0_.id=staff1_.store_id) where store0_.name=?
2020-11-09 10:57:55.935 TRACE 95037 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [스토어6]
2020-11-09 10:57:55.943 TRACE 95037 --- [           main] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([col_0_0_] : [BIGINT]) - [10]
2020-11-09 10:57:55.945 TRACE 95037 --- [           main] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([col_1_0_] : [INTEGER]) - [34]
2020-11-09 10:57:55.947 TRACE 95037 --- [           main] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([col_2_0_] : [VARCHAR]) - [staffName4]
2020-11-09 10:57:55.947 TRACE 95037 --- [           main] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([col_0_0_] : [BIGINT]) - [11]
2020-11-09 10:57:55.948 TRACE 95037 --- [           main] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([col_1_0_] : [INTEGER]) - [21]
2020-11-09 10:57:55.948 TRACE 95037 --- [           main] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([col_2_0_] : [VARCHAR]) - [staffName5]

이제 어떤 파라미터로 요청하고 결과값으로 어떤값이 오는지 확인할 수 있게 되었습니다.

하지만 사용하기에는 아직 부족한 감이 있습니다.

 

p6spy

위의 두 로그 방식의 불편함을 해결할 수 있는 로그 방식입니다. 설정하는 데는 다소 길어질 것하여 다음글에 정리하겠습니다.

 

 

 

 

 

 

반응형