我對這個問題頗爲詬病。
Hibernate使用org.hibernate.dialect.Dialect.SQLFunctionRegistry
來識別DB功能。
這裏是一個hibernate core 4.3.10的例子。 內部,它包含兩個私有字段:
/**
* Defines a registry for SQLFunction instances
*
* @author Steve Ebersole
*/
public class SQLFunctionRegistry {
private final Dialect dialect;
private final Map<String, SQLFunction> userFunctions;
第一個字段表示數據庫的方言。 其次包含可由org.hibernate.cfg.Configuration#addSqlFunction()
填充的用戶定義函數。
不幸的是,在通過hibernate源代碼搜索時,我發現在初始化hibernate時創建的配置對象沒有以任何方式公開。
但是,我設法訪問SQLFunctionRegistry。
一個需要創建類型的局部自動裝配Autowired場的EntityManagerFactory
@Autowired
private EntityManagerFactory emFactory;
後來調用下面的代碼:
private void registerMyDbFunctions()
{
SQLFunctionRegistry registry = this.emFactory.unwrap(org.hibernate.internal.SessionFactoryImpl.class).getSqlFunctionRegistry();
Field field = ReflectionUtils.findField(SQLFunctionRegistry.class, "userFunctions");
ReflectionUtils.makeAccessible(field);
Map<String, SQLFunction> userFunctions = (Map<String, SQLFunction>)ReflectionUtils.getField(field, registry);
userFunctions.put("my_func", new SQLFunctionTemplate(TextType.INSTANCE, "my_func(?1, ?2)"));
}
由於userFunctions
領域是私人的,在課堂上不外露,我用ReflectionUtils獲得它的價值。它通常是空的,我只是添加我的數據庫功能。
由於我不得不進入SqlFunctionRegistry
的內部,這是一種黑客攻擊,但我更喜歡創建新的DB方言並搞亂它。