Spring Boot中记录JDBC、JPA及MyBatis执行SQL及参数的正确姿势

开发 前端
本文将介绍在Spring Boot中使用JDBC、JPA及MyBatis进行数据库操作时记录执行的SQL语句。这些方法包括配置日志级别以捕获SQL输出、自定义数据源输出SQL语句,以及使用第三方库来增强SQL记录的功能。

环境:SpringBoot3.4.0


1. 简介

在Spring Boot应用开发中,监控和记录SQL执行语句对于调试、性能优化以及确保数据访问层的正确性至关重要。无论是使用JDBC直接操作数据库,还是通过JPA或MyBatis等ORM框架,他们都有不同的SQL语句的记录方式。

本文将介绍在Spring Boot中使用JDBC、JPA及MyBatis进行数据库操作时记录执行的SQL语句。这些方法包括配置日志级别以捕获SQL输出、自定义数据源输出SQL语句,以及使用第三方库来增强SQL记录的功能。

2. 实战案例

2.1 JDBC记录SQL

如下数据库操作:

private final JdbcTemplate jdbcTemplate ;
public JdbcService(JdbcTemplate jdbcTemplate) {
  this.jdbcTemplate = jdbcTemplate;
}
  
public void query() {
  String sql = "select id, name, age from user x where x.id = ?" ;
  User user = this.jdbcTemplate.queryForObject(sql, new RowMapper<User>() {
    public User mapRow(ResultSet rs, int rowNum) throws SQLException {
      return new User(rs.getLong(1), rs.getString(2), rs.getString(3)) ;
    }
  }, 8) ;
  System.err.printf("user = %s\n", user) ;
}

默认情况下,执行上面操作是不会输出任何SQL语句的,我们可以通过如下的配置:

logging:
  level:
    '[org.springframework.jdbc.core.JdbcTemplate]': debug

图片图片

如果你还希望输出动态参数,则再添加如下日志配置:

logging:
  level:
    '[org.springframework.jdbc.core.StatementCreatorUtils]': trace

图片图片

2.2 JPA记录SQL

如下数据库操作:

private final UserRepository userRepository ;
public UserService(UserRepository userRepository) {
  this.userRepository = userRepository;
}
public User findById(Long id) {
  return this.userRepository.findById(id).orElse(null) ;
}

最常见的输出执行SQL方式

spring:
  jpa:
    show-sql: true
    properties:
      hibernate:
        '[format_sql]': true

图片图片

但是此种方式是直接通过System.out方式进行输出,并且还不会记录预处理语句的参数;不推荐此做法。

使用日志框架记录

在application.yml或properties中进行日志的配置:

logging:
  level:
    '[org.hibernate.SQL]': debug
    '[org.hibernate.orm.jdbc.bind]': trace

org.hibernate.SQL:记录执行的SQL。

org.hibernate.orm.jdbc.bind:记录预处理语句的参数。

图片图片

2.3 MyBatis记录SQL

如下数据库操作:

@Select("select id, age, name, deleted from user where id = ${id}")
User queryUserById(@Param("id") Long id) ;

注意:${xx}有注入风险?我重写了mybatis处理SQL的一个核心类,不再有任何注入风险

比较常见的配置日志方式

mybatis:
  configuration: 
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

如上配置日志输出结果如下:

图片图片

不仅仅输出的是sql还将数据也输出了,并且这里是通过System.out进行输出的,并且还不管你是否配置的debug级别都会进行输出,下面是源码部分:

图片图片

使用SLF4j日志实现

mybatis:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl

如上配置后并不会输出sql日志,还需要进行如下的配置:

logging:
  level:
    '[com.pack.mapper]': DEBUG

图片

2.4 万能SQL记录方式

使用拦截器是记录各种SQL查询的最佳方法。在这种方法中,我们可以拦截JDBC调用,对其进行格式化,然后以自定义格式记录SQL查询。

下面介绍一个第三方开源库datasource-proxy,该组件用于拦截SQL查询并记录。

<dependency>
  <groupId>com.github.gavlyukovskiy</groupId>
  <artifactId>datasource-proxy-spring-boot-starter</artifactId>
  <version>1.10.0</version>
</dependency>

日志级别配置如下:

logging:
  level:
    '[net.ttddyy.dsproxy.listener]': debug

这时候不论你使用JDBC,JPA还是MyBatis都能优雅的记录SQL信息。

图片图片

责任编辑:武晓燕 来源: Spring全家桶实战案例源码
相关推荐

2021-09-15 16:20:02

Spring BootFilterJava

2025-02-12 08:07:40

2024-08-12 10:13:01

2024-08-01 09:10:03

2024-12-06 10:43:27

2020-06-18 08:18:35

密码加密安全

2022-04-28 08:05:05

数据库数据库交互

2019-10-18 10:43:11

JPASpring Boot Flyway

2024-10-07 08:40:56

Spring应用程序Java

2023-03-13 07:35:44

MyBatis分库分表

2024-08-02 09:15:22

Spring捕捉格式

2020-08-05 08:30:25

Spring BootJavaSE代码

2023-10-18 08:12:34

Spring自动配置

2022-11-10 07:53:54

Spring参数校验

2023-11-03 07:58:54

CORSSpring

2018-01-11 15:31:39

命令Linux关机

2017-02-23 15:37:44

OptionObject容器

2016-05-09 10:41:03

算法分析开发

2010-06-17 15:33:16

SQL Server

2024-09-26 08:03:37

点赞
收藏

51CTO技术栈公众号