2. Mybatis 配置文件完成增删改查
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
1. 任务描述
如上图所示产品原型里面包含了品牌数据的 查询 、 按条件查询 、 添加 、 删除 、 批量删除 、 修改 等功能而这些功能其实就是对数据库表中的数据进行 CRUD 操作。接下来就使用 Mybatis 完成品牌数据的增删改查操作。以下是要完成的功能列表
-
查询
查询所有数据
查看详情
条件查询 -
添加
-
修改
修改全部字段
修改动态字段 -
删除
删除一个
批量删除
2. 准备工作
(1) 创建数据库表 tb_brand
-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand
(
-- id 主键
id int primary key auto_increment,
-- 品牌名称
brand_name varchar(20),
-- 企业名称
company_name varchar(20),
-- 排序字段
ordered int,
-- 描述信息
description varchar(100),
-- 状态0禁用 1启用
status int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织构建万物互联的智能世界', 1),
('小米', '小米科技有限公司', 50, 'are you ok', 1);
SELECT * FROM tb_brand;
(2) 实体类 Brand
在实体类中基本数据类型建议使用对应的包装类型。
public class Brand {
// id主键
private Integer id;
// 品牌名称
private String brandName;
// 企业名称
private String companyName;
// 排序字段
private Integer ordered;
// 描述信息
private String description;
// 状态0-禁用 1-启用
private Integer status;
public Integer getId() {
return id;
}
//getter、setter方法
//toString方法
}
(3) 创建测试用例 MybatisTest
public class MybatisTest {
}
(4) 安装 MyBatisX 插件
在此之前UserMapper 接口和对应的 UserMapper.xml 文件都是手写的安装 MyBatisX 插件后可以根据 UserMapper 接口中的方法自动地向 UserMapper.xml 文件中添加 statement。
MybatisX 是一款基于 IDEA 的快速开发插件为效率而生。
主要功能
① XML 和接口方法相互跳转
② 根据接口方法生成 statement
安装完 mybatisx 插件后可以点击代码前面的小鸟实现 “XML 和接口方法相互跳转”也可以根据在 mapper 接口中写的接口方法生成 statement。
UserMapper.xml 中的生成结果如下
<!--statement-->
<select id="selectById" resultType="com.itheima.pojo.User"></select>
再向其中添加 SQL 语句即可。
<!--statement-->
<!--改一下别名-->
<select id="selectById" resultType="user">
select * from tb_user where id=#{id};
</select>
3. 配置文件完成查询功能
今后无论用 mybatis 完成多么复杂的功能基本就三步
- 在 Mapper 接口中编写接口方法
参数无
返回类型List<Brand> - 利用接口方法生成 SQL 映射文件中的 statement并补充 SQL 语句
- 执行方法测试
在三步之前首先配置好 pom.xml 文件同前准备好 logback.xml同前创建实体类 Brand同前准备好核心配置文件 mybatis-config.xml 如下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--相当于给pojo下面的所有实体类都取了别名
别名默认是类名不区分大小写可以不用带所在包的名称-->
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/><!--该操作可以被spring接管-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--mybatis数据库名-->
<!--jdbc:mysql:///mybatis?useSSL=false"也可以-->
<property name="url" value="jdbc:mysql://localhost/mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--更改sql映射文件路径-->
<!--注意resource下新建的是dictionary
分隔符用“/”,不能用“.”-->
<!--<mapper resource="com/itheima/mapper/UserMapper.xml"/>-->
<!--用包扫描的方式来加载 SQL 映射文件-->
<!--通过接口来找sql映射文件,所以路径中的分隔符用"."-->
<package name="com.itheima.mapper"/>
</mappers>
</configuration>
3.1 查询所有数据
下面开始三个基本步骤
(1) 编写 Mapper 接口
public interface BrandMapper {
List<Brand> selectAll();
}
(2) SQL 映射文件由 Mapper 接口方法生成 statement并补充编写 SQL 语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.BrandMapper">
<!--statement-->
<!--生成后改一下别名-->
<select id="selectAll" resultType="brand">
select * from tb_brand;
</select>
</mapper>
(3) 编写测试代码
public class MybatisTest {
@Test
public void testSelectAll() throws IOException {
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法
List<Brand> brands = brandMapper.selectAll();
System.out.println(brands);
//释放资源
sqlSession.close();
}
}
点这里可以执行测试代码
输出结果
在输出结果中可以看出有些字段为 null这是因为数据库表中的字段名称与实体类的属性写法不同对应不上
解决方案
(1) 起别名对不一样的列名起别名让别名和实体类的属性名相同。
<select id="selectAll" resultType="brand">
select id,brand_name as brandName, company_name as companyName, ordered, description
from tb_brand;
</select>
缺点每次查询都要定义一次别名。
(2) SQL 片段
<!--SQL片段-->
<sql id="brand_column">
<!--起别名时as可以省略-->
id, brand_name as brandName, company_name as companyName, ordered, description, status
</sql>
<select id="selectAll" resultType="brand">
select
<include refid="brand_column"></include>
from tb_brand;
</select>
缺点如果 select 语句所要查询的字段各不相同就要定义各种各样的 SQL 片段不灵活。
(3) resultMap最常用
<!--resultMap的id随便写-->
<!--type就是原SQL语句外部标签的resulType属性值-->
<resultMap id="brandResultMap" type="brand">
<!--把数据库表字段与实体类属性写法不同的写在这里-->
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<!--resultType属性改成resultMap属性-->
<select id="selectAll" resultMap="brandResultMap">
select * from tb_brand;
</select>
3.2 查看详情
有些数据的属性比较多在页面表格中无法全部实现而只会显示部分而其他属性数据的查询可以通过 查看详情 来进行查询如上图所示。
查看详情就是根据 id 查询数据。
在 BrandMapper 接口中添加
Brand selectById(int id);
在 BrandMapper.xml 中添加
<select id="selectById" parameterType="int" resultMap="brandResultMap">
# “#{id}”一般与接口方法的形参名称一致
select * from tb_brand where id=#{id};
</select>
参数占位符
① #{}会被替换为 “”防止 SQL 注入更好
② ${}拼接 SQL一定会存在 SQL 注入问题
适用情况一般的参数传递用 #{}表名或列名不固定时用 ${}
参数类型parameterType="int"可省略Integer 也可。
特殊字符如小于号 “<” 不能直接出现解决方法有
① 转义字符
<select id="selectById" resultMap="brandResultMap">
select * from tb_brand where id < #{id};
</select>
② CDATA 区
<select id="selectById" resultMap="brandResultMap">
select * from tb_brand where id
# 大写CD+enter
<![CDATA[
<
]]>
#{id};
</select>
在测试用例 MybatisTest.java 中添加
@Test
public void testSelectById() throws IOException {
//接收参数
int id = 1;
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法
Brand brand = brandMapper.selectById(id);
System.out.println(brand);
//释放资源
sqlSession.close();
}
3.3 条件查询
上图功能为 “进行多条件查询将查询结果展示在下方的表格中”。
分析 条件字段 企业名称 和 品牌名称 需要进行模糊查询所以条件应该是
(1) 编写接口方法
当查询条件不只一个时就需要考虑接口方法形参与 SQL 语句占位符的对应问题解决方法有三种
① 散装参数@Param(“SQL参数占位符名称”)
表示把该参数传给哪个占位符。
List<Brand> selectByCondition(
//status参数传给叫“status”的占位符
@Param("status") int status,
@Param("companyName") String companyName,
@Param("brandName") String brandName);
② 对象参数把查询条件封装成实体类的对象传递到接口方法中使 SQL 语句根据对象的 getter 方法获取对应属性。条件是占位符名称要与实体类的属性名称一致。
List<Brand> selectByCondition(Brand brand);
③ Map 集合参数也可以把查询条件封装成 Map 集合Map 集合键的名称要与 SQL 语句中的占位符名称一致。
List<Brand> selectByCondition(Map map);
(2) 编写 SQL 语句
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
# 模糊查询
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
(3) 编写测试方法
下面代码中要特别注意模糊查询的相关参数要特殊处理。
① 散装参数的测试
@Test
public void testSelectByCondition() throws IOException {
//接收参数
int status = 1;
String companyName = "小米";
String brandName = "小米";
//模糊查询所以要处理参数
companyName = "%"+companyName+"%";
brandName = "%"+brandName+"%";
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法
List<Brand> brands = brandMapper.selectByCondition(status,companyName,brandName);
System.out.println(brands);
//释放资源
sqlSession.close();
}
② 对象参数的测试
@Test
public void testSelectByCondition() throws IOException {
//接收参数
int status = 1;
String companyName = "小米";
String brandName = "小米";
//模糊查询所以要处理参数
companyName = "%"+companyName+"%";
brandName = "%"+brandName+"%";
//封装对象
Brand brand = new Brand();
brand.setStatus(1);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法传递对象参数
List<Brand> brands = brandMapper.selectByCondition(brand);
System.out.println(brands);
//释放资源
sqlSession.close();
}
③ Map 集合的测试
@Test
public void testSelectByCondition() throws IOException {
//接收参数
int status = 1;
String companyName = "小米";
String brandName = "小米";
//模糊查询所以要处理参数
companyName = "%"+companyName+"%";
brandName = "%"+brandName+"%";
//封装对象
Map map = new HashMap();
map.put("status", status);
map.put("companyName",companyName);
map.put("brandName",brandName);
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法传递对象参数
List<Brand> brands = brandMapper.selectByCondition(map);
System.out.println(brands);
//释放资源
sqlSession.close();
}
输出结果
3.4 动态条件查询
3.4.1 动态条件查询之多条件
上节的条件查询存在一个 bug。用户在输入条件时可能不会填写所有的条件这时就查询不出来所以 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}
SQL 语句会随着用户的输入或外部条件的变化而变化称为动态 SQLMybatis 对动态 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">
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>
//封装对象
Map map = new HashMap();
map.put("status", status);
map.put("companyName",companyName);
// map.put("brandName",brandName);
输出结果
但是它也存在问题如果此时给的参数值是
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 语句解决方式有两种推荐第二种
(1) 恒等式如添加 ”1=1“
(2) 用 where 标签替换 where 关键字在 SQL 语句中替换 where 关键字动态去掉第一个条件前的 and如果所有的参数没有值则不加 where 关键字推荐。
3.4.2 动态条件查询之单条件
如上图所示在查询时只能选择 品牌名称 、 当前状态 、 企业名称 这三个条件中的一个但是用户选哪一个不能确定。这种就属于单个条件的动态 SQL 语句。
这种需求需要使用到 choose(when, otherwise) 标签实现类似于 Java 中的 switch-case-default 语句。
(1) 编写接口方法
List<Brand> selectByConditionSingle(Brand brand);
(2) 编写SQL语句
方式 1不常用
<select id="selectByConditionSingle" resultMap="brandResultMap">
select *
from tb_brand
where
<choose>
<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>
<otherwise>
<!--以防所有字段都没有值时where后面没有语句导致语法错误-->
1=1
</otherwise>
</choose>
</select>
方式 2常用
<select id="selectByConditionSingle" resultMap="brandResultMap">
select *
from tb_brand
<where>
<!--如果所有字段都没有值
where标签就不添加where关键字-->
<choose>
<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) 编写测试方法
@Test
public void testSelectByConditionSingle() throws IOException {
//接收参数
int status = 1;
String companyName = "小米";
String brandName = "小米";
//模糊查询所以要处理参数
companyName = "%"+companyName+"%";
brandName = "%"+brandName+"%";
//封装对象实体类对象或Map对象都可
Brand brand = new Brand();
// brand.setStatus(status);
brand.setCompanyName(companyName);
// brand.setBrandName(brandName);
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法传递对象参数
List<Brand> brands = brandMapper.selectByConditionSingle(brand);
System.out.println(brands);
//释放资源
sqlSession.close();
}
4. 配置文件完成添加功能
4.1 添加数据
上图是添加数据的页面在该页面输入想要的数据后点击 ”提交“ 按钮就会将这些数据添加到数据库中。接下来就来实现添加数据的操作。
(1) 编写 Mapper 接口方法
参数除了 id 之外的所有数据id会自增
结果void
void add(Brand brand);
(2) 编写SQL语句SQL 映射文件
<insert id="add">
insert into tb_brand (brand_name,company_name,ordered,description,status)
values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
(3) 测试
注意插入数据要提交事务
@Test
public void testAdd() throws IOException {
//接收参数
int status = 1;
String companyName = "波导";
String brandName = "波导手机";
String description = "手机中的战斗机";
int ordered = 10;
//封装对象
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setDescription(description);
brand.setOrdered(ordered);
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法传递对象参数
brandMapper.add(brand);
//手动提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
在上面的测试代码中提交事务是必须的否则事务回滚。虽 SQL 执行成功但数据库表中未插入数据。
还有一种自动提交事务的方式
SqlSession sqlSession = sqlSessionFactory.openSession(true);
- openSession()默认开启事务进行增删改操作后需要使用
sqlSession.commit();
手动提交事务 - openSession(true)可以设置为自动提交事务关闭事务
4.2 添加完数据后返回主键
数据添加成功后要想获取数据的 id要在 insert 标签上添加两个属性
- useGeneratedKeys获取自增长的主键值。true 表示获取。
- keyProperty 将获取到的主键值封装到哪个属性
就能在插入数据后获取到 id
brandMapper.add(brand);
System.out.println(brand.getId());
5. 配置文件完成修改功能
5.1 修改全部字段
如图所示是修改页面用户在该页面编辑需要修改的数据点击 “提交” 按钮就会修改数据库中对应的数据。
接下来我们就具体来实现
(1) 编写 Mapper 接口方法
参数所有数据
结果void
void update(Brand brand);
(2) 编写SQL语句SQL映射文件
<update id="update">
update tb_brand
set brand_name =#{brandName},
company_name=#{companyName},
ordered =#{ordered},
description=#{description},
status =#{status}
where id =#{id}
</update>
(3) 测试方法
@Test
public void testUpdate() throws IOException {
//接收参数
int status = 1;
String companyName = "波导";
String brandName = "波导手机";
String description = "波导手机手机中的战斗机";
int ordered = 200;
int id = 7;
//封装对象
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setDescription(description);
brand.setOrdered(ordered);
brand.setId(id);
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法传递对象参数
brandMapper.update(brand);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
5.2 修改动态字段
在上节修改信息时修改的是所有的字段。如果用户修改信息时有的输入框没有输入内容就会导致修改后有的字段为空。
这显然不合理未输入的内容应该保留之前的数据。这就需要用到动态 SQL。
<update id="update">
update tb_brand
<set>
<if test="brandName != null and brandName != '' ">
brand_name =#{brandName},
</if>
<if test="companyName != null and companyName != '' ">
company_name=#{companyName},
</if>
<if test="ordered != null">
ordered =#{ordered},
</if>
<if test="description != null and description != '' ">
description=#{description},
</if>
<if test="status != null">
status =#{status}
</if>
</set>
where id =#{id}
</update>
上面代码用 set 标签而不是 set 关键字的原因
① 若最后一个字段未修改set 语句最后就是逗号语法错误。
② 若所有字段都未修改set 语句就空留一个 set语法错误。
测试
@Test
public void testUpdate() throws IOException {
//接收参数
int status = 0;
String companyName = "波导";
String brandName = "波导手机";
String description = "波导手机手机中的战斗机";
int ordered = 200;
int id = 7;
//封装对象
Brand brand = new Brand();
brand.setStatus(status);
// brand.setCompanyName(companyName);
// brand.setBrandName(brandName);
// brand.setDescription(description);
// brand.setOrdered(ordered);
brand.setId(id);
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法传递对象参数
brandMapper.update(brand);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
6. 配置文件完成删除功能
6.1 删除单条数据
如上图所示每行数据后面都有一个 删除 按钮当用户点击该按钮时就会将该行数据删掉。
这种删除是通过主键 id 删除的因为 id 是表中数据的唯一标识。
接下来就来实现该功能。
(1) 编写 Mapper 接口方法
void deleteById(int id);
(2) 编写 SQL
<delete id="deleteById">
delete from tb_brand where id=#{id};
</delete>
(3) 测试
public void testDeleteById() throws IOException {
//接收参数
int id = 7;
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法传递对象参数
brandMapper.deleteById(id);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
6.2 批量删除数据
如上图所示用户可以选择多条数据然后点击上面的 删除 按钮就会删除数据库中对应的多行数据。
选中复选框并批量删除时会将所有被选中记录的 id 封装成一个数组再遍历数组根据数组中的每个 id 来删除对应的记录。
(1) 编写 Mapper 接口方法
参数id数组
结果void
void deleteByIds(int[] ids);
(2) 编写 SQL
方法 1
<delete id="deleteByIds">
#缺点几个”“不确定
delete from tb_brand
where id in (?.?.?)
</delete>
方法 2
foreach 标签用来迭代任何可迭代的对象如数组集合。
- collection 属性mybatis 会将数组参数封装为一个 Map集合。
默认array = 数组
使用@Param注解改变map集合的默认key的名称 - item 属性本次迭代获取到的元素。
- separator 属性集合项迭代之间的分隔符。foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。
- open 属性该属性值是在拼接SQL语句之前拼接的语句只会拼接一次
- close 属性该属性值是在拼接SQL语句拼接后拼接的语句只会拼接一次
<delete id="deleteByIds">
delete from tb_brand where id
in
<foreach collection="array" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
如果 Mapper 接口方法加上@Param("ids")
注解foreach 的 collection 属性值就能写成 “ids”从而保持与 id 数组名一致。
void deleteByIds(@Param("ids") int[] ids);
<delete id="deleteByIds">
delete from tb_brand where id
in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
假如数组中的 id 数组是 {1,2,3}拼接后的 SQL 语句就是delete from tb_brand where id in (1,2,3)
(3) 测试
@Test
public void testDeleteByIds() throws IOException {
//接收参数
int[] ids = {2,3};
//加载mybatis核心配置文件获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象用它来执行SQL
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取UserMapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//执行方法传递对象参数
brandMapper.deleteByIds(ids);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
7. mybatis 参数传递
Mybatis 接口方法中可以接收各种各样的参数如下
- 多个参数
- 单个参数可以是如下类型
- POJO 类型
- Map 集合类型
- Collection 集合类型
- List 集合类型
- Array 类型
- 其他类型