使用Hibernate的Criteria解決復(fù)雜查詢方案

大部分情況下衣式,我們通過Projections和Restrictions摇幻、Example即可實現(xiàn),如果想要使用Criteria實現(xiàn)復(fù)雜的查詢對Hibernate Criteria相關(guān)接口不熟悉不行,下面介紹幾個關(guān)鍵接口:
Projection接口:封裝分組和投影轉(zhuǎn)化sql操作
Criterion接口:封裝操作轉(zhuǎn)化sql操作
如果需要實現(xiàn)特別的分組或投影可以實現(xiàn)這接口Projection帆谍,或繼承實現(xiàn)該接口類的子類允睹。實現(xiàn)以某個日期屬性中的月份分組。

//使用方式:Projections.projectionList().add(new ByGroupPropertyProjection("屬性名", StaticsType.天)))
public class ByGroupPropertyProjection extends PropertyProjection {
private static final long serialVersionUID = 1L;
private StaticsType dateType; // 分組時間類型
private String propertyName;
/*
 * 作者:lzq 時間:2016年7月8日 修改記錄 修改者 時間 版本 說明
 */
/**
 * @param prop
 * @param grouped
 */
public ByGroupPropertyProjection(String prop, StaticsType dateType) {
    super(prop, true);
    // TODO Auto-generated constructor stub
    this.dateType = dateType;
    this.propertyName = prop;
}

/*
 * (非 Javadoc) 作者:lzq 時間:2016年7月8日 修改記錄修改者 時間 版本 說明
 * 
 * @see
 * org.hibernate.criterion.PropertyProjection#toGroupSqlString(org.hibernate
 * .Criteria, org.hibernate.criterion.CriteriaQuery)
 */
@Override
public String toGroupSqlString(Criteria criteria,
        CriteriaQuery criteriaQuery) throws HibernateException {
    // TODO Auto-generated method stub

    return groupSqlString(criteria, criteriaQuery);
}

/*
 * 作者:lzq 時間:2016年7月8日 修改記錄 修改者 時間 版本 說明
 */
/**
 * 分組sql
 * 
 * @param criteria
 * @param criteriaQuery
 * @return
 */
private String groupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
    String columns = StringHelper.join(", ",
            criteriaQuery.getColumns(propertyName, criteria));
    String result[] = columns.split(",");
    for (int i = 0; i < result.length; ++i) {
        result[i] = this.builderByGroups(result[i]);
    }
    return StringHelper.join(", ", result);
}

/*
 * 作者:lzq 時間:2016年7月8日 修改記錄 修改者 時間 版本 說明
 */
/**
 * 根據(jù)時間分組
 * 
 * @param columns
 *            列名
 * @return
 */
private String builderByGroups(String columns) {

    String groupSql = null;
    switch (dateType) {
    case 年:
        groupSql = "year(" + columns + ")";
        break;
    case 月:
        groupSql = "month(" + columns + ")";
        break;
    case 天:
        groupSql = "day(" + columns + ")";
        break;
    case 小時:
        groupSql = "hour(" + columns + ")";
        break;
    }
    return groupSql;
}
}
public enum StaticsType {小時,天,月,年}

在投影中是用month函數(shù)涩堤,例子如下:

//使用方式:Projections.projectionList().add(new MonthDateExtractPropertyProjection("屬性名"))
public class MonthDateExtractPropertyProjection extends
    AbstractDateExtractPropertyProjection {

private static final long serialVersionUID = 1L;

public MonthDateExtractPropertyProjection(String prop) {
    super(prop);
    // TODO Auto-generated constructor stub
}

protected String builderFunction(String columnName) {
    // TODO Auto-generated method stub
    return "MONTH(" + columnName + ")";
}} 

//抽象日期抽取類
public abstract class AbstractDateExtractPropertyProjection extends
    PropertyProjection {
private static final long serialVersionUID = 1L;
private String propertyName; // 屬性名
protected AbstractDateExtractPropertyProjection(String prop) {
    super(prop);
    // TODO Auto-generated constructor stub
    this.propertyName = prop;
}
public String toSqlString(Criteria criteria, int position,
        CriteriaQuery criteriaQuery) throws HibernateException {
    // TODO Auto-generated method stub
    StringBuilder buf = new StringBuilder();
    String[] cols = criteriaQuery.getColumns(propertyName, criteria); // 根據(jù)屬性名獲取對應(yīng)字段名
    for (int i = 0; i < cols.length; i++) {
        buf.append(builderFunction(cols[i])).append(" as y")
                .append(position + i).append('_');
        if (i < cols.length - 1)
            buf.append(", ");
    }
    return buf.toString();
}
public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
        throws HibernateException {
    // TODO Auto-generated method stub
    return new Type[] { StandardBasicTypes.INTEGER };
}

/*
 * 作者:lzq 時間:2016年7月9日 修改記錄 修改者 時間 版本 說明
 */
/**
 * 構(gòu)建方法
 * 
 * @param columnName
 *            列名
 * @return 包含方法參數(shù)的方法sql
 */
protected abstract String builderFunction(String columnName);
}

