๐ Spring Boot SQL ์ค์ (hibernate, logging)
์๋ ํ์ธ์, Spring Boot์ hibernate SQL ์ค์ ์ ๋ํด ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ค์ ์ด์์ ํ๋ค๋ณด๋ฉด ์ํ๋ ์ฟผ๋ฆฌ๋ฌธ์ ๋ํด ํ์ ํ๊ณ , DB์์ ๊ฒฐ๊ณผ๊ฐ์ ํ์ธํ๊ณ ์ถ์๋๊ฐ ์์ต๋๋ค.
์ด๋, ๋ก๊ทธ ํ์ผ์ ์ฟผ๋ฆฌ๋ฌธ์ด ์ ์ฅ์ด ๋์ด์๋ค๋ฉด, ํด๋น ์ฟผ๋ฆฌ๋ฌธ์ ๋ณต๋ถํ์ฌ ๊ฐ๋จํ ๊ฒฐ๊ณผ๊ฐ์ ํ์ธํ ์ ์๋ ์ฅ์ ์ด ์กด์ฌํฉ๋๋ค. ๋ฌผ๋ก ๋ชจ๋ ์ฟผ๋ฆฌ๋ฌธ์ ๋ํด ๋ก๊ทธ ํ์ผ์ ์ ์ฅํ๋ค๋ฉด ์ฉ๋ ๋ฑ์ ์ด์๊ฐ ์์์๋ ์๊ฒ ์ฃ ?
ํนํ ๋ณต์กํ๊ฒ ์ํ๋๋ ์ฟผ๋ฆฌ๋ฌธ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์ ์กด์ฌํ ๋, ์ด๋ฅผ ํ๋์ฉ ๋ถ์ํ์ฌ DB์์ ์ฟผ๋ฆฌ๋ฅผ ์ํํ์ฌ ๊ฒฐ๊ณผ๊ฐ์ ํ์ธํ๊ธฐ์๋ ๊ฝค๋ ๋ฒ๊ฑฐ๋ก์ด ์์ ์ด ๋ ์ ์๋๋ฐ์ ์ด๋ด๋ ๊ต์ฅํ ํธํ๊ฒ ํ์ธํ ์ ์์ต๋๋ค.
StringBuilder sb = new StringBuilder(some_appropriate_size);
sb.append("select id1, id2, id3, id4, ... ");
sb.append(id2);
...
sb.append(" from ");
...
sb.append(" where ");
...
sb.append(" order by ");
...
return sb.toString();
ํนํ ๋ ๊ฑฐ์ ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ, ์์ ๊ฐ์ด StringBuilder๋ฅผ ํตํด ์ฟผ๋ฆฌ๋ฌธ์ ๋ฌธ์์ด๋ก ๋ง๋ค์ด์ ์คํํ๋ ์ฝ๋๋ ์๋๋ฐ, ์ด์ ๊ฐ์๋ ์ค์ ์ํ๋๋ ์ฟผ๋ฆฌ๋ฅผ ํ์ ํ๋ ค๋ฉด.. ๋ง๋งํฉ๋๋ค์
์์ฆ์, ๋ก๊ทธ ํ์ผ์ด ์ ๋ง ์ค์ํจ์ ๋ค์ ํ๋ฒ ๋๋ผ๊ณ ์๊ณ , ํ์ผ์ ์ ํํ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ๊ฒ ๋ํ ์ค์ํ๊ฑธ ์ฒดํํ๊ณ ์์ต๋๋ค.
๐ SQL ์ค์
hibernate.show_sql
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.show-sql=true
- Hibernate๊ฐ DB์ ์ํํ๋ ๋ชจ๋ ์ฟผ๋ฆฌ๋ฌธ์ ์ฝ์์ ์ถ๋ ฅํฉ๋๋ค.
- ๋ํดํธ ๊ฐ์ false ์ ๋๋ค.
- ์ ์ค์ ์ org.hibernate.SQL๋ฅผ debug๋ก ์ค์ ํ๋ ๊ฒ๊ณผ ๋์ผํ์ง๋ง, show_sql์ ๊ฒฝ์ฐ System.out์ ์ถ๋ ฅํ๋ ๋ฐ๋ฉด org.hibernate.sql์ ๊ฒฝ์ฐ logger์ ์ถ๋ ฅ์ ํ๋ ์ฐจ์ด์ ์ด ์กด์ฌํฉ๋๋ค.
- ๊ณต์๋ฌธ์์๋ show_sql ์ผ๋ก ๋์์์ผ๋ ์ค์ properties(yml) ํ์ผ์๋ ์๋์์ฑ์ด show-sql๋ก ๋์ด์๋๋ฐ์, show-sql๊ณผ show_sql ๋ ์ค ์ด๋๊ฒ์ ์ฌ์ฉํด๋ ์๊ด์ด ์์ต๋๋ค.
logging.level.org.hibernate.SQL=debug
์ค์ ์ถ๋ ฅ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด System.out๊ณผ logger์ ์ถ๋ ฅ์ ํ๋ฏ๋ก ์ฐจ์ด์ ์ด ์กด์ฌํฉ๋๋ค.
- show_sql=true
- org.hibernate.SQL=debug
logger์ ๊ฒฝ์ฐ ์ค์ ์ํ๋๋ ์๊ฐ๋ ํ์ธํ ์ ์๊ธฐ๋๋ฌธ์ ๊ฐ์ธ์ ์ผ๋ก๋ org.hibernate.SQL=debug ์ฌ์ฉ์ ๊ถ์ฅํฉ๋๋ค.
hibernate.format_sql
spring.jpa.properties.hibernate.format_sql=true
- ๋ก๊ทธ, ์ฝ์์ SQL์ ์ข ๋ ์ด์๊ฒ ์ถ๋ ฅํฉ๋๋ค.
- ๋ง์ฝ ์ ์ค์ ์ธ show_sql์ด false๋ผ๋ฉด ์ถ๋ ฅ๋๋ ์ฟผ๋ฆฌ๋ฌธ์ด ์์ผ๋ฏ๋ก, ํ์์๋ ์ค์ ์ ๋๋ค.
- ๋ํดํธ ๊ฐ์ false ์ ๋๋ค.
์ ๋ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๋ฉด format_sql ์ค์ ์ true๋ก ํ ๊ฒฐ๊ณผ๊ฐ ๋ฑ๋ด๋ ํ๋์ ๋งค์ฐ ๋ณด๊ธฐ๊ฐ ์ข์๋ฐ์, ์ด์ฒ๋ผ ๋ฐ๋์ ์ค์ ์ true๋ก ํด์ผ๋์ง ์์๊น?๋ผ๊ณ ์๊ฐ์ ํ์์ผ๋ ์ ๊ฐ ์ฃผ๋ก ์ฐธ์กฐํ๋ Baeldung์์๋ ๋ค์๊ณผ ๊ฐ์ ์ด์ผ๊ธฐ๋ฅผ ํ๊ณ ์์ต๋๋ค.
"While this is extremely simple, it's not recommended, as it directly unloads everything to standard output without any optimizations of a logging framework."
์ ๋ฌธ์ฅ์ ๋ฒ์ญํด๋ณด์๋ฉด, "์ด ๋ฐฉ๋ฒ์ ๋งค์ฐ ๊ฐ๋จํ๋ ๋ก๊น
ํ๋ ์์ํฌ์ ์ด๋ ํ ์ต์ ํ๋ ์์ด ๋ชจ๋ ๊ฒ์ ํ์ค ์ถ๋ ฅ(standard output)์ผ๋ก ์ง์ unloadํ๋ฏ๋ก ๊ถ์ฅ๋์ง ์์ต๋๋ค." ๋ผ๊ณ ํฉ๋๋ค.
๊ฐ๋ ์ฑ ์ข๊ฒ ๊ฐํ์ ํ์ฌ ์ถ๋ ฅํ๊ธฐ ๋๋ฌธ์, ๋น์ฐํ ๋ก๊ทธ์ ๊ธฐ๋ก๋๋ ํ์ผ์ ์ฉ๋์ด๋ ๋ผ์ธ์ ๋ ๊ธธ์ด์ง ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ ์ธ์ ๋ ๊ทธ๋ ๋ฏ(?) ์ํฉ์ ๋ง๊ฒ ์ ์ ํ ์ฌ์ฉํ๋๊ฒ์ด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค. ๐
hibernate.highlight_sql
spring.jpa.properties.hibernate.highlight_sql=true
- SQL ์ถ๋ ฅ์ ANSI escape codes๋ฅผ ์ฌ์ฉํ์ฌ ์์ ๋ถ์ฌํฉ๋๋ค.
hibernate.use_sql_comments
spring.jpa.properties.hibernate.use_sql_comments=true
- ๋ณด๋ค ์ฌ์ด ๋๋ฒ๊น ์ ์ํด SQL ๋ด๋ถ์ /* */์ ์ฃผ์์ ์ถ๊ฐํฉ๋๋ค.
hibernate.type.descriptor.sql=trace
logging.level.org.hibernate.type.descriptor.sql=trace
- ์ฟผ๋ฆฌ๋ฌธ ๋ก๊ทธ์ ์ถ๋ ฅ๋์ด ์๋ ํ๋ผ๋ฏธํฐ(?)์ ๋ฐ์ธ๋ฉ ๋๋ ๊ฐ์ ํ์ธํ ์ ์์ต๋๋ค.
- trace๋ก ์ค์ ํด์ผ ๋ฐ์ธ๋ฉ ํ๋ผ๋ฏธํฐ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
- binding parameter
๐ ์ ๋ฆฌ
์์์ ์ค์ ํ ์ต์ ๋ค์ ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
// properties
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.highlight_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql=trace
// yml
spring:
jpa:
properties:
hibernate:
format_sql: true
highlight_sql: true
use_sql_comments: true
logging:
level:
org:
hibernate:
SQL: debug
type:
descriptor:
sql: trace
์ฐธ๊ณ ๋ก properties ํ์ฅ์์ ํ์ผ๊ณผ yml ํ์ฅ์์ ํ์ผ๊ฐ ๋ณํ์ ๋ค์ ์ฌ์ดํธ๋ฅผ ํตํด ์์ฝ๊ฒ ํ ์ ์์ต๋๋ค.
์์๋ SQL๊ณผ ๊ด๋ จ๋ hibernate ์ค์ ์ต์ ๋ค์ ๋ํด์๋ง ์ดํด๋ณด์๋๋ฐ์, ๊ณต์๋ฌธ์์๋ ๊ต์ฅํ ๋ง์ ์ค์ ๋ค์ด ์กด์ฌํฉ๋๋ค.
๊ทธ๋์ show_sql๊ณผ format_sql์ ๊ฐ๋ง ์ค์ ํด์ ๋๋ต์ ์ผ๋ก ์ฌ์ฉ์ ํ์๋๋ฐ์, ์ ๋ฆฌ๋ฅผ ํตํด ์ค์ ๊ฐ๋ค์ ๋ณด๋ค ์์ธํ ํ์
ํ ์ ์์์ต๋๋ค. ๋น์ทํ๋ฏ ๋น์ทํ์ง์์ ์ค์ ๋ค์ด ์์ด์ ๊ฝค ํท๊ฐ๋ ธ์๋๋ฐ์, ํนํ ์ฟผ๋ฆฌ๋ฌธ์ ๋ก๊น
ํ๊ฑฐ๋ ๋ฐ์ธ๋ฉ ํ๋ผ๋ฏธํฐ์ ๋ํด์๋ ๋ก๊น
ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ฐพ์๋ณด๋ค๊ฐ ํท๊ฐ๋ ค์ ์์ฑํ๊ฒ ๋์์ต๋๋ค.
์ฐธ๊ณ
- https://goodgid.github.io/Spring-Boot-SQL-Option/
- https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html
'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring Thread, Transaction, Connection ๊ด๊ณ (0) | 2022.09.03 |
---|---|
Spring Data MongoDB Array field $elemMatch(MongoRepository Custom) (2) | 2022.08.20 |
Spring AOP - (2) AOP ๊ฐ๋ ๋ฐ ์ค์ต (0) | 2021.09.24 |
[Spring] - ๋ก๊น : Log4j, Log4j2, Slf4j, Logback (0) | 2021.09.15 |
Spring Validation - @NotNull, @NotEmpty, @NotBlank (0) | 2021.09.09 |
๋๊ธ