1. 准備
請先完成Mybatis基本配置(一)的基本內容
2. 疑問
我們再Mybatis基本配置(一)中實現了按照商品ID進行查詢商品信息,可是在實際應用中卻很少出現根據ID來查詢商品的情況。因為我們的用戶或許並不知道這個商品的ID是什么,他們只能記住商品編碼或者商品的部分名稱,更甚至是他們只記得這個商品的大致售價。如果這個時候他們想找到自己想要的那個商品該怎么辦么?所以我們的系統還必須提供另外一些功能。
3. 解決
現在我們擬定我們的用戶需要根據商品編碼、商品名稱及價格等信息來查詢自己想要的商品,所以我們要做如下更改:
1) 定義查詢條件實體類
package com.mybatis.entity; public class QryPartParam { private String partCode; //要查詢的商品編碼 private String partName; //要查詢的商品名稱 private float salePriceLow; //價格區間--起始價格 private float salePriceHigh; //價格區間--結束價格 public String getPartCode() { return partCode; } public void setPartCode(String partCode) { this.partCode=partCode; } public String getPartName() { return partName; } public void setPartName(String partName) { this.partName=partName; } public String getSalePriceLow() { return salePriceLow; } public void setSalePriceLow(String salePriceLow) { this.salePriceLow=salePriceLow; } public String getSalePriceHigh() { return salePriceHigh; } public void setSalePriceHigh(String SalePriceHigh) { this.SalePriceHigh=SalePriceHigh; } }
2)在com.mybatis.dao.PartDao中增加接口函數
public List<PartInfo> getPartInfoByUser(QryPartParam qryPartParam);
3)在com.mybatis.dao.mapper.PartMapper中增加其實現方法。
<select id="getPartInfoByUser" parameterType="com.mybatis.entity.QryPartParam" resultType="com.mybatis.entity.PartInfo"> SELECT * FROM tbInfoPart WHERE PartCode = #{partCode} AND PartName LIKE '%'+#{partName}+'%' AND SalePrice <![CDATA[>=]]> #{salePriceLow} AND SalePrice <![CDATA[<=]]> #{salePriceHigh} </select>
需要注意的是:
(1)需要模糊查詢的時候,可參考PartName LIKE '%'+#{partName}+'%'這種的寫法,當然還有其他寫法就待讀者自行摸索
(2)當我們的查詢語句中出現>或者<等此類符號時,因為這兩種符號為xml的關鍵字符,
"<" 會產生錯誤,因為解析器會把該字符解釋為新元素的開始。
">" 會產生錯誤,因為解析器會把該字符解釋為新元素的結束。
所以需要特殊處理成<![CDATA[>=]]>。術語 CDATA 指的是不應由 XML 解析器進行解析的文本數據。
當然我們也可以用轉義字符。xml的轉義字符列表如下:
< | < | 小於 |
> | > | 大於 |
& | & | 和號 |
' | ' | 省略號 |
" | " | 引號 |
4)測試下效果
public static List<PartInfo> selectPartByUser(QryPartParam qryPartParam){ InputStream iStream = TestMain.class.getClassLoader().getResourceAsStream("mybatis.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(iStream); SqlSession session = sessionFactory.openSession(); String statement = "com.mybatis.dao.PartDao.getPartInfoByUser"; List<PartInfo> partInfos = session.selectList(statement, qryPartParam); session.close(); return partInfos; }
public static void main(String[] args) { QryPartParam qryPartParam = new QryPartParam(); qryPartParam.setPartCode("001-0001"); qryPartParam.setPartName("TCL"); qryPartParam.setSalePriceLow(0f); qryPartParam.setSalePriceHigh(10000f); List<PartInfo> partInfos = selectPartByUser(qryPartParam); for (PartInfo partInfo : partInfos) { System.out.println("ID:"+partInfo.getId()+" 商品:["+ partInfo.getPartCode()+"] "+ partInfo.getPartName()+" ,售價:"+ partInfo.getSalePrice()+"元/"+ partInfo.getUnit()); }
打印結果為
ID:1 商品:[001-0001] TCL D32E161 32英寸 內置wifi 在線影視 窄邊LED網絡液晶電視 ,售價:1099.9元/台
可以看到我們已經成功查詢到了該條商品
4.有關參數問題
有人可能會問,按照現在參數定義方式(com.mybatis.entity.QryPartParam),那是不是說我以后每增加一個查詢,就需要定義相對應的參數類?為了解決這個問題,筆者提供其他兩種參數定義方式
1)通過@Param注解來標識多參數:
public List<PartInfo> getPartInfoByUser(@Param("partCode") String partCode,
@Param("partName") String partName,
@Param("salePriceLow") float salePriceLow,
@Param("salePriceHigh") float salePriceHigh);
在Mapper中則不再需要parameterType賦值:
<select id="getPartInfoByUser" resultType="com.mybatis.entity.PartInfo"> SELECT * FROM tbInfoPart WHERE PartCode = #{partCode} AND PartName LIKE '%'+#{partName}+'%' AND SalePrice <![CDATA[>=]]> #{salePriceLow} AND SalePrice <![CDATA[<=]]> #{salePriceHigh} </select>
此種傳參方式適用於參數個數比較少的情況。
2)通過Map傳參:
public List<PartInfo> getPartInfoByUser(Map<String, Object> map);
在Mapper中對應的parameterType應賦值為(其中#{}種的取值應和Map中的鍵名是一致的):
<select id="getPartInfoByUser" parameterType="java.util.Map" resultType="com.mybatis.entity.PartInfo"> SELECT * FROM tbInfoPart WHERE PartCode = #{partCode} AND PartName LIKE '%'+#{partName}+'%' AND SalePrice <![CDATA[>=]]> #{salePriceLow} AND SalePrice <![CDATA[<=]]> #{salePriceHigh} </select>
此種傳參方式優點在於易擴展。