You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot控制器中获取Java数据查询对应的Hibernate SQL语句?

实现Spring Boot接口获取Hibernate执行的SQL语句

下面提供几种实用的实现方式,根据你的场景选择:

方法1:通过Hibernate StatementInspector拦截并保存SQL

这是最直接的方式,可以在SQL执行时拦截并记录,后续在接口中返回:

  1. 自定义StatementInspector实现类:
import org.hibernate.resource.jdbc.spi.StatementInspector;

public class SqlCaptureInspector implements StatementInspector {
    private ThreadLocal<String> currentSql = new ThreadLocal<>();

    @Override
    public String inspect(String sql) {
        currentSql.set(sql);
        return sql;
    }

    public String getCurrentSql() {
        return currentSql.get();
    }

    public void clear() {
        currentSql.remove();
    }
}
  1. 在Spring Boot配置中注册这个Inspector:
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import javax.sql.DataSource;

@Configuration
public class HibernateConfig {
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, SqlCaptureInspector sqlInspector) {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("your.package.path");
        em.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        
        // 配置Hibernate属性,添加Inspector
        em.getJpaPropertyMap().put("hibernate.session_factory.statement_inspector", sqlInspector);
        
        return em;
    }

    @Bean
    public SqlCaptureInspector sqlCaptureInspector() {
        return new SqlCaptureInspector();
    }
}
  1. 在控制器/业务方法中获取SQL:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    private final EntityManagerService entityManagerService;
    private final SqlCaptureInspector sqlInspector;

    // 构造注入
    public UserController(EntityManagerService entityManagerService, SqlCaptureInspector sqlInspector) {
        this.entityManagerService = entityManagerService;
        this.sqlInspector = sqlInspector;
    }

    @GetMapping("/users")
    public UserResponse getUsers() {
        try {
            var users = entityManagerService.findTable("userTable").getRepository().findAllData();
            String executedSql = sqlInspector.getCurrentSql();
            // 组装包含数据和SQL的响应
            return new UserResponse(users, executedSql);
        } finally {
            // 清理ThreadLocal,避免内存泄漏
            sqlInspector.clear();
        }
    }
}

// 自定义响应类
class UserResponse {
    private List<User> users;
    private String executedSql;

    // 构造方法、getter/setter
    public UserResponse(List<User> users, String executedSql) {
        this.users = users;
        this.executedSql = executedSql;
    }

    // getter/setter省略
}

方法2:针对自定义Repository方法直接获取SQL

如果你的findAllData是自定义Repository方法,可以通过Hibernate的API直接生成并获取SQL:

假设你的Repository方法基于CriteriaQuery实现,可这样获取SQL:

// 在自定义Repository的findAllData方法中
public List<User> findAllData() {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<User> cq = cb.createQuery(User.class);
    Root<User> root = cq.from(User.class);
    cq.select(root);

    // 获取Hibernate的QueryImpl,进而获取SQL
    org.hibernate.query.Query<User> query = entityManager.createQuery(cq);
    String sql = query.unwrap(org.hibernate.query.Query.class).getQueryString();
    
    // 可以将SQL保存到ThreadLocal或者返回给上层
    sqlCaptureInspector.inspect(sql);
    
    return query.getResultList();
}

方法3:通过日志框架捕获SQL(适合调试或非实时场景)

如果只是需要获取SQL,也可以通过配置Hibernate日志,再将日志内容捕获到内存中供接口返回,但这种方式复杂度较高,仅推荐调试场景使用:

在application.properties中配置日志:

# 输出Hibernate生成的SQL
logging.level.org.hibernate.SQL=DEBUG
# 输出SQL参数(可选)
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

之后可以自定义日志Appender,将日志内容收集到内存中,在接口中读取。需注意处理日志过滤和线程隔离问题。


内容的提问来源于stack exchange,提问作者Diogo Alpendre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:16:13