Mybaits的10種通用的寫法

用來循環(huán)容器的標簽forEach,查看例子

foreach元素的屬性主要有item,index钦听,collection洒试,open,separator朴上,close垒棋。

item:集合中元素迭代時的別名,

index:集合中元素迭代時的索引

open:常用語where語句中痪宰,表示以什么開始叼架,比如以'('開始

separator:表示在每次進行迭代時的分隔符,

close 常用語where語句中衣撬,表示以什么結束乖订,

在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的具练,但是在不同情況下乍构,該屬性的值是不一樣的,主要有一下3種情況:

如果傳入的是單參數(shù)且參數(shù)類型是一個List的時候扛点,collection屬性值為list .

如果傳入的是單參數(shù)且參數(shù)類型是一個array數(shù)組的時候哥遮,collection的屬性值為array .

如果傳入的參數(shù)是多個的時候,我們就需要把它們封裝成一個Map了陵究,當然單參數(shù)也可以封裝成map眠饮,實際上如果你在傳入?yún)?shù)的時候,在MyBatis里面也是會把它封裝成一個Map的铜邮,map的key就是參數(shù)名仪召,所以這個時候collection屬性值就是傳入的List或array對象在自己封裝的map里面的key.

針對最后一條,我們來看一下官方說法:

注意 你可以將一個 List 實例或者數(shù)組作為參數(shù)對象傳給 MyBatis松蒜,當你這么做的時候返咱,MyBatis 會自動將它包裝在一個 Map 中并以名稱為鍵。List 實例將會以“l(fā)ist”作為鍵牍鞠,而數(shù)組實例的鍵將是“array”咖摹。

所以,不管是多參數(shù)還是單參數(shù)的list,array類型难述,都可以封裝為map進行傳遞萤晴。如果傳遞的是一個List,則mybatis會封裝為一個list為key胁后,list值為object的map店读,如果是array,則封裝成一個array為key攀芯,array的值為object的map屯断,如果自己封裝呢,則colloection里放的是自己封裝的map里的key值

//mapper中我們要為這個方法傳遞的是一個容器,將容器中的元素一個一個的

//拼接到xml的方法中就要使用這個forEach這個標簽了

publicListqueryById(List<String>?userids);

//對應的xml中如下

select*?FROM?entity

whereidin

#{userid}

concat模糊查詢

//比如說我們想要進行條件查詢,但是幾個條件不是每次都要使用,那么我們就可以

//通過判斷是否拼接到sql中

SELECT?*fromentity

