Mybatis实战练习三【多条件查询】

举报
爱吃豆的土豆 发表于 2022/09/25 05:02:35 2022/09/25
1.7k+ 0 0
【摘要】 目录 💂 个人主页: 爱吃豆的土豆 🌈欢迎加入社区,福利多多哦!土豆社区 🤟数据库专栏更新完毕:数据库知识🤟JDBC专栏更新完毕:JDBC知识🤟Mybatis专栏更新中:Mybatis知识💬 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 多条件查询 编写接口方法 编写SQL语句 ...

目录

多条件查询

编写接口方法

编写SQL语句

编写测试方法

动态SQL


多条件查询

我们经常会遇到如上图所示的多条件查询,将多条件查询的结果展示在下方的数据列表中。而我们做这个功能需要分析最终的SQL语句应该是什么样,思考两个问题

  • 条件表达式

  • 如何连接

条件字段 企业名称品牌名称 需要进行模糊查询,所以条件应该是:

简单的分析后,我们来看功能实现的步骤:

  • 编写接口方法

    • 参数:所有查询条件

    • 结果:List<Brand>

  • 在映射配置文件中编写SQL语句

  • 编写测试方法并执行  

编写接口方法

BrandMapper 接口中定义多条件查询的方法。

而该功能有三个参数,我们就需要考虑定义接口时,参数应该如何定义。Mybatis针对多参数有多种实现

  • 使用 @Param("参数名称") 标记每一个参数,在映射配置文件中就需要使用 #{参数名称} 进行占位

    List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName,@Param("brandName") String brandName);
       

    将多个参数封装成一个 实体对象 ,将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容} 时,里面的内容必须和实体类属性名保持一致。

List<Brand> selectByCondition(Brand brand);
 

 将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容} 时,里面的内容必须和map集合中键的名称一致。

List<Brand> selectByCondition(Map map);
 

编写SQL语句

BrandMapper.xml 映射配置文件中编写 statement,使用 resultMap 而不是使用 resultType


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

编写测试方法

test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法


      @Test
      public void testSelectByCondition() throws IOException {
         //接收参数
         int status = 1;
         String companyName = "华为";
         String brandName = "华为";
         // 处理参数
          companyName = "%" + companyName + "%";
          brandName = "%" + brandName + "%";
         //1. 获取SqlSessionFactory
         String resource = "mybatis-config.xml";
         InputStream inputStream = Resources.getResourceAsStream(resource);
         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
         //2. 获取SqlSession对象
         SqlSession sqlSession = sqlSessionFactory.openSession();
         //3. 获取Mapper接口的代理对象
         BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
         //4. 执行方法
     	//方式一 :接口方法参数使用 @Param 方式调用的方法
         //List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
         //方式二 :接口方法参数是 实体类对象 方式调用的方法
          //封装对象
         /* Brand brand = new Brand();
       brand.setStatus(status);
       brand.setCompanyName(companyName);
       brand.setBrandName(brandName);*/
         //List<Brand> brands = brandMapper.selectByCondition(brand);
         //方式三 :接口方法参数是 map集合对象 方式调用的方法
         Map map = new HashMap();
          map.put("status" , status);
          map.put("companyName", companyName);
          map.put("brandName" , brandName);
          List<Brand> brands = brandMapper.selectByCondition(map);
          System.out.println(brands);
         //5. 释放资源
          sqlSession.close();
      }
  
 

动态SQL

上述功能实现存在很大的问题。用户在输入条件时,肯定不会所有的条件都填写,这个时候我们的SQL语句就不能那样写的

例如用户只输入 当前状态 时,SQL语句就是

select * from tb_brand where status = #{status}
 

而用户如果只输入企业名称时,SQL语句就是

select * from tb_brand where company_name like #{companName}
 

而用户如果输入了 当前状态企业名称 时,SQL语句又不一样

select * from tb_brand where status = #{status} and company_name like #{companName}
 

针对上述的需要,Mybatis对动态SQL有很强大的支撑:

  • if

  • choose (when, otherwise)

  • trim (where, set)

  • foreach

我们先学习 if 标签和 where 标签:

  • if 标签:条件判断

    • test 属性:逻辑表达式


      <select id="selectByCondition" resultMap="brandResultMap">
          select *
          from tb_brand
          where
             <if test="status != null">
                  and 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>
  
 

如上的这种SQL语句就会根据传递的参数值进行动态的拼接。如果此时status和companyName有值那么就会值拼接这两个条件。

执行结果如下:

但是它也存在问题,如果此时给的参数值是


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

 拼接的SQL语句就变成了

select * from tb_brand where and company_name like ? and brand_name like ?
 
  • 而上面的语句中 where 关键后直接跟 and 关键字,这就是一条错误的SQL语句。这个就可以使用 where 标签解决

  • where 标签

    • 作用:

      • 替换where关键字

      • 会动态的去掉第一个条件前的 and

      • 如果所有的参数没有值则不加where关键字


      <select id="selectByCondition" resultMap="brandResultMap">
          select *
          from tb_brand
         <where>
             <if test="status != null">
                  and 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>
      </select>
  
 

 注意:需要给每个条件前都加上 and 关键字。

文章来源: qianxu.blog.csdn.net,作者:爱吃豆的土豆,版权归原作者所有,如需转载,请联系作者。

原文链接:qianxu.blog.csdn.net/article/details/126586963

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。