Mybatis:CRUD数据操作之多条件查询及动态SQL
Mybatis基础环境准备请看:Mybatis基础环境准备
本篇讲解Mybati数据CRUD数据操作之多条件查询
1,编写接口方法
在 com.itheima.mapper
包写创建名为 BrandMapper
的接口。在 BrandMapper
接口中定义多条件查询的方法。
而该功能有三个参数,我们就需要考虑定义接口时,参数应该如何定义。Mybatis针对多参数有多种实现
-
使用
@Param("参数名称")
标记每一个参数,在映射配置文件中就需要使用#{参数名称}
进行占位List<Brand> selectByCondition1(@Param("status") int status, @Param("companyName") String companyName,@Param("brandName") String brandName);
-
将多个参数封装成一个 实体对象 ,将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用
#{内容}
时,里面的内容必须和实体类属性名保持一致。List<Brand> selectByCondition2(Brand brand);
-
将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用
#{内容}
时,里面的内容必须和map集合中键的名称一致。List<Brand> selectByCondition3(Map map);
即在接口中,定义接口如下3种形式:
List<Brand> selectByCondition1(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
List<Brand> selectByCondition2(Brand brand);
List<Brand> selectByCondition3(Map map);
2,编写SQL语句
在 reources
下创建 com/itheima/mapper
目录结构,并在该目录下创建名为 BrandMapper.xml
的映射配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.BrandMapper">
<resultMap id="brandResultMap" type="brand">
<!--
id:完成主键字段的映射
column:表的列名
property:实体类的属性名
result:完成一般字段的映射
column:表的列名
property:实体类的属性名
-->
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<select id="selectByCondition1" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
<select id="selectByCondition2" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
<select id="selectByCondition3" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
</mapper>
3,编写测试方法
在 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> selectByCondition1(@Param("status") int status, @Param("companyName") String companyName,@Param("brandName") String brandName);
List<Brand> brands1 = brandMapper.selectByCondition1(status, companyName, brandName);
System.out.println(brands1);
//方式二 :接口方法参数是 实体类对象 方式调用的方法
// 对应接口:List<Brand> selectByCondition2(Brand brand);
//封装对象
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
List<Brand> brands2 = brandMapper.selectByCondition2(brand);
System.out.println(brands2);
//方式三 :接口方法参数是 map集合对象 方式调用的方法
// 对应接口:List<Brand> selectByCondition3(Map map);
Map map = new HashMap();
map.put("status" , status);
map.put("companyName", companyName);
map.put("brandName" , brandName);
List<Brand> brands3 = brandMapper.selectByCondition3(map);
System.out.println(brands3);
//5. 释放资源
sqlSession.close();
}
执行测试方法结果如下:
结果与数据库里信息一致,3种方式都可以得到相同的结果。
4,动态SQL
上述功能实现存在很大的问题, 用户在输入条件时,肯定不会所有的条件都填写,如果写死sql
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
那么,肯定会报错,比如status字段没有,则语法报错。
这就需要我们根据实际去动态生成SQL语句。
Mybatis对动态SQL有很强大的支撑:
if
choose (when, otherwise)
trim (where, set)
foreach
-
if 标签:条件判断
- test 属性:逻辑表达式,如果为是,则 if标签保留,否则if标签内容不保留
-
where 标签
作用:- 替换where关键字
- 会动态的去掉第一个条件前的 and
- 如果所有的参数没有值则不加where关键字
注意:需要给每个条件前都加上 and 关键字。
动态sql示例
sql配置编写:
<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>
测试类里:
Map map2 = new HashMap();
//map2.put("status" , status);
map2.put("companyName", companyName);
map2.put("brandName" , brandName);
List<Brand> brands = brandMapper.selectByCondition(map2);
System.out.println(brands);
运行结果:
可以看到,SQL语句动态生成了,结果正确!
[声明]:内容主要来源黑马程序员网上资源学习