1.什么是動態(tài)sql
mybatis核心,對sql語句進(jìn)行靈活操作胧谈,通過表達(dá)式進(jìn)行判斷悼凑,對sql進(jìn)行靈活拼接、組裝隙券。2.需求
用戶信息綜合查詢列表和用戶信息查詢列表總數(shù)這兩個(gè)statement的定義使用動態(tài)sql牙肝。
對查詢條件進(jìn)行判斷唉俗,如果輸入?yún)?shù)不為空才進(jìn)行查詢條件拼接。3.mapper.xml
原查詢語句配置:
<mapper namespace="cn.edu.hpu.mybatis.mapper.UserMapper">
<!-- 用戶信息綜合查詢
#{UserCustom.sex}取出包裝對象中性別值
${UserCustom.username}取得pojo包裝對象中用戶名稱
-->
<select id="findUserList" parameterType="cn.edu.hpu.mybatis.PO.UserQueryVo"
resultType="cn.edu.hpu.mybatis.PO.UserCustom">
select * from user where user.sex=#{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>
<!-- 用戶信息綜合查詢總數(shù) -->
<select id="findUserCount" parameterType="cn.edu.hpu.mybatis.PO.UserQueryVo" resultType="int">
select count(*) from user where user.sex=#{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>
......
</mapper>
修改后的查詢語句配置:
<!-- 用戶信息綜合查詢
#{UserCustom.sex}取出包裝對象中性別值
${UserCustom.username}取得pojo包裝對象中用戶名稱
-->
<select id="findUserList" parameterType="cn.edu.hpu.mybatis.PO.UserQueryVo"
resultType="cn.edu.hpu.mybatis.PO.UserCustom">
select * from user
<!-- where標(biāo)簽可以自動去掉第一個(gè)and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and user.username like '%${userCustom.username}%'
</if>
</if>
</where>
</select>
<!-- 用戶信息綜合查詢總數(shù) -->
<select id="findUserCount" parameterType="cn.edu.hpu.mybatis.PO.UserQueryVo" resultType="int">
select count(*) from user
<!-- where標(biāo)簽可以自動去掉第一個(gè)and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and 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 testFindUserList() throws Exception{
SqlSession sqlSession=sqlSessionFactory.openSession();
//創(chuàng)建UserMapper代理對象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//創(chuàng)建包裝對象配椭,設(shè)置查詢條件
UserQueryVo userQueryVo=new UserQueryVo();
UserCustom userCustom=new UserCustom();
//由于這里使用動態(tài)sql虫溜,如果這里不設(shè)置某個(gè)值,條件不會拼接在sql中
//userCustom.setSex("男");
userCustom.setUsername("張三");
userQueryVo.setUserCustom(userCustom);
//調(diào)用userMapper的方法
List<UserCustom> users=userMapper.findUserList(userQueryVo);
for (int i = 0; i < users.size(); i++) {
UserCustom user=(UserCustom)users.get(i);
System.out.println(user.getId()+":"+user.getUsername());
}
}
測試結(jié)果:
1:張三
4:張三豐
輸出日志:
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 31761534.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@1e4a47e]
DEBUG [main] - ==> Preparing: select * from user WHERE user.username like '%張三%'
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 2
發(fā)現(xiàn)sql語句為select * from user WHERE user.username like '%張三%' 股缸,并沒有將sex拼接進(jìn)去衡楞,說明我們的動態(tài)sql設(shè)置成功
相應(yīng)的,把userCustom.setUsername("張三");也注釋掉敦姻,發(fā)現(xiàn)輸出日志:
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 24027753.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@16ea269]
DEBUG [main] - ==> Preparing: select * from user
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 5
發(fā)現(xiàn)sql語句為select * from user瘾境,并沒有將sex和username拼接進(jìn)去,說明我們的動態(tài)sql設(shè)置成功
5.sql片段
5.1需求
將上邊實(shí)現(xiàn)的動態(tài)sql判斷代碼塊抽取出來镰惦,組成一個(gè)sql片段迷守。其它的statement中就可以引用sql片段。
方便程序員進(jìn)行開發(fā)旺入。
5.2定義sql片段
<mapper namespace="cn.edu.hpu.mybatis.mapper.UserMapper">
<!-- 定義sql片段
id:sql片段的唯一標(biāo)識
在sql片段中不要加入where
經(jīng)驗(yàn):一般我們定義sql片段是為了可重用性兑凿,是基于單表來定義sql片段,
這樣的話這個(gè)sql片段可重用性才高-->
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and user.username like '%${userCustom.username}%'
</if>
</if>
</sql>
......
</mapper>
5.3引用sql片段
在mapper.xml中定義的statement中引用sql片段
<!-- 用戶信息綜合查詢
#{UserCustom.sex}取出包裝對象中性別值
${UserCustom.username}取得pojo包裝對象中用戶名稱
-->
<select id="findUserList" parameterType="cn.edu.hpu.mybatis.PO.UserQueryVo"
resultType="cn.edu.hpu.mybatis.PO.UserCustom">
select * from user
<!-- where標(biāo)簽可以自動去掉第一個(gè)and -->
<where>
<!-- 應(yīng)用sql片段的id茵瘾,如果refid指定的id不再本mapper文件中礼华,需要前邊加namespace -->
<include refid="query_user_where"></include>
<!-- 在這里還可能要引用其他的sql片段 -->
</where>
</select>
<!-- 用戶信息綜合查詢總數(shù) -->
<select id="findUserCount" parameterType="cn.edu.hpu.mybatis.PO.UserQueryVo" resultType="int">
select count(*) from user
<!-- where標(biāo)簽可以自動去掉第一個(gè)and -->
<where>
<!-- 應(yīng)用sql片段的id,如果refid指定的id不再本mapper文件中拗秘,需要前邊加namespace -->
<include refid="query_user_where"></include>
<!-- 在這里還可能要引用其他的sql片段 -->
</where>
</select>
測試:
//用戶信息綜合查詢
@Test
public void testFindUserList() throws Exception{
SqlSession sqlSession=sqlSessionFactory.openSession();
//創(chuàng)建UserMapper代理對象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//創(chuàng)建包裝對象卓嫂,設(shè)置查詢條件
UserQueryVo userQueryVo=new UserQueryVo();
UserCustom userCustom=new UserCustom();
//由于這里使用動態(tài)sql,如果這里不設(shè)置某個(gè)值聘殖,條件不會拼接在sql中
userCustom.setSex("男");
userCustom.setUsername("張三");
userQueryVo.setUserCustom(userCustom);
//調(diào)用userMapper的方法
List<UserCustom> users=userMapper.findUserList(userQueryVo);
for (int i = 0; i < users.size(); i++) {
UserCustom user=(UserCustom)users.get(i);
System.out.println(user.getId()+":"+user.getUsername());
}
}
測試結(jié)果:
1:張三
4:張三豐
輸出日志:
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 17689439.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@10deb5f]
DEBUG [main] - ==> Preparing: select * from user
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 5
說明sql片段引用成功
小結(jié):
sql片段方便程序員進(jìn)行開發(fā)