注解方式配置MyBatis執(zhí)行動(dòng)態(tài)SQL

作者:梁開權(quán)苫昌,叩丁狼高級(jí)講師沈自。

各位小伙伴們大家好,逍遙又跟大家見面了,在上次分享中給大家分享了如何通過注解的方式來操作MyBatis,也都僅僅局限于靜態(tài)SQL語(yǔ)句,這次給大家分享想如何通過注解的方式使用動(dòng)態(tài)SQL

準(zhǔn)備工作

事先建好表/domain/mapper/QueryObject

@Setter@Getter@ToString
public class Employee {
    private Long id; //代理主鍵
    private String name; //員工姓名
    private String age; //員工年齡
}

public interface EmployeeMapper {
    //查詢符合條件的總行數(shù)
    Integer selectForCount(EmployeeQueryObject qo);
    //查詢符合條件的對(duì)象
    List<?> selectForList(EmployeeQueryObject qo);
}

@Setter@Getter
public class EmployeeQueryObject {
    private int currentPage; //當(dāng)前頁(yè)
    private int pageSize; //頁(yè)面容量

    private String name; //員工姓名的模糊查詢
    private Integer minAge; //員工年齡的最小值范圍查詢
    private Integer maxAge; //員工年齡的最大值范圍查詢
     
    //取值前跳過的行數(shù)
    public int getStart() {
        return (currentPage - 1) * pageSize;
    }
}

方式1:

直接在mapper接口的方法中貼@Select注解在配置value屬性,該屬性中的SQL語(yǔ)句使用script標(biāo)簽包起來,表示里面使用了腳本語(yǔ)言

public interface EmployeeMapper {
    //查詢符合條件的總行數(shù)
    @Select("<script>" +
            "select count(0) from employee" +
            "<where>" +
                "<if test='name != null'>" +
                    "and name like concat('%', #{name}, '%')"+
                "</if>"+
                "<if test='minAge != null'>" +
                    "and age >= #{minAge}"+
                "</if>"+
                "<if test='maxAge != null'>" +
                    "and age <= #{maxAge}"+
                "</if>"+
            "</where>" +
            "</script>")
    Integer selectForCount(EmployeeQueryObject qo);
    
    //查詢符合條件的對(duì)象
    @Select("<script>" +
            "select id, name, age from employee" +
            "<where>" +
                "<if test='name != null'>" +
                    "and name like concat('%', #{name}, '%')"+
                "</if>"+
                "<if test='minAge != null'>" +
                    "and age >= #{minAge}"+
                "</if>"+
                "<if test='maxAge != null'>" +
                    "and age <= #{maxAge}"+
                "</if>"+
            "</where>" +
            "limit #{start}, #{pageSize}" +
            "</script>")
    List<?> selectForList(EmployeeQueryObject qo);
}

以上代碼中存在了大量的重復(fù)代碼,比如from語(yǔ)句和where的語(yǔ)句都是一樣的,此時(shí)是這種直接注解中寫SQL的方式是不能做抽取的,怎么辦?我們可以使用另外的一種方式,把生成SQL語(yǔ)句的代碼寫在某個(gè)類的某個(gè)方法中,再告訴框架找某個(gè)類的某個(gè)方法拿到SQL語(yǔ)句即可

方式2:

自己定義一個(gè)類,在類中設(shè)計(jì)兩個(gè)方法分別用于拿到selectForCount和selectForList的SQL語(yǔ)句,在此之前先介紹MyBatis的SQL對(duì)象,該對(duì)象用于生成最終的SQL語(yǔ)句


SQL對(duì)象

此時(shí)我們就可以通過自己動(dòng)手創(chuàng)建SQL對(duì)象,從而拿到我們要的SQL語(yǔ)句

//員工對(duì)象的SQL提供者
public class EmployeeSQLProvider {
    //拿到查詢總行數(shù)的SQL語(yǔ)句
    public String getCountSql(EmployeeQueryObject qo) {
        //創(chuàng)建SQL對(duì)象并設(shè)置select語(yǔ)句要查詢的列
        SQL sql = new SQL().SELECT("count(0)"); 
        addFrom(sql); //添加from語(yǔ)句
        addWhere(sql, qo); //添加where語(yǔ)句
        return sql.toString();
    }

    //拿到查詢集合對(duì)象的SQL語(yǔ)句
    public String getLimitSql(EmployeeQueryObject qo) {
        SQL sql = new SQL().SELECT("id, name, age");
        addFrom(sql);
        addWhere(sql, qo);
        return sql.toString();
    }

    //抽取拼接的from語(yǔ)句的方法
    private void addFrom(SQL sql) {
        sql.FROM("employee"); //往SQL對(duì)象中添加from語(yǔ)句
    }

