hiberante QBC sqlProjection 别名问题

本文介绍了一种针对 Hibernate 中 SQLProjection 功能的扩展方法,通过自定义扩展解决了 SQLProjection 仅能引用顶级表别名的问题,实现了对关联表属性的灵活引用。

Projections.sqlProjection 允许我们使用SQL嵌入到当前的hql中。

但是所使用的语句中只提供当前表的别名引用,对于其它关联表就没办法制定属性了。

 

应用场景:

criteria.createAlias("Test", "f",DetachedCriteria.LEFT_JOIN);

prolist.add(Projections.sqlProjection("(decode({f}.state,null,{alias}.state,{f}.state)) as state", new String[]{"state"},new Type[]{ Hibernate.STRING}));

预计输出:

(decode(f1_.state,null,this_.state,f1_.state)) as state

 

实际输出:

(decode({f}state,null,this_.state,{f}.state)) as state

 

别名为什么是 f1_  而不是 f , 只是生成的别名规则。如果直接写上 f1_ 那就什么烦恼都没了。

 

求助了GG后,发现有人问,没人答。英文的倒是有几篇提到。果然烦恼什么的大家处理的都很彻底。

 

猜猜,(脑)补(脑)补,弄懂了大概的意思。

 

SQLProjection 确实只提供顶级的别名引用,但是可以通过自己的扩展实现其它别名引用.......。

好了,思路有了,就来实现吧。 点开  SQLProjection 的源码

    public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery)
        throws HibernateException
    {
        return StringHelper.replace(sql, "{alias}", criteriaQuery.getSQLAlias(criteria));
    }

意思简单明了,实现起来也简单。
这是我写的一个扩展。

  prolist.add(SQLProjectionExt.sqlProjection("(decode({f}.state,null,{alias}.state,{f}.state)) as state", new String[]{"state"}, Hibernate.STRING));
   输出成理想的语句了。

public class SQLProjectionExt extends SQLProjection{

	protected SQLProjectionExt(String sql, String[] columnAliases, Type[] types) {
		super(sql, columnAliases, types);	
		// TODO Auto-generated constructor stub
	}

	public static SQLProjection sqlProjection(String sql, String[] columnAliases, Type... types)
	{
		return new SQLProjectionExt(sql, columnAliases, types);
	}
	@Override
	public String toSqlString(Criteria criteria, int loc,
			CriteriaQuery criteriaQuery) throws HibernateException {
		// TODO Auto-generated method stub
		String sql = super.toSqlString(criteria, loc, criteriaQuery);
		Pattern p = Pattern.compile("\\{(\\w++)\\}");
		 Matcher m = p.matcher(sql);
		 StringBuffer sb = new StringBuffer();
		 while (m.find()) {
			 String s = m.group();
			 s = s.replace("{", "").replace("}", "")+".";
			m.appendReplacement(sb, criteriaQuery.getSQLAlias(criteria, s));
		 }
		 m.appendTail(sb);	
		return sb.toString();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值