【MyBatis】多關鍵字的模糊查詢
任務驅動才能明確方向。我舉一個例子。
情景分析
題目
現在我們要執行查詢操作,例如我要查詢商品的供應商資訊。供應商的資訊包括公司名稱,負責人名字,聯繫電話,公司地址等。
我也許會輸入電話號碼的前幾位查詢,也許會輸入公司名稱的某個字查詢,也許會輸出負責人的姓氏查詢……
我希望查出來的結果,是按照Id升序排序好了的。
要求
1.我要根據公司名稱查詢,只要公司名稱包含「廣東」、「深圳」的都可以被查詢出來
2.我要根據負責人名字查詢,只要負責人名字包含「周」、「吳」、「鄭」、「王」的都可以被查詢出來
3.我要根據電話號碼查詢,只要電話號碼包含「139」,「136」,「137」的都可以被查詢出來
相關程式碼
下面MyBatis的配置方式是Spring整合MyBatis的,詳情請參閱下面這篇文章
【Spring】【MyBatis】Spring整合MyBatis01 - 萌狼藍天 - 部落格園 (//www.cnblogs.com/mllt/p/SpringAndMybatis01.html)
Mapper.java
/**
* 查詢供應商資訊
* @param way 查詢方式。1:根據供應商公司名稱模糊查詢 2:根據供應商負責人名字模糊查詢 3:根據電話模糊查詢
* @param npcs 查詢的關鍵字
* @return List<SmbmsProvider>
*/
public List<SmbmsProvider> getProviderByNCP(@Param("way") int way, @Param("npcs") List<String> npcs);
SmbmsProvider是供應商對象。
Impl.java
package cc.mllt.impl;
import cc.mllt.mapper.ProviderMapper;
import cc.mllt.pojo.SmbmsProvider;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
//實現類
public class ProviderImpl implements ProviderMapper {
private SqlSessionTemplate sqlSessionTemplate;
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate){
this.sqlSessionTemplate=sqlSessionTemplate;
}
@Override
public List<SmbmsProvider> getProviderByNCP(int way, List<String> npcs) {
ProviderMapper providerMapper = sqlSessionTemplate.getMapper(ProviderMapper.class);
return providerMapper.getProviderByNCP(way,npcs);
}
}
mapper.xml
<!-- public List<SmbmsProvider> getProviderByNCP(@Param("way") int way, @Param("npc") List<String> npcs);-->
<select id="getProviderByNCP" resultType="SmbmsProvider">
select * from smbms_provider
<choose>
<when test="way==1">
where
<foreach item="npc" index="index" collection="npcs" open="" separator=" or " close="">
<if test="npc!=''">
proName like concat('%',#{npc},'%')
</if>
</foreach>
</when>
<when test="way==2">
where
<foreach item="npc" index="index" collection="npcs" open="" separator=" or " close="">
<if test="npc!=''">
proContact like concat('%',#{npc},'%')
</if>
</foreach>
</when>
<when test="way==3">
where
<foreach item="npc" index="index" collection="npcs" open="" separator=" or " close="">
<if test="npc!=''">
proPhone like concat('%',#{npc},'%')
</if>
</foreach>
</when>
<otherwise>
where
<foreach item="npc" index="index" collection="npcs" open="" separator=" or " close="">
<if test="npc!=''">
proName like concat('%',#{npc},'%')
</if>
</foreach>
</otherwise>
</choose>
order by `id`
</select>
經過測試,當List類型參數包含Null時,不會對結果造成影響,因此我上面沒有進行null的判斷,如果你有需求,可以加上
經過測試,當List類型參數包含""(也就是空)的時候,會導致將所有數據都查詢出來了,因此要判斷內容不為空
了解
MyBatis foreach標籤相關資訊請查閱:MyBatis foreach標籤 (biancheng.net)
test.java
ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
ProviderMapper providerMapper = context.getBean("providerMapperBean",ProviderMapper.class);
@Test
public void getProviderByNCPTest(){
List<String> list1 = new ArrayList<>();
//下面兩個是我們要查詢的
list1.add("北京");
list1.add("深圳");
//下面這些是用來測試的
list1.add(null);
list1.add("");
//下面這句話是分頁插件的使用,未使用分頁插件則忽略這句話
Page<Object> page = PageHelper.startPage(1,3);
//執行查詢操作
List<SmbmsProvider> result1 = providerMapper.getProviderByNCP(1,list1);
//方式1查詢結果合集,通過分頁插件整理了的
PageInfo<SmbmsProvider> pageInfo1 = new PageInfo<>(result1,3);//三頁
//輸出相關分頁的資訊
System.out.println(page);
System.out.println(pageInfo1);
//從分頁資訊中取出查詢到的數據
result1=pageInfo1.getList();
//格式化輸出
System.out.println("--------------------根據公司名稱查詢--------------------");
for(SmbmsProvider smbmsProvider:result1){
System.out.println(smbmsProvider.getId()+"\t"+smbmsProvider.getProCode()+"\t"+smbmsProvider.getProName()+"\t"+ smbmsProvider.getProContact()+"\t"+smbmsProvider.getProPhone());
}
}
【輸出結果如下】
思路分析
1.最開始,參數沒有使用List,引起的問題
/**
* 查詢供應商資訊
* @param way 查詢方式。1:根據供應商公司名稱模糊查詢 2:根據供應商負責人名字模糊查詢 3:根據電話模糊查詢
* @param npc 查詢的關鍵字
* @return List<SmbmsProvider>
*/
public List<SmbmsProvider> getProviderByNCP(@Param("way") int way, @Param("npc") String npc);
這種方式有一個問題,我查詢「北京」,「深圳」需要分為兩次查詢,後面手動將查詢結果合併在一起,然後又要去考慮id升序排序問題……
正如你所見,很麻煩。尤其是排序問題。因為得到的結果是List
如果能一起將多個關鍵字一起查詢,將得到的結果,一個Order By 就解決了,所以,我們要去考慮使用的參數應該是個List,然後裡面包含我們想要查詢的多個關鍵字。
那麼傳入一個List,又怎麼在Mapper.xml中取出想要的東西呢,就發現了後面的 MyBatis foreach
2.Mybatis的foreach
了解
MyBatis foreach標籤相關資訊請查閱:MyBatis foreach標籤 (biancheng.net)
3. npc != ''
注意標題上的是兩個單引號,而不是一個雙引號
為什麼我特意用一個 if做判斷?
這裡應對的是List中存在空
1:如果整個列表都空的(也就是一個空列表)
List<String> list1 = new ArrayList<>();
list1.add(null);
list1.add("");
我們沒有在When中進行判斷,列表是否為空,所以它會繼續執行下去

到達foreach的時候,開始遍歷,如果為空,則後續無語句,若不為空,則繼續添加if塊中的語句
測試當空List傳入時,結果如下

4.其他
分頁插件在這篇文章並沒有得到充分的應用。


