1 .什麼是動態sql
mybatis核心 對sql語句進行靈活操作,通過表達式進行判斷,對sql進行靈活拼接、組裝。
2. 需求
用戶信息綜合查詢列表和用戶信息查詢列表總數這兩個statement的定義使用動態sql。
對查詢條件進行判斷,如果輸入參數不爲空才進行查詢條件拼接。
3. mapper.xml
<!--多條件查詢用戶信息 -->
<select id="findUserList" parameterType="com.ren.mybatis.po.UserQueryVo" resultType="com.ren.mybatis.po.UserCustom">
select * from user
<where>
<include refid="query_user_where"></include>
</where>
</select>
<!--查詢總記錄條數 -->
<select id="findTotalCount" parameterType="com.ren.mybatis.po.UserQueryVo" resultType="int">
select count(*) from user
<where>
<if test="userCustom != null">
<if test="userCustom.sex != null and userCustom.username != ''">
user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username != null and userCustom.username != ''">
and user.username like '%${userCustom.username}%'
</if>
</if>
</where>
</select>
4. 測試代碼
//查詢總記錄條數
@Test
public void testfindCount() throws Exception
{
SqlSession sqlSession = sqlSessionFactory.openSession();
//得到Mapper接口的代理類對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserCustom userCustom = new UserCustom();
UserQueryVo userQueryVo = new UserQueryVo();
userCustom.setSex("1");
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
int totalCount = userMapper.findTotalCount(userQueryVo);
System.out.println(totalCount);
}
5. sql片段
將上邊實現的動態sql判斷代碼塊抽取出來,組成一個sql片段。其它的statement中就可以引用sql片段。方便程序員進行開發。
(1)定義sql片段
<!--定義sql片段 -->
<!--id是sql片段的唯一標識;一般基於單表定義,靈活;一般不包含where條件 -->
<sql id="query_user_where">
<if test="userCustom != null">
<if test="userCustom.sex != null and userCustom.username != ''">
user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username != null and userCustom.username != ''">
and user.username like '%${userCustom.username}%'
</if>
</if>
</sql>
(2) 引用sql片段
在mapper.xml中定義的statement中引用sql片段:
<include refid="query_user_where"></include>
6. foreach
向sql傳遞數組或List,mybatis使用foreach解析;
(1) 需求
在用戶查詢列表和查詢總數的statement中增加多個id輸入查詢。
sql語句如下:
兩種方法:
SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
SELECT * FROM USER WHERE id IN(1,10,16)
(2)在輸入參數類型中添加List<Integer> ids傳入多個id
package com.ren.mybatis.po;
import java.util.List;
/**
* POJO的包裝類型:
* 用於包裝所需要的查詢條件:
* @author 任志燕
* 2017年4月19日
*
*/
public class UserQueryVo {
//用戶查詢條件
private UserCustom userCustom;
//包含其他的查詢條件:訂單、商品..
private List ids;//定義一個查詢id集合,用於如果查詢id在某一個範圍內時使用
public void setIds(List ids) {
this.ids = ids;
}
public List getIds() {
return ids;
}
public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
}
public UserCustom getUserCustom() {
return userCustom;
}
}
(3) 修改mapper.xml: WHERE id=1 OR id=10 OR id=16:在查詢條件中,查詢條件定義成一個sql片段,需要修改sql片段。
<!--
forech的使用:用於遍歷接受的list類型的參數:(userQueryVo中的ids屬性)
collection:是指定輸入對象中集合屬性的名字即ids
open:指定開始遍歷時拼接串(即你要拼接的sql語句的開始字符串)你可以先寫出你要拼接的sql語句串來判斷開始字符串和結束字符串
close:指定結束遍歷時拼接串(即你要拼接的sql語句的結束字符串)
item:每次遍歷時生成的對象(自己起名)
separator:寫遍歷的兩個對象之間需要拼接的字符串
-->
<!--
目的:如果爲了實現拼接sql語句:and (id=16 or id =22 or id = 42)
注意:多寫and連接符也不怕,因爲使用where標籤會將sql語句中多餘的and去掉
-->
<!-- <if test="ids != null">
<foreach collection="ids" item="item_id" open="and (" close=")" separator="or">
這裏寫每次遍歷需要拼接的內容
id =#{item_id}
</foreach>
</if> -->
<!--
目的:如果爲了實現拼接sql語句:and id in (16,22,42)
注意:多寫and連接符也不怕,因爲使用where標籤會將sql語句中多餘的and去掉
-->
<if test="ids != null">
<foreach collection="ids" item="item_id" open="and id in(" close=")" separator=",">
<!--每個遍歷需要拼接的字符串 -->
#{item_id}
</foreach>
</if>
(4)測試代碼:
//多條件查詢:使用POJO包裝模型
@Test
public void testfindUserList() throws Exception
{
SqlSession sqlSession = sqlSessionFactory.openSession();
//得到Mapper接口的代理類對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserCustom userCustom = new UserCustom();
UserQueryVo userQueryVo = new UserQueryVo();
userCustom.setSex("1");
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
List<Integer>ids = new ArrayList<>();
ids.add(16);
ids.add(22);
ids.add(42);
userQueryVo.setIds(ids);
List<UserCustom> list = userMapper.findUserList(userQueryVo);
for (UserCustom userCustom2 : list) {
System.out.println(userCustom2.getUsername());
}
}