介绍
我有一个奇怪的任务 - 对Hibernate的标准API(即数据库独立的风格)SQL查询类似写
select * from branch b where '2/5/3/' like b.hier_path + '%'
其中+
是连接运算符。 置运算符取决于数据库“+”在MS SQL,“||” 在甲骨文等。
我必须使用标准的API(没办法切换到HQL)。
问题1 -像运营商
不幸的是,休眠允许只写基于Java对象的属性标准:
pCriteria.createCriteria(Branch.class).add(Restrictions.like("hierarchyPath", "2/5/3/%"));
这相当于中
select * from branch where 'hier_path like 2/5/3/%'
我不知道怎么样换运营商的操作数。
问题2 -独立于数据库级联
在SQL代码必须工作在Oracle,MS SQL服务器,DB2,Postgres的中,Sybase,MySQL和HSQLDB,火鸟(和其他一些新的关系型数据库)。
我已经得到了,现在是一个基于SQL黑客:
Restrictions.sqlRestriction("? like concat({alias}.hier_path,'%')", "2/5/3/", Hibernate.STRING)
不幸的是, concat
是存在于大多数从上述数据库(除外的Postgres和火鸟) 数据库相关函数。 该方法是一种解决方法,不能(我会尝试添加自定义函数作为常数解决方案concat
到没有它的数据库)。
结论
任何人可以提出一个改进我的黑客(数据库独立SQL)或修正原有CriteriaAPI?
更新12年9月28日
concat
功能出现在9.1 Postgres的
你可以写你自己的标准执行,这会产生类似于你在你的问题有一个SQL子句,除非它会使用与标准相关联的方言查询,以获得相应的concat函数,并委托级联到这个数据库依赖concat函数。
由于@JB Nizet。 代码被他的思想的启发:
private class InverseLikeExpression extends SimpleExpression{
private static final String CONST_HQL_FUNCTION_NAME_CONCAT = "concat";
private static final String CONST_LIKE = " like ";
private static final String CONST_LIKE_SUFFIX = "'%'";
private final String propertyName;
protected InverseLikeExpression(String pPropertyName, Object pValue) {
super(pPropertyName, pValue, CONST_LIKE);
propertyName = pPropertyName;
}
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
Dialect dialect = criteriaQuery.getFactory().getDialect();
SQLFunction concatFunction = (SQLFunction) dialect.getFunctions().get(CONST_HQL_FUNCTION_NAME_CONCAT);
StringBuffer fragment = new StringBuffer();
if (columns.length>1) fragment.append('(');
for ( int i=0; i<columns.length; i++ ) {
String fieldName = concatFunction.render(Arrays.asList(new Object[] {columns[i], CONST_LIKE_SUFFIX}), criteriaQuery.getFactory());
fragment.append("?").append( getOp() ).append(fieldName);
if ( i<columns.length-1 ) fragment.append(" and ");
}
if (columns.length>1) fragment.append(')');
return fragment.toString();
}
}
文章来源: Hibernate CriteriaAPI and like operator. Swap operands + database independent concatenation - is it possible?