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