mybatis(4)多條件查詢與單條件查詢


1. 編寫Mapper接口

 /**
     *  查看詳情,通過id查詢
     */
    Brand selectById(int id);

2. 編寫sql語句,sql映射文件

    <select id="selectById" resultMap="brandResultMap">
        select * from tb_brand where id=#{id};
    </select>

3. 執行方法 測試

  //4.執行方法
        Brand brand = mapper.selectById(id);
        System.out.println(brand);

傳遞的參數id有兩種參數占位符。
1.#{}:會將其替換為?,為了防止sql注入

Preparing: select * from tb_brand where id=?;
2.${}:拼sql。會存在sql注入問題
Preparing: select * from tb_brand where id=1;

*參數類型:parameterType:可以省略
*特殊字符處理:(比如小於號,小於號在xml中是注釋符號所以sql語句寫<會報錯)
1.轉義字符

   <select id="selectById" resultMap="brandResultMap">
        select * from tb_brand where id &lt; #{id};
    </select>

2.CDATA區

    <select id="selectById" resultMap="brandResultMap">
        select * from tb_brand where id <![CDATA[
        <
        ]]> #{id};
    </select>

 

 

 

 

  1. 如果我們想多條件查詢那么就是要傳遞散裝參數,需要在接口的方法中添加@Param("sql參數占位符")
    List<Brand> selectByCondition(@Param("status")int status, @Param("companyName")String companyName, @Param("brandName")String brandName);

 
那么我們在sql映射配置文件中就需要用#{"sql參數占位符"}來接收參數了。

          <!--    條件查詢-->
    <select id="selectByCondition" resultMap="brandResultMap">
            select * from tb_brand
             where   status=#{status}
            and company_name like #{companyName}
            and brand_name like #{brandName}
    </select>

 

下面進行測試用例的編寫

 @Test
    public void testSelectByCondition() throws IOException {
        //接收參數
        int status=1;
        String companyName="華為";
        String brandName="華為";
        //因為要進行模糊查詢
        companyName="%"+companyName+"%";
        brandName="%"+brandName+"%";
        //1.獲取sqlSessionFactory對象
        String resources ="mybatis-config.xml";
        InputStream resourceAsStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);


        //2.獲取SqlSession對象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3.獲取mapper接口的處理對象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        //4.執行方法
        List<Brand> brands = mapper.selectByCondition(status, companyName, brandName);
        System.out.println(brands);

        //5.釋放資源
        sqlSession.close();



    }
  1. 當我們傳遞對象參數時,我們的sql映射配置文件可以像散裝參數那樣不用變,只要在測試用例中給類設置參數就行了。
    mapper接口
    List<Brand> selectByCondition(Brand brand);

sql映射配置文件:

            <!--    條件查詢-->
    <select id="selectByCondition" resultMap="brandResultMap">
            select * from tb_brand
             where   status=#{status}
            and company_name like #{companyName}
            and brand_name like #{brandName}
    </select>

測試用例:

 //封裝對象
        Brand brand=new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);
        

 List<Brand> brands = mapper.selectByCondition(brand);

        System.out.println(brands);

完整代碼:

 @Test
    public void testSelectByCondition() throws IOException {
        //接收參數
        int status=1;
        String companyName="華為";
        String brandName="華為";
        //因為要進行模糊查詢
        companyName="%"+companyName+"%";
        brandName="%"+brandName+"%";

        //封裝對象
        Brand brand=new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);


        //1.獲取sqlSessionFactory對象
        String resources ="mybatis-config.xml";
        InputStream resourceAsStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);


        //2.獲取SqlSession對象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3.獲取mapper接口的處理對象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        //4.執行方法
//        List<Brand> brands = mapper.selectByCondition(status, companyName, brandName);
        List<Brand> brands = mapper.selectByCondition(brand);

        System.out.println(brands);

        //5.釋放資源
        sqlSession.close();



    }
  1. map集合參數
    mapper接口:
    List<Brand> selectByCondition(Map map);

sql映射文件不變

 
測試用例:
首先要有個map集合,map集合的鍵要和sql映射配置文件的值相對應

 Map map = new HashMap();
        map.put("status",status);
        map.put("companyName",companyName);
        map.put("brandName",brandName);


 

