JavaWeb-Mysql 3-5 Mybatis案例2 条件查询、动态多、单条件查询(if、where、when、choose标签)

1、多条件查询

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

  • 条件表达式
  • 如何连接

条件字段 企业名称 和 品牌名称 需要进行模糊查询,所以条件应该是:
在这里插入图片描述
简单的分析后,我们来看功能实现的步骤:

编写接口方法
参数:所有查询条件
结果:List
在映射配置文件中编写SQL语句
编写测试方法并执行

1.1三种编写多条件查询的接口方法

在 BrandMapper 接口中定义多条件查询的方法。
而该功能有三个参数,我们就需要考虑定义接口时,参数应该如何定义。Mybatis针对多参数有多种实现

1.1.1 使用 @Param(“参数名称”) 标记每一个参数,在映射配置文件中就需要使用 #{参数名称} 进行占位
List<Brand> selectCondition(@Param("status") int status, @Param("companyName") String
companyName,@Param("brandName") String brandName);
1.1.2 将多个参数封装成一个实体对象,将该实体对象作为接口的方法参数。该方式要求在映射文件中的SQL中使用#{内容} 时,里面的内容必须和实体类的属性名保持一致。
List<Brand> selectCondition(Brand brand);
1.1.3 将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容}时,里面的内容必须和map集合中键的名称一致。
List<Brand> selectCondition(Map map); 

1.2 编写SQL语句

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

    <!-- 多条件查询sql映射   -->
    <select id="selectCondition" resultMap="brandResultMap">
        select * from tb_brand where
        status = #{status} and
        company_name like #{companyName} and
        brand_name like #{brandName}
    </select>

1.3 编写测试方法

@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.selectCondition(status, companyName, brandName);
  //方式二 :接口方法参数是 实体类对象 方式调用的方法
  //封装对象
  /* Brand brand = new Brand();
    brand.setStatus(status);
    brand.setCompanyName(companyName);
    brand.setBrandName(brandName);*/
 
  //List<Brand> brands = brandMapper.selectCondition(brand);
 
  //方式三 :接口方法参数是 map集合对象 方式调用的方法
  Map map = new HashMap();
  map.put("status" , status);
  map.put("companyName", companyName);
  map.put("brandName" , brandName);
  List<Brand> brands = brandMapper.selectCondition(map);
  System.out.println(brands);
  //5. 释放资源
  sqlSession.close();
}

在这里插入图片描述

2、动态多条件查询–动态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="selectCondition" 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>

如上的这种SQL语句就会根据传递的参数值进行动态的拼接。如果此时status和companyName有值那么就会值拼接这
两个条件。
在这里插入图片描述
但是它也存在问题,如果此时给的参数值是
在这里插入图片描述
拼接的SQL语句就变成了

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

在这里插入图片描述
而上面的语句中 where 关键后直接跟 and 关键字,这就是一条错误的SQL语句。这个就可以使用 where 标签解决

  • where 标签
    • 作用:
      • 替换where关键字
      • 会动态的去掉第一个条件前的 and
      • 如果所有的参数没有值则不加where关键字
<select id="selectCondition" 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 关键字。
在这里插入图片描述

3、动态单条件查询 sql

在这里插入图片描述
如上图所示,在查询时只能选择 品牌名称 、 当前状态 、 企业名称 这三个条件中的一个,但是用户到底选择哪儿一个,我们并
不能确定。这种就属于单个条件的动态SQL语句。

这种需求需要使用到 choose(when,otherwise)标签 实现, 而 choose 标签类似于Java 中的switch语句。

通过一个案例来使用这些标签

3.1 编写接口方法

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

/**
 * 单条件动态查询
 * @param brand
 * @return
 */
List<Brand> selectBySingle(Brand brand);

3.2编写SQL语句

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

 <!-- 动态单条件查询 choose when otherwise   -->
    <select id="selectBySingle" resultMap="brandResultMap">
        select * from tb_brand
        <where>
            <choose><!-- 相当于switch -->
                <when test="status !=null ">
                    status = #{status}
                </when>
                <when test="companyName != null and companyName != ''">
                    company_name like #{companyName}
                </when>
                <when test="brandName != null and brandName != ''">
                    brand_name like #{brandName}
                </when>
            </choose>
        </where>
    </select>

3.3编写接口方法

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

    @Test
    public void selectBrandCondition() throws Exception {

        // 0.传参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";

        //0.1  添加模糊查询的条件
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";

        // 封装brand对象
        Brand brand = new Brand();
        // brand.setStatus(status);
        // brand.setCompanyName(companyName);
        brand.setBrandName(brandName);
        //1、加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";//相对路径,基于resources
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.有了工厂对象,就要获取SqlSession对象,执行SQL语句。
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3.执行sql,实参名字是sql的mapper.xml命名空间.id标识
        // List<User> users = sqlSession.selectList("test.selectAll");

        //3.执行sql获取UserMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        List<Brand> brands = brandMapper.selectCondition(status,companyName,brandName);
        List<Brand> brands = brandMapper.selectBySingle(brand);

        //4.输出
        //[Brand{id=2, brandName='华为', companyName='华为技术有限公司', ordered=100, description='化为牛B', status=1}]
        System.out.println(brands);

        //5.释放资源
        sqlSession.close();
    }

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值