Logging trong Hibernate
hibernate
3
logging
7
White

Nguyễn Tuấn Anh viết ngày 11/09/2018

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

  1. datasource-proxy
  2. P6Spy

Tài liệu tham khảo

http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#sql_statementlogging

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Nguyễn Tuấn Anh

30 bài viết.
264 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
58 42
MyContact là một ứng dụng mà mình thường viết mỗi khi học một ngôn ngữ hay công nghệ mới. MyContact chỉ là một ứng dụng CRUD đơn giản, cho phép ngư...
Nguyễn Tuấn Anh viết gần 4 năm trước
58 42
White
40 17
Hướng dẫn lập trình Spring Security Trong bài viết lần này, mình sẽ giúp các bạn bước đầu tìm hiểu (Link) thông qua xây dựng các chức năng: Đăng ...
Nguyễn Tuấn Anh viết gần 4 năm trước
40 17
White
23 0
Trước đây khi mới học Spring, mình thường nhảy thẳng lên tìm hiểu các project như Spring MVC hay Spring Boot để viết ứng dụng, thỉnh thoảng mới ngó...
Nguyễn Tuấn Anh viết gần 2 năm trước
23 0
Bài viết liên quan
White
3 2
Vấn đề Nay mình được các giao cho cái việc đồng bộ cái database với elasticsearch, đầu tiên là mình dùng thằng logstash cho nó chạy schedule 5 ph...
hunghh.dev viết 3 tháng trước
3 2
White
25 0
(Ảnh) Slow query là gì? Khi các câu query chậm hơn một thời gian nhất định tùy theo bạn định nghĩa, ví dụ chậm hơn 50ms, thì các câu query đó đư...
Triet Pham viết hơn 3 năm trước
25 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
30 bài viết.
264 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!