我使用JPA规范和Hibernate作为我的供应商。我需要以某种方式将生成的SQL Query发送到DB(打印到sysout)并将其保存为一个简单的字符串。
有办法做到这一点吗?
修改
让我更清楚一点:我不需要休眠日志。我需要能够在不同的DB上执行相同的查询。因此,我需要按原样获取SQL查询,并将其保存在普通的String变量中。
修改2
是否有一个util,我可以为它提供一个bean,它会自动生成一个Insert查询?我能以某种方式在这里使用Hibernate bean吗?我知道这是一个节拍复杂。
谢谢,
Idob
答案 0 :(得分:13)
像这样创建一个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。
答案 1 :(得分:1)
您必须启用log4j日志记录并为Hibernate添加一个appender以显示查询。
这已在此处描述:How to print a query string with parameter values when using Hibernate
答案 2 :(得分:1)
你的问题的简单答案是否定的。你想要做的是许多开发人员也想做的事情,但它不是JPA规范的一部分,因此获得生成的SQL的能力将取决于供应商决定这样做。使用Hibernate获取SQL的唯一方法是通过日志。
答案 3 :(得分:1)
如果我理解正确,你想获得在一个数据库上执行Hibernate的插入查询,并通过代码,通过entityManager#executeUpdate
或类似的方式在另一个数据库上运行它。
Hibernate不公开生成的查询,因为它特定于目标数据库的方言。所以,即使要获得插入查询,也可能毫无意义。
但是在您的情况下,您可以创建两个数据库连接(通过两个DataSource
或EntityManagerFactory
无论如何)并为两个数据库调用dao.persist(entity)
两次,并让Hibernate处理查询构造部分。
编辑:通过查询我的意思是本地查询,两个数据库的HQL查询都是相同的。 希望它有所帮助。
答案 4 :(得分: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;
}
}
答案 5 :(得分: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();