web-dev-qa-db-ja.com

JPAで生成されたSQLクエリを取得する方法

私はJPA仕様とHibernateをベンダーとして使用しています。 DBに送信される(sysoutに出力される)生成されたSQLクエリを何らかの方法で取得し、単純な文字列として保存する必要があります。

これを行う方法はありますか?

[〜#〜]編集[〜#〜]

ビートを明確にしましょう。休止状態のログは必要ありません。別のDBで同じクエリを実行できるようにする必要があります。したがって、SQLクエリをそのまま取得し、通常の文字列変数に保持する必要があります。

編集2

Beanを提供できるユーティリティはありますか?それは自動的に挿入クエリを生成しますか?ここでHibernate Beanをどうにかして使用できますか?ビートコンプレックスだと知っています。

おかげで、

イドブ

15
Ido Barash

このような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があります。

私が正しく理解している場合、Hibernateが1つのデータベースで実行される挿入クエリを取得し、コードを使用して、_entityManager#executeUpdate_または同様の方法で別のデータベースで実行する必要があります。

Hibernateはターゲットデータベースの方言に固有であるため、生成されたクエリを公開しません。したがって、挿入クエリを取得したとしても、それは無意味になる可能性があります。

ただし、あなたのケースでは、2つのデータベース接続を作成し(2つのDataSourceまたはEntityManagerFactoryを介して)、両方のデータベースに対してdao.persist(entity)を2回呼び出し、Hibernateにクエリ構築部分を処理します。

編集:クエリとは、ここではネイティブクエリを意味し、HQLクエリは両方のデータベースで同じになります。それが役に立てば幸い。

1
Archit

あなたの質問に対する単純な答えは「いいえ」です。あなたがやりたいことは、多くの開発者もしたいことですが、JPA仕様の一部ではなかったため、生成されたSQLを取得できるかどうかは、ベンダーが何を決定したかによって異なります。行う。 Hibernateを使用してSQLを取得する唯一の方法は、ログを使用することです。

1
Scott Gustafson

クエリを表示するには、log4jロギングを有効にし、Hibernateのアペンダーを追加する必要があります。

これはすでにここで説明されています: Hibernateを使用するときにパラメーター値を含むクエリ文字列を出力する方法

1
ioan

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;
    }
}

生成されたクエリの意味はわかりませんが、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();
0
Saljack