[JAVA] Use JUL to record the SQL execution log issued by MyBatis

Introduction

I worked on a surprisingly unusual thing, "Use java.util.logging (hereinafter referred to as JUL) to record the execution log of SQL issued by MyBatis", so the procedure at that time I want to keep it easily. It's a fairly long article, but setting logging.properties should be the most important thing.

Caution

This article has been checked for operation in the following environments, but I think it will work in environments with different versions and middleware.

Preparation (Postgres)

Prepare the following ʻuserstable. The DB will bedev and the user will be dev`.

dev=# \d users
              Table "public.users"
 Column | Type | Collation | Nullable | Default
--------+------+-----------+----------+---------
 id     | text |           | not null |
 name   | text |           | not null |
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)

Preparation (Java project)

Prepare the following four modules.

  1. mybatis.logging.Main.java: Entry point. The main method is defined.
  2. mybatis.logging.repository.UsersRepository.java: ʻusers` Mapper interface to the table.
  3. mybatis-config.xml: Connection information to DB used by MyBatis.
  4. logging.properties: JUL settings.

java:mybatis.logging.Main.java


package mybatis.logging;

import java.io.IOException;
import java.io.UncheckedIOException;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import mybatis.logging.repository.UsersRepository;

public class Main {
    public static void main(String[] args) {
        var builder = new SqlSessionFactoryBuilder();
        try (var in = Resources.getResourceAsStream("mybatis-config.xml")) {
            var factory = builder.build(in);
            try (var session = factory.openSession(true)) {
                var usersRepository = session.getMapper(UsersRepository.class);
                usersRepository.truncate();
                usersRepository.insert("1", "Alice");
                usersRepository.insert("2", "Bob");
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}

java:mybatis.logging.repository.UsersRepository.java


package mybatis.logging.repository;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;

public interface UsersRepository {
    
    @Insert("INSERT INTO users (id, name) VALUES (#{id}, #{name})")
    int insert(@Param("id") String id, @Param("name") String name);
    
    @Delete("DELETE FROM users")
    int truncate();
}

mybatis-config.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
  <environments default="dev">
    <environment id="dev">
      <transactionManager type="JDBC"></transactionManager>
      <dataSource type="POOLED">
        <property name="driver" value="org.postgresql.Driver"/>
        <property name="url" value="jdbc:postgresql://localhost:5432/dev"/>
        <property name="username" value="dev"/>
        <property name="password" value="password"/>
      </dataSource>
    </environment>
  </environments>
  
  <mappers>
    <mapper class="mybatis.logging.repository.UsersRepository" />
  </mappers>
</configuration>

logging.properties


# ROOT LOGGER
handlers = java.util.logging.ConsoleHandler
.level = INFO

# ConsoleHandler Default Setting
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

# MyBatis LOGGER
mybatis.logging.repository.level = FINE

The image of the placement information is shown below (Eclipse). image.png

Run

After that, set Java as Main class = mybatis.logging.Main and execute Java. At this time, specify the properties file for JUL in the VM option java.util.logging.config.file (logging.properties in the above example). The following is an example of setting VM options in ʻEclipse`. Please change this according to your environment.

image.png

result

If the following log is output to the standard output, it is successful. If you want to keep the log in a file etc., change the handler specification as appropriate.

April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: ==>  Preparing: DELETE FROM users 
April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: ==> Parameters: 
April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: <==    Updates: 2
April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: ==>  Preparing: INSERT INTO users (id, name) VALUES (?, ?) 
April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: ==> Parameters: 1(String), Alice(String)
April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: <==    Updates: 1
April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: ==>  Preparing: INSERT INTO users (id, name) VALUES (?, ?) 
April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: ==> Parameters: 2(String), Bob(String)
April 13, 2019 6:31:41 pm org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl debug
usually: <==    Updates: 1

reference

Recommended Posts

Use JUL to record the SQL execution log issued by MyBatis
[JAVA] [Spring] [MyBatis] Use GROUP BY in SQL Builder
How to dynamically change the column name acquired by MyBatis
How to use the link_to method
How to use the include? method
How to use the form_with method
How to use the wrapper class
How to use MyBatis Mapper annotation
ActiveRecord prints the SQL query that is actually issued to standard output