2014-01-24 49 views
2

在保存或更新時可以看到hibenate generated sql。 現在我的要求是,我有一個已經持久的對象(實體)。 現在我想插入腳本的對象按dialect沒有手動生成。如何獲得一個hibernate實體的方言特定的sql?

有什麼可能嗎?

+0

我不知道(實際上我不認爲)Hibernate支持開箱即用。但是,難道你不能只使用你最喜歡的SQL工具並從那裏生成插入腳本? – Magnilex

回答

2

這有點棘手,但可能。

在休眠中,EntityPersister負責生成sql。但它從sql中抽象出來,所以沒有獲得sql的API方法。

儘管如此實現EntityPersister生成的SQL。但這裏也有一個問題:sql生成方法是protected

但我們仍然可以訪問它們。無論是通過反思,還是僅僅在同一個包中創建一個類。

所以我創建了一個名爲EntityPersisterAccess的類,與AbstractEntityPersister的包相同,但當然在我的項目中。 (基於Hibernate 3.6.7.Final例)

package org.hibernate.persister.entity; 

import org.hibernate.SessionFactory; 
import org.hibernate.engine.SessionFactoryImplementor; 

public class EntityPersisterAccess { 

    private SessionFactoryImplementor sessionFactoryImplementor; 

    public EntityPersisterAccess(SessionFactory sessionFactory) { 
     if (!(sessionFactory instanceof SessionFactoryImplementor)) { 
      throw new IllegalArgumentException(
        "EntityPersisterAccess only works with a " 
        + SessionFactoryImplementor.class); 
     } 
     this.sessionFactoryImplementor = (SessionFactoryImplementor) sessionFactory; 
    } 

    public String getInsertSql(Class<?> entityClass) { 
     return getInsertSql(entityClass.getCanonicalName()) 
    } 

    public String getInsertSql(String entityName) { 
     String insertSql = null; 
     EntityPersister ep = sessionFactoryImplementor.getEntityPersister(entityName); 
     if(entityPersister instanceof AbstractEntityPersister){ 
      AbstractEntityPersister aep = (AbstractEntityPersister) entityPersister; 
      boolean[] includeProperty = aep.getPropertyInsertability(); 
      insertSql = aep.generateInsertString(true, includeProperty); 
     } 
     return insertSql ; 
    } 
} 

你可以不是簡單地做這樣的事情在你的代碼

SessionFactory sessionFactory = ....; 
EntityPersisterAccess epa = new EntityPersisterAccess(sessionFactory); 
String insertSql = epa.getInsertSql(Person.class); // some entity class 
System.out.println(insertSql); 

在我的測試輸出

insert into PERSON (FIRSTNAME, LASTNAME, BIRTHDAY, ADDRESS_ID_FK, ID) values (?, ?, ?, ?, null) 

這種方法的好處EntityPersisterAccess完全封裝了使用它的客戶端代碼中的hibernate內部組件。因此,你「僅僅」必須改變這個類遷移到新的休眠版本時 - 希望:)

PS:可能有更多的考慮,並在EntityPersisterAccess實現,但這個例子應該是一個很好的起點點。

相關問題