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的转义字符列表如下:

                 

&lt;

<

小于

&gt;

>

大于

&amp;

&

和号

&apos;

'

省略号

&quot;

"

引号

 

        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>



         此种传参方式优点在于易扩展。

5. 目录结构

mybaties 根据某一列 saveOrUpdate_解析器