但是這個查詢是由bug的。比如:
如果用戶只輸入一個條件時,那么sql語句就會出現null的情況就會報錯。

select * from tb_brand where status=? and company_name like ? and brand_name like ? 

 
 
 
 
 
當用戶輸入的條件不確定時,我們讓sql語句動態隨着用戶的輸入而變化時,這樣就不會報錯了。
 

多條件查詢

mybatis對動態有很大的支持,比如說if:
在sql語句中加入if標簽其實就是if判斷,里面的test屬性就是if判斷語句


<!--    動態條件查詢-->
    <select id="selectByCondition" resultMap="brandResultMap">
        select * from tb_brand
        where
        <if test="status!=null">
            status=#{status}
        </if>

        <if test="companyName!=null and companyName!=''">
            and  company_name like #{companyName}
        </if>

        <if test="brandName!=null and brandName!=''">
            and    brand_name like #{brandName}
        </if>
    </select>

但是呢,這樣還是有一些問題的?就像下面這樣如果我沒有status前面會多出一個and不滿足語法,解決方案呢有兩個,第一個是恆等式;

<!--
    動態條件查詢
    *if: 條件判斷
        *test:邏輯表達式
    *問題:
        *1.恆等式
        *2.<where> 替換 where關鍵字
-->

  1. 恆等式
  select * from tb_brand
        where 1=1
        <if test="status!=null">
            status=#{status}
        </if>

        <if test="companyName!=null and companyName!=''">
            and  company_name like #{companyName}
        </if>

        <if test="brandName!=null and brandName!=''">
            and    brand_name like #{brandName}
        </if>

2. where
~~~xml
  select * from tb_brand
        /*where 1=1*/
        <where>
        <if test="status!=null">
            status=#{status}
        </if>

        <if test="companyName!=null and companyName!=''">
            and  company_name like #{companyName}
        </if>

        <if test="brandName!=null and brandName!=''">
            and    brand_name like #{brandName}
        </if>
        </where>

這里where標簽會自動把and去掉,是不是很爽捏。

 
 
 
 

下面看一下單條件的查詢

 

因為要傳的參數不確定,所以傳個類的參數。

        List<Brand> selectByConditionSingle(Brand brand);
<select id="selectByConditionSingle" resultMap="brandResultMap">
        select *
        from tb_brand
        where
        <choose>
            <when test="status!=null">/*相當於case*/
                status=#{status}
            </when>
            <when test="companyName!=null and companyName!=''">/*相當於case*/
                company_name like #{companyName}
            </when>
            <when test="brandName!=null and brandName!=''">/*相當於case*/
                brand_name like #{brandName}
            </when>
        </choose>

    </select>

如果用戶什么都沒有傳參數過來那么otherwise1=1,即sql語句為select * from tb_brand where 1=1。如果沒有otherwise那么語句就為select * from tb_brand where會報錯。

  <choose>
            <when test="status!=null">/*相當於case*/
                status=#{status}
            </when>
            <when test="companyName!=null and companyName!=''">/*相當於case*/
                company_name like #{companyName}
            </when>
            <when test="brandName!=null and brandName!=''">/*相當於case*/
                brand_name like #{brandName}
            </when>
            <otherwise>/*相當於default*/
                1=1
            </otherwise>
        </choose>

當然這里可以把otherwise去掉換成 包裹choose,因為where標簽可以動態調整sql語法,給它修改正確,

  <select id="selectByConditionSingle" resultMap="brandResultMap">
        <!--select *
        from tb_brand
        where
        <choose>
            <when test="status!=null">/*相當於case*/
                status=#{status}
            </when>
            <when test="companyName!=null and companyName!=''">/*相當於case*/
                company_name like #{companyName}
            </when>
            <when test="brandName!=null and brandName!=''">/*相當於case*/
                brand_name like #{brandName}
            </when>
            <otherwise>/*相當於default*/
                1=1
            </otherwise>
        </choose>-->
        select *
        from tb_brand
        <where>
        <choose>
            <when test="status!=null">/*相當於case*/
                status=#{status}
            </when>
            <when test="companyName!=null and companyName!=''">/*相當於case*/
                company_name like #{companyName}
            </when>
            <when test="brandName!=null and brandName!=''">/*相當於case*/
                brand_name like #{brandName}
            </when>

        </choose>
        </where>
    </select>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM