18

我使用 JPA 规范和 Hibernate 作为我的供应商。我需要以某种方式获取发送到数据库的生成的 SQL 查询(打印到 sysout)并将其保存为一个简单的字符串。

有没有办法做到这一点?

编辑

让我更清楚一点:我不需要休眠日志。我需要能够在不同的数据库上执行相同的查询。因此,我需要按原样获取 SQL 查询,并将其保存在一个普通的 String 变量中。

编辑 2

有没有我可以提供一个 bean 的工具,它会自动生成一个插入查询?我可以在这里以某种方式使用 Hibernate bean 吗?我知道这是一个节拍情结。

谢谢,

伊多布

4

6 回答 6

17

像这样创建一个 bean。

@Bean
public JpaVendorAdapter jpaVendorAdapter(){
    HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
    jpaVendorAdapter.setGenerateDdl(true);
    jpaVendorAdapter.setShowSql(true);

    return jpaVendorAdapter;
}

如果您使用的是 Spring Boot,请将其添加到您的 @Configuration 中。

由此创建的日志可以在 MySQL 工作台中执行。您说您正在使用 JPA 和 Hibernate。除非您支持的数据库受 JPA 支持,否则别无他法。在这种情况下,您可以实现一个 AbstractJpaVendorAdapter。

于 2016-09-30T06:02:28.187 回答
2

对您的问题的简单回答是否定的。您想要做的是许多开发人员也想做的事情,但它不是 JPA 规范的一部分,因此获取生成的 SQL 的能力将取决于供应商决定什么做。使用 Hibernate 获取 SQL 的唯一方法是通过日志。

于 2014-07-11T19:34:28.580 回答
1

您必须启用 log4j 日志记录并为 Hibernate 添加一个附加程序以显示查询。

此处已对此进行了描述:How to print a query string with parameter values when using Hibernate

于 2013-01-16T12:54:53.937 回答
1

如果我理解正确,您希望获取 Hibernate 在一个数据库上执行的插入查询,并通过代码在不同的数据库上运行它entityManager#executeUpdate或类似。

Hibernate 不会公开生成的查询,因为它特定于目标数据库的方言。因此,即使要获得插入查询,也可能毫无意义。

但是,在您的情况下,您可以创建两个数据库连接(在您的情况下通过两个DataSourceEntityManagerFactory其他任何方式)并为两个数据库调用dao.persist(entity)两次,并让 Hibernate 处理查询构造部分。

编辑:这里的查询是指本地查询,两个数据库的 HQL 查询是相同的。希望能帮助到你。

于 2018-03-30T06:35:15.423 回答
0

我不知道生成的查询是什么意思,但如果你使用 Hibernate 并且你有javax.persistence.Query query你可以很容易地获得 HQL 字符串(对于 EclipseLink 它是相似的)。如果你有 HQL,你可以用 QueryTranslator 将它翻译成 SQL。

// Get HQL
String hqlQueryString = query.unwrap(org.hibernate.query.Query.class).getQueryString();

// Translate HQL to SQL
ASTQueryTranslatorFactory queryTranslatorFactory = new ASTQueryTranslatorFactory();
SessionImplementor hibernateSession = em.unwrap(SessionImplementor.class);
QueryTranslator queryTranslator = queryTranslatorFactory.createQueryTranslator("", hqlQueryString, Collections.emptyMap(), hibernateSession.getFactory(), null);
queryTranslator.compile(Collections.emptyMap(), false);
String sqlQueryString = queryTranslator.getSQLString();
于 2019-10-13T15:16:08.607 回答
0

尝试在 LocalContainerEntityManagerFactoryBean 实例中添加属性,它对我有用:-

@EnableJpaRepositories(basePackages = "org.common.persistence.dao")
public class PersistenceJPAConfig {

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[] { "org.common.persistence.model" });
        final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());
        return em;
    }

    final Properties additionalProperties() {
        final Properties hibernateProperties = new Properties();
        hibernateProperties.setProperty("showSql", "true");
        hibernateProperties.setProperty("hibernate.show_sql", "true");
        hibernateProperties.setProperty("hibernate.format_sql", "true");
        hibernateProperties.setProperty("hibernate.query.substitutions", "false");
        return hibernateProperties;
    }
}
于 2017-03-31T04:46:57.937 回答