    //抽取拼接的where語(yǔ)句的方法
    private void addWhere(SQL sql, EmployeeQueryObject qo) {
        //往SQL對(duì)象中動(dòng)態(tài)的添加添加
        if (StringUtils.hasLength(qo.getName())) {
            sql.WHERE("e.name like #{name}");
        }
        if (qo.getMinAge() != null) {
            sql.WHERE("e.age >= #{minAge}");
        }
        if (qo.getMaxAge() != null) {
            sql.WHERE("e.age <= #{maxAge}");
        }
    }
}

有了上面的哪個(gè)SQL提供者,我們就可以告訴框架找EmployeeSQLProvider對(duì)象中的方法來拿到SQL語(yǔ)句,所以我們?cè)趍apper接口的方法中使用注解@SelectProvider,并且告訴該注解找EmployeeSQLProvider類中的哪個(gè)方法拿SQL語(yǔ)句即可,所以方式2就變成一下的樣子

public interface EmployeeMapper {
    //type表示提供SQL的類,method表示該類中的哪個(gè)方法
    @SelectProvider(type= EmployeeSQLProvider.class, method="getCountSql")
    Integer selectForCount(EmployeeQueryObject qo);

    @SelectProvider(type= EmployeeSQLProvider.class, method="getLimitSql")
    List<?> selectForList(EmployeeQueryObject qo);
}

對(duì)比方式1大家應(yīng)該不難發(fā)現(xiàn)方式2在配置上的簡(jiǎn)潔性,把復(fù)雜的邏輯操作拿到了代碼中,同時(shí)也能抽取重復(fù)的代碼,相對(duì)來講方式2要更好些,大家學(xué)會(huì)了嗎?本期就先分享到這來,我們下期再會(huì)

WechatIMG9.jpeg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贷屎,一起剝皮案震驚了整個(gè)濱河市鳍烁,隨后出現(xiàn)的幾起案子蔚叨,更是在濱河造成了極大的恐慌载绿,老刑警劉巖粥诫,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異崭庸,居然都是意外死亡怀浆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門冀自,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揉稚,“玉大人,你說我怎么就攤上這事熬粗〔缶粒” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵驻呐,是天一觀的道長(zhǎng)灌诅。 經(jīng)常有香客問我,道長(zhǎng)含末,這世上最難降的妖魔是什么猜拾? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮佣盒,結(jié)果婚禮上挎袜,老公的妹妹穿的比我還像新娘。我一直安慰自己肥惭,他們只是感情好盯仪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜜葱,像睡著了一般全景。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牵囤,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天爸黄,我揣著相機(jī)與錄音,去河邊找鬼揭鳞。 笑死炕贵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的野崇。 我是一名探鬼主播鲁驶,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼舞骆!你這毒婦竟也來了钥弯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤督禽,失蹤者是張志新(化名)和其女友劉穎脆霎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狈惫,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡睛蛛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胧谈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忆肾。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖菱肖,靈堂內(nèi)的尸體忽然破棺而出客冈,到底是詐尸還是另有隱情,我是刑警寧澤稳强,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布场仲,位于F島的核電站,受9級(jí)特大地震影響退疫,放射性物質(zhì)發(fā)生泄漏渠缕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一褒繁、第九天 我趴在偏房一處隱蔽的房頂上張望亦鳞。 院中可真熱鬧,春花似錦棒坏、人聲如沸燕差。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谁不。三九已至,卻和暖如春徽诲,著一層夾襖步出監(jiān)牢的瞬間刹帕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工谎替, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留偷溺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓钱贯,卻偏偏與公主長(zhǎng)得像挫掏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秩命,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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

  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis 尉共? MyBatis 是支持定制化 SQL褒傅、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,520評(píng)論 0 4
  • 1 Mybatis入門 1.1 單獨(dú)使用jdbc編程問題總結(jié) 1.1.1 jdbc程序 上邊使...
    哇哈哈E閱讀 3,307評(píng)論 0 38
  • 相信很多女生殿托,青春年少時(shí),對(duì)另一半的擇偶要求剧蚣,都會(huì)說要找個(gè)靈魂伴侶 覺得這才是愛情的最高階段支竹,只有這樣的愛情才是真...
    三十而麗閱讀 675評(píng)論 2 8
  • 前陣子母親節(jié)剛過,又剛好我有好多的朋友跟同學(xué)已經(jīng)當(dāng)了年輕媽媽鸠按,我想分享一個(gè)小故事礼搁。 小時(shí)候我家有一臺(tái)小小的錄放音...
    d21f5576b168閱讀 337評(píng)論 0 1
  • ios11更新了。之前xcode9的bate版我也沒時(shí)間看目尖,知道今天要適配才發(fā)現(xiàn)問題來了纫谅。下午研究半天跪解。感覺這玩意...
    xiaoliang1閱讀 1,570評(píng)論 4 3