Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Logging trong Hibernate
Logging, cụ thể là logging SQL statement là một tính năng không thể thiếu trong bất kỳ ORM framework nào. Trong bài viết này, mình sẽ tổng hợp một vài kinh nghiệm nhỏ của bản thân về logging trong Hibernate - một trong những Java ORM framework được dùng phổ biến nhất hiện nay.
1. Cấu hình logging trong Hibernate
1.1. Show SQL statement
Chúng ta sẽ cấu hình bằng thuộc tính hibernate.show_sql=true/false
. Giá trị mặc định là false
.
Hibernate sẽ in SQL statement ra console theo cơ chế StdOut:
Hibernate: update post set title=? where id=?
1.2. Format SQL statement
Chúng ta sẽ cấu hình bằng thuộc tính hibernate.format_sql=true/false
. Giá trị mặc định là false
.
SQL statement khi in ra console sẽ được format thành nhiều dòng thay vì một dòng:
Hibernate:
update
post
set
title=?
where
id=?
1.3. Comment SQL statement
Chúng ta sẽ cấu hình bằng thuộc tính hibernate.use_sql_comments=true/false
. Giá trị mặc định là false
.
Hibernate sẽ gen thêm comment trên mỗi SQL statement để giải thích thao tác với entity của SQL statement:
Hibernate: /* update org.ashina.tutorial.hibernate.entity.Post */ update post set title=? where id=?
...
Trong thực tế, việc ghi log ra console theo cơ chế StdOut như ở trên chỉ nhằm phục vụ cho quá trình develop. Ở môi trường product, việc làm này lại được coi là một bad practice. Chúng ta nên sử dụng các logging framework như Logback để ghi log. Ví dụ với Logback, trong file cấu hình, chúng ta sẽ thêm logger sau:
<logger name="org.hibernate.SQL" level="debug"/>
2. Show SQL statement parameter
Chúng ta có thể thấy khi show SQL statement, các parameter được hiển thị dưới dạng ký hiệu ?
. Điều này gây không ít khó chịu trong khi debug. Chúng ta sẽ giải quyết vấn đề này bằng cách sử dụng các thư viện như datasource-proxy, P6Spy ...
2.1. datasource-proxy
Với thư viện này, data access layer thay vì làm việc trực tiếp với datasource, sẽ làm việc thông qua một proxy datasource (đóng vai trò trung gian giữa data access layer và datasource).
Đầu tiên, trong file pom.xml
, chúng ta thêm 2 dependency sau:
<dependency>
<groupId>net.ttddyy</groupId>
<artifactId>datasource-proxy</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
Sau đó đăng ký proxy datasource với StandardServiceRegistry
:
private static DataSource getDataSource() {
// Create DataSource
PGSimpleDataSource dataSource = new PGSimpleDataSource();
dataSource.setUrl("jdbc:postgresql://localhost:5432/blog");
dataSource.setUser("postgres");
dataSource.setPassword("1234");
// Create ProxyDataSource
return ProxyDataSourceBuilder.create(dataSource)
.logQueryByCommons(CommonsLogLevel.INFO)
.name("ProxyDataSource")
.countQuery()
.multiline()
.build();
}
...
Map<String, Object> settings = new HashMap<>();
settings.put(Environment.DATASOURCE, getDataSource());
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.applySettings(settings)
.build();
Kết quả:
Sep 10, 2018 6:19:19 PM net.ttddyy.dsproxy.listener.logging.CommonsQueryLoggingListener writeLog
INFO:
Name:ProxyDataSource, Connection:2, Time:1, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["update post set title=? where id=?"]
Params:[(abc,1)]
2.2. P6Spy
Đầu tiên, trong file pom.xml
, chúng ta thêm dependency sau:
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.0.0</version>
</dependency>
Tiếp theo, chúng ta cần sửa lại 2 thông số kết nối sau:
hibernate.connection.driver_class=com.p6spy.engine.spy.P6SpyDriver
hibernate.connection.url=jdbc:p6spy:postgresql://localhost:5432/blog
Cuối cùng, tạo 1 file có tên spy.properties
nằm trong thư mục src/main/resources
:
driverlist=org.postgresql.Driver
dateformat=yyyy-MM-dd HH:mm:ss
appender=com.p6spy.engine.spy.appender.StdoutLogger
#appender=com.p6spy.engine.spy.appender.FileLogger
#logfile=C:/spy.log
Ở đây, do mình muốn test ngay trên console, nên mình sẽ sử dụng appender là com.p6spy.engine.spy.appender.StdoutLogger
. Nếu các bạn muốn ghi log ra file, có thể dùng appender com.p6spy.engine.spy.appender.FileLogger
và chỉ ra đường dẫn của file log trong thuộc tính logfile
.
Các bạn có thể tham khảo thêm file spy.properties
tại đây.
Kết quả:
2018-09-10 19:00:41|1|statement|connection 0|update post set title=? where id=?|update post set title='abc' where id=1
Source code tham khảo
Tài liệu tham khảo






