【问题标题】:How to get the JPA generated SQL query?如何获取 JPA 生成的 SQL 查询?
【发布时间】:2012-12-30 19:16:11
【问题描述】:

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

有没有办法做到这一点?

编辑

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

编辑 2

是否有一个实用程序可以提供一个 bean,它会自动生成一个插入查询?我可以在这里以某种方式使用 Hibernate bean 吗?我知道这是一个节拍复合体。

谢谢,

伊多布

【问题讨论】:

  • 编辑你的问题,不太清楚你问的是spring data jpa模块,spring可以在没有spring data的情况下使用jpa
  • 你找到解决办法了吗?
  • 看起来没有一个干净的解决方案。您也许可以通过参数将 EntityManager 传递给规范实现,然后使用此处找到的代码 antoniogoncalves.org/2012/05/24/…
  • @ido-barash 您是否获得了“我需要按原样获取 SQL 查询,并将其保存在普通字符串变量中”的解决方案。 ?如果是,请告诉我。
  • 没有。我放弃了

标签: jpa spring-data-jpa


【解决方案1】:

像这样创建一个 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。

【讨论】:

  • 酷。能够在我的控制台中看到 sql 语句 :)
  • 如果我还想查看参数值?
【解决方案2】:

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

【讨论】:

【解决方案3】:

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

这里已经描述过了:How to print a query string with parameter values when using Hibernate

【讨论】:

  • 这不是我问的!
  • 我需要将查询作为字符串获取以备后用。不在日志中查看。
【解决方案4】:

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

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

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

编辑:这里的查询是指本地查询,两个数据库的 HQL 查询是相同的。 希望对您有所帮助。

【讨论】:

    【解决方案5】:

    尝试在 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;
        }
    }
    

    【讨论】:

      【解决方案6】:

      我不知道生成的查询是什么意思,但是如果您使用 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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-31
        • 2012-11-14
        相关资源
        最近更新 更多