當我們使用傳統(tǒng)JDBC方法去寫復雜的SQL語句的時候,需要去進行大量的拼接。常常會因為一個小錯誤如少寫了一個空格導致錯誤,而且還很難找出錯誤的原因,Mybatis的動態(tài)SQL功能正是為了解決這些問題,通過if,choose,when,otherwise,trim,where,set,foreach,sql,include,bind標簽,組合成靈活的sql語句。動態(tài)SQL是Mybatis強大的特性之一,極大的簡化了拼接SQL的操作,Mybatis采用功能強大基于OGNL表達式來簡化操作。
- if 功能
簡單的條件判斷,利用 if 語句可以實現簡單的條件選擇、判斷拼接和否定忽略。
<resultMap type="cn.softjx.modle.User" id="UserMap">
<result column="t_id" property="id"/>
<result column="t_username" property="username"/>
<result column="t_password" property="password"/>
<result column="t_sid" property="sid"/>
<association property="school" javaType="cn.softjx.modle.School">
<result column="s_name" property="name" />
</association>
</resultMap>
<!-- 自定義條件查詢 -->
<select id="getStudent" resultMap="UserMap">
select *from t_user where 1=1
<if test="id!=null"><!-- if標簽內的字段名應與javabean內的字段名一致 -->
and t_id=#{id}
</if>
<if test="username!=null and username!=''">
and t_username=#{username}
</if>
<if test="password!=null and password!=''">
and t_password=#{password}
</if>
</select>
使用 if 標簽進行了動態(tài)SQL的拼接,需要注意的是 if 標簽內的條件判斷語句字段應該與javabean中定義的字段名一致,而不是數據庫中真實的字段名。
- where功能
where標簽語句的作用主要是簡化SQL語句中 where 中的條件判斷,where 元素的作用是在會寫入 where 元素的地方輸出一個 where,另外一個好處是不需要考慮 where 元素里面的條件輸出是什么樣子的,mybatis 會自動的幫我們處理,如果所有的條件都不滿足那么 mybatis 就會查詢出所有的記錄,如果輸出后是 and 開頭的,mybatis 會把第一個 and 忽略,如果是 or 開頭也會將其忽略。此外,在 where 元素中不需要考慮空格的問題,mybatis都會幫你自動的補充完善。
<select id="getStudent" resultMap="UserMap">
select *from t_user
<where>
<if test="id!=null"><!-- if標簽內的字段名應與javabean內的字段名一致 -->
and t_id=#{id}
</if>
<if test="username!=null and username!=''">
and t_username=#{username}
</if>
<if test="password!=null and password!=''">
and t_password=#{password}
</if>
</where>
</select>
- choose功能
choose 標簽的作用相當于java中的 switch 語句,通常都是與 when 和 otherwise 搭配使用,when 表示按照順序來判斷是否滿足條件。當 when 有條件滿足的時候就會跳出 choose,即所有的 when 和 otherwise 條件中只會有一個輸出,當所有條件都不滿足時,輸出 otherwise 中的內容。
<!-- choose自定義條件查詢 -->
<select id="getStudent1" resultMap="UserMap">
select *from t_user where 1=1
<choose>
<when test="id!=null"><!-- if標簽內的字段名應與javabean內的字段名一致 -->
and t_id=#{id}
</when>
<when test="username!=null and username!=''">
and t_username=#{username}
</when>
<otherwise>
and t_id=2
</otherwise>
</choose>
</select>
在 choose 標簽中,條件會按 when 的順序進行判斷,當有一個值為真時,就會跳出 choose 返回內容。
- set功能
<update id="updataUser">
update t_user
<set>
<if test="username!=null and username!=''">
t_username=#{username}
</if>
<if test="password!=null and password!=''">
,t_password=#{password}
</if>
<if test="sid!=null">
,t_sid=#{sid}
</if>
</set>
where t_id=#{id}
</update>
在set標簽中逗號是不能省略的,mybatis不會自動的把逗號補上造成SQL語句出錯。
- trim標簽時刻在自己包含的內容前加上某些前綴,也可以在其后加上后綴,與其對應的屬性是 prefix 和 suffix ;可以把包含的內容的首部某些內容覆蓋即忽略,也可以把尾部某些內容覆蓋,對應的屬性是 prefixOverrides 和 suffixOverrides。
<select id="getStudent3" resultMap="UserMap">
select *from t_user
<trim prefix="where" prefixOverrides='and | or' >
<if test="id!=null">
and t_id=#{id}
</if>
<if test="username!=null and username!=''">
and t_username=#{username}
</if>
<if test="password!=null and password!=''">
and t_password=#{password}
</if>
</trim>
</select>
使用 trim 標簽在 and 或 or 前加入 where 前綴,重復的 and 或 or 將其覆蓋不處理。如果在例子中三個 if 都為真,那么 sql 語句將會變?yōu)椋簊elect *from t_user where t_id=? and t_username=? and t_password=?
- foreach功能
foreach 的主要用在構建 in 條件中,它可以在SQL語句中迭代一個集合,foreach 的主要屬性有:item index open separator close collection。需要注意的是 collection,在不同的情況下該屬性的值是不一樣的如:List Array Map
<select id="getStudent2" resultMap="UserMap">
select * from t_user where t_id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
Test.java
@Test
public void getStudent2(){
try {
List<Integer> list=new ArrayList<Integer>();
list.add(2);
list.add(3);
list.add(4);
list.add(5);
List<User> ulist=mapper.getStudent2(list);
for(User users:ulist){
System.out.println(users.getPassword()+" "+users.getUsername());
}
} finally{
// TODO Auto-generated catch block
session.close();
}
}
- sql , include 功能
抽取可重用的SQL片段,方便后面引用:
- sql 抽取經常將要查詢的列名,或插入用的列名抽取出來方便引用。
- include 來引用已抽取的sql
<!-- sql與include標簽 -->
<sql id="Userfield">
(t_username,t_password,t_sid)
</sql>
<insert id="addUser">
insert into t_user
<include refid="Userfield"></include>
values
<foreach collection="list" item="user" separator=",">
(#{user.username},#{user.password},#{user.sid})
</foreach>
</insert>
使用標簽所拼接而成的 sql 語句:
insert into t_user (t_username,t_password,t_sid) values (?,?,?) , (?,?,?) , (?,?,?) , (?,?,?)
可以看到 include 標簽將我們抽取出來的 sql 語句填充了回去,使用 separate 以 "," 進行分割
Test.java
public void addUser(){
try {
User user1=new User();
user1.setPassword("19978878");
user1.setSid(2);
user1.setUsername("zcdfggad");
User user2=new User();
user2.setPassword("2013456");
user2.setSid(1);
user2.setUsername("oiuyiusa");
User user3=new User();
user3.setPassword("wqewqe878");
user3.setSid(2);
user3.setUsername("xczfdgsad");
User user4=new User();
user4.setPassword("qweqw8878");
user4.setSid(1);
user4.setUsername("32164897/");
List<User> ulist=new ArrayList<User>();
ulist.add(user1);
ulist.add(user2);
ulist.add(user3);
ulist.add(user4);
int tmp=mapper.addUser(ulist);
session.commit();
System.out.println(tmp);
} finally{
// TODO Auto-generated catch block
session.close();
}
}
- 8.bind 功能
使用 ONGL 表達式將變量進行綁定
<select id="getStudent3" resultMap="UserMap">
<!-- 綁定 uname 變量 值為 '%'+username+'%' -->
<bind name="uname" value="'%'+username+'%'"/>
select *from t_user where 1=1
<if test="id!=null">
and t_id=#{id}
</if>
<if test="username!=null and username!=''">
<!-- 將 bind 綁定的變量傳入 -->
and t_username like #{uname}
</if>
<if test="password!=null and password!=''">
and t_password=#{password}
</if>
</select>
Mybatis 動態(tài) SQL 非常靈活,當需要寫大量拼接語句使使用動態(tài) SQL 能大大的減少我們所需的工作量,合理的運用到項目中提升了開發(fā)效率。
上篇:Mybatis(二)返回值、表查詢
http://www.lxweimin.com/p/adf5ddc7247a