投影SUM中使用IFNULL函數(shù),例子如下:

/**
* 創(chuàng)建時間:2016年7月9日
* 作者:lzq
*/
package cn.webapp.youjifen.staticbasic.projection;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.AggregateProjection;
import org.hibernate.criterion.CriteriaQuery;

/*
 修改記錄
 修改者    時間    版本    說明
 */

/**
 * 重寫AggregateProjection類分瘾,使其支持IFNULL函數(shù)
 * 
 * @author lzq
 * @version v1.0
 * 
 */

public class AggregateProjectionSuportIfNull extends AggregateProjection {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    /*
     * 作者:lzq 時間:2016年7月9日 修改記錄 修改者 時間 版本 說明
     */
    /**
     * @param functionName
     * @param propertyName
     */
    protected AggregateProjectionSuportIfNull(String functionName,
            String propertyName) {
        super(functionName, propertyName);
        // TODO Auto-generated constructor stub
    }

    /*
     * (非 Javadoc) 作者:lzq 時間:2016年7月9日 修改記錄修改者 時間 版本 說明
     * 
     * @see
     * org.hibernate.criterion.AggregateProjection#toSqlString(org.hibernate
     * .Criteria, int, org.hibernate.criterion.CriteriaQuery)
     */
    @Override
    public String toSqlString(Criteria criteria, int loc,
            CriteriaQuery criteriaQuery) throws HibernateException {
        // TODO Auto-generated method stub
        final String functionFragment = getFunction(criteriaQuery).render(
                    criteriaQuery.getType(criteria, getPropertyName()),
                buildFunctionParameterList(criteria, criteriaQuery),
                criteriaQuery.getFactory());
        return "IFNULL(" + functionFragment + ",0) as y" + loc + '_';
    }

}
//使用方式
//Projections.projectionList().add(new SumAggregateProjectionSuportIfNull("屬性名"))
public class SumAggregateProjectionSuportIfNull extends
        AggregateProjectionSuportIfNull {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    /*
     * 作者:lzq 時間:2016年7月9日 修改記錄 修改者 時間 版本 說明
     */
    /**
     * @param functionName
     * @param propertyName
     */
    public SumAggregateProjectionSuportIfNull(String propertyName) {
        super("sum", propertyName);
        // TODO Auto-generated constructor stub
    }
}  
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胎围,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子德召,更是在濱河造成了極大的恐慌白魂,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件上岗,死亡現(xiàn)場離奇詭異福荸,居然都是意外死亡,警方通過查閱死者的電腦和手機肴掷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門敬锐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來背传,“玉大人,你說我怎么就攤上這事台夺【毒粒” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵颤介,是天一觀的道長梳星。 經(jīng)常有香客問我,道長滚朵,這世上最難降的妖魔是什么丰泊? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮始绍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘话侄。我一直安慰自己亏推,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布年堆。 她就那樣靜靜地躺著吞杭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪变丧。 梳的紋絲不亂的頭發(fā)上芽狗,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音痒蓬,去河邊找鬼童擎。 笑死,一個胖子當(dāng)著我的面吹牛攻晒,可吹牛的內(nèi)容都是我干的顾复。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鲁捏,長吁一口氣:“原來是場噩夢啊……” “哼芯砸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起给梅,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤假丧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后动羽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體包帚,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年曹质,在試婚紗的時候發(fā)現(xiàn)自己被綠了婴噩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擎场。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖几莽,靈堂內(nèi)的尸體忽然破棺而出迅办,到底是詐尸還是另有隱情,我是刑警寧澤章蚣,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布站欺,位于F島的核電站,受9級特大地震影響纤垂,放射性物質(zhì)發(fā)生泄漏矾策。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一峭沦、第九天 我趴在偏房一處隱蔽的房頂上張望贾虽。 院中可真熱鬧,春花似錦吼鱼、人聲如沸蓬豁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽地粪。三九已至,卻和暖如春琐谤,著一層夾襖步出監(jiān)牢的瞬間蟆技,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工斗忌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留质礼,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓飞蹂,卻偏偏與公主長得像几苍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子陈哑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容