動(dòng)態(tài)SQL

通過mybatis提供的各種標(biāo)簽方法實(shí)現(xiàn)動(dòng)態(tài)拼接sql。
需求:根據(jù)性別和名字查詢用戶
查詢sql:
SELECT id, username, birthday, sex, address FROM user WHERE sex = 1 AND username LIKE '%張%'
UserMapper.xml配置sql,如下:

<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM user
WHERE sex = #{sex} AND username LIKE
'%${username}%'
</select>
編寫Mapper接口,如下圖:

image.png

在UserMapperTest添加測(cè)試方法,如下:
Test
public void testQueryUserByWhere() {
// mybatis和spring整合,整合之后,交給spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 創(chuàng)建Mapper接口的動(dòng)態(tài)代理對(duì)象,整合之后,交給spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 使用userMapper執(zhí)行根據(jù)條件查詢用戶
User user = new User();
user.setSex("1");
user.setUsername("張");

List<User> list = userMapper.queryUserByWhere(user);

for (User u : list) {
    System.out.println(u);
}

// mybatis和spring整合,整合之后,交給spring管理
sqlSession.close();

}
測(cè)試效果如下圖:


image.png

如果注釋掉 user.setSex("1"),測(cè)試結(jié)果如下圖:


image.png

測(cè)試結(jié)果二很顯然不合理。
按照之前所學(xué)的,要解決這個(gè)問題,需要編寫多個(gè)sql,查詢條件越多,需要編寫的sql就更多了,顯然這樣是不靠譜的。
解決方案,使用動(dòng)態(tài)sql的if標(biāo)簽。

我們使用if標(biāo)簽來解決問題:
改造UserMapper.xml,如下:

<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM user
WHERE 1=1
<if test="sex != null and sex != ''">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</select>
注意字符串類型的數(shù)據(jù)需要要做不等于空字符串校驗(yàn)。
效果如下:

image.png


繼續(xù)改造上面的例子
上面的sql還有where 1=1 這樣的語句,很麻煩,可以使用where標(biāo)簽進(jìn)行改造
改造UserMapper.xml,如下:

<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM user

<where>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</where>
</select>
測(cè)試效果如下:

image.png


Sql片段
Sql中可將重復(fù)的sql提取出來,使用時(shí)用include引用即可,最終達(dá)到sql重用的目的。
把上面例子中的id, username, birthday, sex, address提取出來,作為sql片段,如下:

<select id="queryUserByWhere" parameterType="user" resultType="user">


SELECT <include refid="userFields" /> FROM user

<where>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</where>
</select>


<sql id="userFields">
id, username, birthday, sex, address
</sql>
如果要使用別的Mapper.xml配置的sql片段,可以在refid前面加上對(duì)應(yīng)的Mapper.xml的namespace
例如下圖:


image.png

foreach的使用方法:
向sql傳遞數(shù)組或List,mybatis使用foreach解析,如下:
根據(jù)多個(gè)id查詢用戶信息
我們傳入的是POJO的包裝類


查詢sql:
SELECT * FROM user WHERE id IN (1,10,24)
如下圖在pojo中定義list屬性ids存儲(chǔ)多個(gè)用戶id,并添加getter/setter方法:

image.png

編寫Mapper.xml
UserMapper.xml添加sql,如下:

<select id="queryUserByIds" parameterType="queryVo" resultType="User">
SELECT * FROM user
<where>






<foreach collection="ids" item="item" open="id IN (" close=")"
separator=",">
#{item}
</foreach>
</where>
</select>
測(cè)試方法如下圖:
@Test
public void testQueryUserByIds() {
// mybatis和spring整合,整合之后,交給spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 創(chuàng)建Mapper接口的動(dòng)態(tài)代理對(duì)象,整合之后,交給spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 使用userMapper執(zhí)行根據(jù)條件查詢用戶
QueryVo queryVo = new QueryVo();
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(10);
ids.add(24);
queryVo.setIds(ids);

List<User> list = userMapper.queryUserByIds(queryVo);

for (User u : list) {
    System.out.println(u);
}

// mybatis和spring整合,整合之后,交給spring管理
sqlSession.close();

}
測(cè)試效果如下圖:


image.png

我們傳入的是是List的時(shí)候


image.png

配置文件應(yīng)該修改成相應(yīng)的


image.png

我們傳入的是數(shù)組的時(shí)候
image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容