name?likeconcat('%',concat(#{name},'%'))

choose (when, otherwise)標簽

choose標簽是按順序判斷其內(nèi)部when標簽中的test條件出否成立,如果有一個成立殖演,則 choose 結束氧秘。當 choose 中所有 when 的條件都不滿則時,則執(zhí)行 otherwise 中的sql趴久。類似于Java 的 switch 語句丸相,choose 為 switch,when 為 case彼棍,otherwise 則為 default灭忠。

例如下面例子,同樣把所有可以限制的條件都寫上座硕,方面使用弛作。choose會從上到下選擇一個when標簽的test為true的sql執(zhí)行。安全考慮华匾,我們使用where將choose包起來映琳,放置關鍵字多于錯誤。

<!--??choose(判斷參數(shù))?-?按順序?qū)嶓w類?User?第一個不為空的屬性作為:where條件?-->

SELECT?*

FROM?User?u

u.username?LIKE?CONCAT(CONCAT('%',?#{username,?jdbcType=VARCHAR}),'%')

AND?u.sex?=?#{sex,?jdbcType=INTEGER}

AND?u.birthday?=?#{birthday,?jdbcType=DATE}

selectKey 標簽

在insert語句中瘦真,在Oracle經(jīng)常使用序列刊头、在MySQL中使用函數(shù)來自動生成插入表的主鍵,而且需要方法能返回這個生成主鍵诸尽。使用myBatis的selectKey標簽可以實現(xiàn)這個效果原杂。?

下面例子,使用mysql數(shù)據(jù)庫自定義函數(shù)nextval('student')您机,用來生成一個key穿肄,并把他設置到傳入的實體類中的studentId屬性上。所以在執(zhí)行完此方法后际看,邊可以通過這個實體類獲取生成的key咸产。

<!--?插入學生?自動主鍵-->

select?nextval('student')

INSERT?INTO?STUDENT_TBL(STUDENT_ID,

STUDENT_NAME,

STUDENT_SEX,

STUDENT_BIRTHDAY,

STUDENT_PHOTO,

CLASS_ID,

PLACE_ID)

VALUES?(#{studentId},

#{studentName},

#{studentSex},

#{studentBirthday},

#{studentPhoto,?javaType=byte[],?jdbcType=BLOB,?typeHandler=org.apache.ibatis.type.BlobTypeHandler},

#{classId},

#{placeId})

調(diào)用接口方法,和獲取自動生成key

StudentEntity?entity?=newStudentEntity();

entity.setStudentName("黎明你好");

entity.setStudentSex(1);

entity.setStudentBirthday(DateUtil.parse("1985-05-28"));

entity.setClassId("20000001");

entity.setPlaceId("70000001");

this.dynamicSqlMapper.createStudentAutoKey(entity);

System.out.println("新增學生ID:?"+?entity.getStudentId());

if標簽

if標簽可用在許多類型的sql語句中仲闽,我們以查詢?yōu)槔砸纭J紫瓤匆粋€很普通的查詢:

<!--?查詢學生list,like姓名?-->

SELECT?*?from?STUDENT_TBL?ST

WHERE?ST.STUDENT_NAME?LIKE?CONCAT(CONCAT('%',?#{studentName}),'%')

但是此時如果studentName為null赖欣,此語句很可能報錯或查詢結果為空屑彻。此時我們使用if動態(tài)sql語句先進行判斷,如果值為null或等于空字符串顶吮,我們就不進行此條件的判斷社牲,增加靈活性。

參數(shù)為實體類StudentEntity悴了。將實體類中所有的屬性均進行判斷搏恤,如果不為空則執(zhí)行判斷條件违寿。


SELECTST.STUDENT_ID,

ST.STUDENT_NAME,

ST.STUDENT_SEX,

ST.STUDENT_BIRTHDAY,

ST.STUDENT_PHOTO,

ST.CLASS_ID,

ST.PLACE_ID

FROMSTUDENT_TBL?ST

WHERE

ST.STUDENT_NAMELIKECONCAT(CONCAT('%',?#{studentName,?jdbcType=VARCHAR}),'%')??

ANDST.STUDENT_SEX?=#{studentSex,?jdbcType=INTEGER}??

ANDST.STUDENT_BIRTHDAY?=#{studentBirthday,?jdbcType=DATE}??

ANDST.CLASS_ID?=#{classId,?jdbcType=VARCHAR}??

ANDST.CLASS_ID?=#{classEntity.classId,?jdbcType=VARCHAR}??

ANDST.PLACE_ID?=#{placeId,?jdbcType=VARCHAR}??

ANDST.PLACE_ID?=#{placeEntity.placeId,?jdbcType=VARCHAR}??

ANDST.STUDENT_ID?=#{studentId,?jdbcType=VARCHAR}??

使用時比較靈活, new一個這樣的實體類熟空,我們需要限制那個條件藤巢,只需要附上相應的值就會where這個條件,相反不去賦值就可以不在where中判斷痛阻。

publicvoidselect_test_2_1(){

StudentEntity?entity?=newStudentEntity();

entity.setStudentName("");

entity.setStudentSex(1);

entity.setStudentBirthday(DateUtil.parse("1985-05-28"));

entity.setClassId("20000001");

//entity.setPlaceId("70000001");??

Listlist=this.dynamicSqlMapper.getStudentList_if(entity);

for(StudentEntity?e?:list)?{

System.out.println(e.toString());

}

}

if + where 的條件判斷

當where中的條件使用的if標簽較多時菌瘪,這樣的組合可能會導致錯誤腮敌。我們以在3.1中的查詢語句為例子阱当,當java代碼按如下方法調(diào)用時:

@Test

publicvoidselect_test_2_1()

{

StudentEntity?entity?=newStudentEntity();

entity.setStudentName(null);

entity.setStudentSex(1);

Listlist=this.dynamicSqlMapper.getStudentList_if(entity);

for(StudentEntity?e?:list)?{

System.out.println(e.toString());

}

}

如果上面例子,參數(shù)studentName為null糜工,將不會進行STUDENT_NAME列的判斷弊添,則會直接導“WHERE AND”關鍵字多余的錯誤SQL。?

這時我們可以使用where動態(tài)語句來解決捌木。這個“where”標簽會知道如果它包含的標簽中有返回值的話油坝,它就插入一個‘where’。此外刨裆,如果標簽返回的內(nèi)容是以AND 或OR 開頭的澈圈,則它會剔除掉。?

上面例子修改為:


SELECTST.STUDENT_ID,

ST.STUDENT_NAME,

ST.STUDENT_SEX,

ST.STUDENT_BIRTHDAY,

ST.STUDENT_PHOTO,

ST.CLASS_ID,

ST.PLACE_ID

FROMSTUDENT_TBL?ST

ST.STUDENT_NAMELIKECONCAT(CONCAT('%',?#{studentName,?jdbcType=VARCHAR}),'%')??

ANDST.STUDENT_SEX?=#{studentSex,?jdbcType=INTEGER}??

ANDST.STUDENT_BIRTHDAY?=#{studentBirthday,?jdbcType=DATE}??

ANDST.CLASS_ID?=#{classId,?jdbcType=VARCHAR}??

ANDST.CLASS_ID?=#{classEntity.classId,?jdbcType=VARCHAR}??

ANDST.PLACE_ID?=#{placeId,?jdbcType=VARCHAR}??

ANDST.PLACE_ID?=#{placeEntity.placeId,?jdbcType=VARCHAR}??

ANDST.STUDENT_ID?=#{studentId,?jdbcType=VARCHAR}??

if + set實現(xiàn)修改語句

當update語句中沒有使用if標簽時帆啃,如果有一個參數(shù)為null瞬女,都會導致錯誤。?

當在update語句中使用if標簽時努潘,如果前面的if沒有執(zhí)行诽偷,則或?qū)е露禾柖嘤噱e誤。使用set標簽可以將動態(tài)的配置SET 關鍵字疯坤,和剔除追加到條件末尾的任何不相關的逗號报慕。使用if+set標簽修改后,如果某項為null則不進行更新压怠,而是保持數(shù)據(jù)庫原值眠冈。如下示例:


UPDATE?STUDENT_TBL

STUDENT_TBL.STUDENT_NAME?=#{studentName},??

STUDENT_TBL.STUDENT_SEX?=#{studentSex},??

STUDENT_TBL.STUDENT_BIRTHDAY?=#{studentBirthday},??

STUDENT_TBL.STUDENT_PHOTO?=#{studentPhoto,?javaType=byte[],?jdbcType=BLOB,?typeHandler=org.apache.ibatis.type.BlobTypeHandler},??

STUDENT_TBL.CLASS_ID?=#{classId}??

STUDENT_TBL.PLACE_ID?=#{placeId}??

WHERE?STUDENT_TBL.STUDENT_ID?=#{studentId};??????

if + trim代替where/set標簽

trim是更靈活的去處多余關鍵字的標簽,他可以實踐where和set的效果菌瘫。

trim代替where


SELECTST.STUDENT_ID,

ST.STUDENT_NAME,

ST.STUDENT_SEX,

ST.STUDENT_BIRTHDAY,

ST.STUDENT_PHOTO,

ST.CLASS_ID,

ST.PLACE_ID

FROMSTUDENT_TBL?ST

ST.STUDENT_NAMELIKECONCAT(CONCAT('%',?#{studentName,?jdbcType=VARCHAR}),'%')??

ANDST.STUDENT_SEX?=#{studentSex,?jdbcType=INTEGER}??

ANDST.STUDENT_BIRTHDAY?=#{studentBirthday,?jdbcType=DATE}??

ANDST.CLASS_ID?=#{classId,?jdbcType=VARCHAR}??

ANDST.CLASS_ID?=#{classEntity.classId,?jdbcType=VARCHAR}??

ANDST.PLACE_ID?=#{placeId,?jdbcType=VARCHAR}??

ANDST.PLACE_ID?=#{placeEntity.placeId,?jdbcType=VARCHAR}??

ANDST.STUDENT_ID?=#{studentId,?jdbcType=VARCHAR}??

trim代替set


UPDATE?STUDENT_TBL

STUDENT_TBL.STUDENT_NAME?=#{studentName},??

STUDENT_TBL.STUDENT_SEX?=#{studentSex},??

STUDENT_TBL.STUDENT_BIRTHDAY?=#{studentBirthday},??

STUDENT_TBL.STUDENT_PHOTO?=#{studentPhoto,?javaType=byte[],?jdbcType=BLOB,?typeHandler=org.apache.ibatis.type.BlobTypeHandler},??

STUDENT_TBL.CLASS_ID?=#{classId},??

STUDENT_TBL.PLACE_ID?=#{placeId}??

WHERE?STUDENT_TBL.STUDENT_ID?=#{studentId}??

foreach

對于動態(tài)SQL 非常必須的蜗顽,主是要迭代一個集合,通常是用于IN 條件突梦。List 實例將使用“l(fā)ist”做為鍵诫舅,數(shù)組實例以“array” 做為鍵。

foreach元素是非常強大的宫患,它允許你指定一個集合刊懈,聲明集合項和索引變量,它們可以用在元素體內(nèi)。它也允許你指定開放和關閉的字符串虚汛,在迭代之間放置分隔符匾浪。這個元素是很智能的,它不會偶然地附加多余的分隔符卷哩。

注意:你可以傳遞一個List實例或者數(shù)組作為參數(shù)對象傳給MyBatis蛋辈。當你這么做的時候,MyBatis會自動將它包裝在一個Map中将谊,用名稱在作為鍵冷溶。List實例將會以“l(fā)ist”作為鍵,而數(shù)組實例將會以“array”作為鍵尊浓。

這個部分是對關于XML配置文件和XML映射文件的而討論的逞频。下一部分將詳細討論Java API,所以你可以得到你已經(jīng)創(chuàng)建的最有效的映射栋齿。

參數(shù)為array示例的寫法

接口的方法聲明:

publicListgetStudentListByClassIds_foreach_array(String[]?classIds);

動態(tài)SQL語句:


SELECT?ST.STUDENT_ID,

ST.STUDENT_NAME,

ST.STUDENT_SEX,

ST.STUDENT_BIRTHDAY,

ST.STUDENT_PHOTO,

ST.CLASS_ID,

ST.PLACE_ID

FROM?STUDENT_TBL?ST

WHERE?ST.CLASS_ID?IN

#{classIds}

測試代碼苗胀,查詢學生中,在20000001瓦堵、20000002這兩個班級的學生:

@Test

publicvoidtest7_foreach()

{

String[]?classIds?=?{"20000001","20000002"};

Listlist=this.dynamicSqlMapper.getStudentListByClassIds_foreach_array(classIds);

for(StudentEntity?e?:list)?{

System.out.println(e.toString());

}

}

2參數(shù)為list示例的寫法?

接口的方法聲明:

publicList?getStudentListByClassIds_foreach_list(List?classIdList);

動態(tài)SQL語句:

<!--?7.2?foreach(循環(huán)List<String>參數(shù))?-?作為where中in的條件?-->

SELECT?ST.STUDENT_ID,

ST.STUDENT_NAME,

ST.STUDENT_SEX,

ST.STUDENT_BIRTHDAY,

ST.STUDENT_PHOTO,

ST.CLASS_ID,

ST.PLACE_ID

FROM?STUDENT_TBL?ST

WHERE?ST.CLASS_ID?IN

#{classIdList}

測試代碼基协,查詢學生中,在20000001菇用、20000002這兩個班級的學生:

@Test

publicvoidtest7_2_foreach()

{

ArrayList?classIdList?=newArrayList();

classIdList.add("20000001");

classIdList.add("20000002");

List?list?=this.dynamicSqlMapper.getStudentListByClassIds_foreach_list(classIdList);

for(StudentEntity?e?:?list)?{

System.out.println(e.toString());

}

sql片段標簽:通過該標簽可定義能復用的sql語句片段澜驮,在執(zhí)行sql語句標簽中直接引用即可。這樣既可以提高編碼效率刨疼,還能有效簡化代碼泉唁,提高可讀性

需要配置的屬性:id="" >>>表示需要改sql語句片段的唯一標識

引用:通過標簽引用,refid="" 中的值指向需要引用的中的id=“”屬性

<!--定義sql片段-->

o.order_id,o.cid,o.address,o.create_date,o.orderitem_id,i.orderitem_id,i.product_id,i.count

select

<!--引用sql片段-->

from?ordertable?o

join?orderitem?i?on?o.orderitem_id?=?i.orderitem_id

where?o.order_id?=?#{orderId}

?

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末揩慕,一起剝皮案震驚了整個濱河市亭畜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌迎卤,老刑警劉巖拴鸵,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜗搔,居然都是意外死亡劲藐,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門樟凄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來聘芜,“玉大人,你說我怎么就攤上這事缝龄√郑” “怎么了挂谍?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瞎饲。 經(jīng)常有香客問我口叙,道長,這世上最難降的妖魔是什么嗅战? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任妄田,我火速辦了婚禮,結果婚禮上驮捍,老公的妹妹穿的比我還像新娘疟呐。我一直安慰自己,他們只是感情好厌漂,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布萨醒。 她就那樣靜靜地躺著斟珊,像睡著了一般苇倡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上囤踩,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天旨椒,我揣著相機與錄音,去河邊找鬼堵漱。 笑死综慎,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的勤庐。 我是一名探鬼主播示惊,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼愉镰!你這毒婦竟也來了米罚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤丈探,失蹤者是張志新(化名)和其女友劉穎录择,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碗降,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡隘竭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了讼渊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片动看。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖爪幻,靈堂內(nèi)的尸體忽然破棺而出菱皆,到底是詐尸還是另有隱情赋兵,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布搔预,位于F島的核電站霹期,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拯田。R本人自食惡果不足惜表蝙,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巧骚。 院中可真熱鬧个从,春花似錦、人聲如沸鸭轮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窃爷。三九已至邑蒋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間按厘,已是汗流浹背医吊。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留逮京,地道東北人卿堂。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像懒棉,于是被迫代替她去往敵國和親草描。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

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

  • 1. Java基礎部分 基礎部分的順序:基本語法策严,類相關的語法穗慕,內(nèi)部類的語法,繼承相關的語法享钞,異常的語法揍诽,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • MYSQL 基礎知識 1 MySQL數(shù)據(jù)庫概要 2 簡單MySQL環(huán)境 3 數(shù)據(jù)的存儲和獲取 4 MySQL基本操...
    Kingtester閱讀 7,787評論 5 116
  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,805評論 0 11
  • 先創(chuàng)建服務端的APP 1.官網(wǎng)下載Winrun4j狐肢。http://winrun4j.sourceforge.net...
    Alex_1799閱讀 1,697評論 1 2
  • 我們不是親人添吗,勝似親人,是這次騎行最大的感受份名。 原本是一起環(huán)過青海湖騎友的小聚碟联,因我實在想感受長途騎行的快樂妓美,厚著...
    appleye閱讀 493評論 0 1