hiberante QBC 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();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章