点击链接了解有关MyBatis映射器说明
1.MyBatis insert标签
1.1 insert标签
MyBatis insert 标签用来定义插入语句,执行插入操作。当 MyBatis 执行完一条插入语句后,就会返回其影响数据库的行数。
下面通过一个示例演示 insert 标签的具体用法。
1.修改 PetMapper.xml,增加插入语句,代码如下
java"><insert id="insert" parameterType="String">
insert into pets (name) values(#{name})
</insert>
2.在 PetMapper接口中定义一个 insert() 方法,代码如下
java">public int insert(String name);
参数为 Sting 类型的字符串;返回值为 int 类型,即执行 SQL 后,插入记录的行数。
3.测试代码如下
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
int i = session.getMapper(PetMapper.class).delete1(8);
System.out.println("删除了"+i+"行记录!");
}
1.2 insert 标签常用属性
insert 标签中常用的属性如下表。
属性名称 | 描述 | 备注 |
---|---|---|
id | 它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用 | 如果命名空间+ id 不唯一,那么 MyBatis 抛出异常 |
parameterType | 传入 SQL 语句的参数类型的全限定名或别名,它是一个可选属性。 | 支持基本数据类型和 JavaBean、Map 等复杂数据类型 |
keyProperty | 该属性的作用是将插入操作的返回值赋给 PO 类的某个属性,通常为主键对应的属性。如果是联合主键,可以将多个值用逗号隔开。 | - |
useGeneratedKe | 该属性用来设置,是否使用 JDBC 提供的 getGenereatedKeys() 方法,获取数据库内部产生的主键并赋值到 keyProperty 属性设置的请求对象的属性中,例如 MySQL、SQL Server 等自动递增的字段,其默认值为 false。 | 该属性值设置为 true 后,会将数据库生成的主键回填到请求对象中,以供其他业务使用。 |
flushCache | 该属性用于设置执行该操作后,是否会清空二级缓存和本地缓存,默认值为 true。 | - |
timeout | 该属性用于设置执行该操作的最大时限,如果超时,就抛异常。 | - |
databaseId | 取值范围 oracle、mysql 等,表示数据库厂家;元素内部可通过 来为特定数据库指定不同的 sql 语句。 | MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。 |
keyColumn | 该属性用于设置第几列是主键,当主键列不是表中的第 1 列时,就需要设置该属性。如果是联合主键,可以将多个值用逗号隔开。 | - |
注意:
insert 标签中没有 resultType 属性,只有查询操作才需要对返回结果类型进行相应的指定。
1.3 传递多个参数
在上面的示例中,我们在插入语句中只使用了一个 String 类型的参数,而在实际的开发过程中,我们的插入语句往往需要使用多个参数,Mybatis 为我们提供以下 3 种方式,来实现给映射器传递多个参数:
- 使用 Map 传递参数
- 使用注解传递参数
- 使用 JavaBean 传递参数
1.4 使用 Map 传递参数
我们可以将参数封装到一个 Map 对象中,然后传递给 MyBatis 的映射器,示例如下。
- 在 PetMapper接口中,定义一个 insert1() 方法,并使用 Map 传递参数,方法如下
java">public int insert1(Map<String,Object> map);
- 在 PetMapper.xml 中,使用 insert 标签定义一条插入语句,并接收通过 Map 传递的参数,配置如下
java"><insert id="insert1" parameterType="Map" useGeneratedKeys="true">
insert into pets(name,species,age) values (#{name},#{species},#{age})
</insert>
- 测试代码如下
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
PetMapper mapper = session.getMapper(PetMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("name","旺财");
map.put("species","Dog");
map.put("age",5);
int i = mapper.insert1(map);
System.out.println(i);
}
- 执行测试代码,控制台输出如下。
java">[org.mybatis.mapper.PetMapper.insert1]-==> Preparing: insert into pets(name,species,age) values (?,?,?)
[org.mybatis.mapper.PetMapper.insert1]-==> Parameters: 旺财(String), Dog(String), 5(Integer)
[org.mybatis.mapper.PetMapper.insert1]-<== Updates: 1
1
通过 Map 成功向数据库中添加了 1 条记录
1.5 使用注解传递参数
我们还可以使用 MyBatis 提供的 @Param 注解给注解器传递参数,示例代码如下。
1.在 PetMapper接口中,定义一个 insert2() 方法,并使用 @Param 注解传递参数,方法如下
java">public int insert2(@Param("name") String name,@Param("species") String species,@Param("age") int age);
2.在 StudentMapper.xml 中使用 insert 标签定义一条插入语句,并接收通过 @Param 注解传递的参数,配置如下
java"><insert id="insert2">
insert into pets(name,species,age) values (#{name},#{species},#{age})
</insert>
3.测试代码如下
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
int i = session.getMapper(PetMapper.class).insert2("小黑", "Cat", 3);
System.out.println(i);
}
1.6 使用 JavaBean 传递参数
在参数过多的情况下,我们可以将参数通过 setter 方法封装到 JavaBean(实体类)对象中 ,传递给映射器。
1.在 PetMapper 接口中,定义一个 insert3() 方法,并使用 JavaBean 传递参数,方法如下。
java">public int insert3(Pet pet);
2.在 PetMapper.xml 中使用 insert 标签定义一条插入语句,并接收通过 JavaBean 传递的参数,配置如下。
java"><insert id="insert3" parameterType="Pet">
insert into pets(name,species,age) values (#{name},#{species},#{age})
</insert>
3.测试代码如下
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
Pet pet = new Pet();
pet.setName("CC");
pet.setSpecies("Dog");
pet.setAge(5);
int i = session.getMapper(PetMapper.class).insert3(pet);
System.out.println(i);
}
1.7 主键(自动递增)回填
我们知道,MySQL、SQL Server 等数据库表可以采用自动递增的字段作为其主键,当向这样的数据库表插入数据时,即使不指定自增主键的值,数据库也会根据自增规则自动生成主键并插入到表中。
一些特殊情况下,我们可能需要将这个刚刚生成的主键回填到请求对象(原本不包含主键信息的请求对象)中,供其他业务使用。此时,我们就可以通过在 insert 标签中添加 keyProperty 和 useGeneratedKeys 属性,来实现该功能。
下面我们通过一个示例,来演示主键(自动递增)回填功能。
7.1 为 PetMapper.xml 中 id 为 Student的 insert 标签添加 keyProperty 和 useGeneratedKeys 属性,具体代码如下:
java"><insert id="insert4" parameterType="Pet" keyProperty="id" useGeneratedKeys="true">
insert into pets(name,species,age) values (#{name},#{species},#{age})
</insert>
7.2 测试代码如下:
java"> public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
Pet pet = new Pet();
pet.setName("小B");
pet.setSpecies("Dog");
pet.setAge(3);
int i = session.getMapper(PetMapper.class).insert4(pet);
System.out.println("插入了" + i + "条记录,内容为:\t" + pet);
}
}
7.3 执行测试代码,控制台输出如下。
java">[org.mybatis.mapper.PetMapper.insert4]-==> Preparing: insert into pets(name,species,age) values (?,?,?)
[org.mybatis.mapper.PetMapper.insert4]-==> Parameters: 小B(String), Dog(String), 3(Integer)
[org.mybatis.mapper.PetMapper.insert4]-<== Updates: 1
插入了1条记录,内容为: Pet(id=20, name=小B, species=Dog, age=3)
2.MyBatis delete标签
2.1 delete标签
MyBatis delete 标签用于定义 delete 语句,执行删除操作。当 MyBatis 执行完一条更新语句后,会返回一个整数,表示受影响的数据库记录的行数。
下面我们通过一个示例演示 delete 标签的用法。
1.在 PetMapper.xml 中添加以一条 delete 语句,代码如下。
<delete id="delete1" parameterType="Int">
delete from pets where id = #{id}
</delete>
2.在 PetMapper接口中增加一个 delete1() 方法,代码如下。
java">public int delete1(int id);
3.参数为 id类型的整数;返回值为 int 类型,表示执行 sql 语句后,被删除记录的行数,测试代码如下。
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
int i = session.getMapper(PetMapper.class).delete1(8);
System.out.println("删除了"+i+"行记录!");
}
2.2delete 标签常用属性
属性名称 | 描述 | 备注 |
---|---|---|
id | 它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用 | 如果命名空间+ id 不唯一,那么 MyBatis 抛出异常 |
parameterType | 传入 SQL 语句的参数类型的全限定名或别名,它是一个可选属性。 | 支持基本数据类型和 JavaBean、Map 等复杂数据类型 |
flushCache | 该属性用于设置执行该操作后,是否会清空二级缓存和本地缓存,默认值为 true。 | - |
timeout | 该属性用于设置 SQL 执行的超时时间,如果超时,就抛异常。 | - |
statementType | 执行 SQL 时使用的 statement 类型, 默认为 PREPARED,可选值:STATEMENT,PREPARED 和 CALLABLE。 | - |
注意:delete 标签中没有 resultType 属性,只有查询操作才需要对返回结果类型进行相应的指定。
2.3 传递多个参数
在上面的示例中,我们在delete语句中只使用了一个 Int 类型的参数,而在实际的开发过程中,大多数时候,我们的更新语句都需要使用多个参数,Mybatis 为我们提供以下 3 种方式,来实现给映射器传递多个参数:
- 使用 Map 传递参数
- 使用注解传递参数
- 使用 JavaBean 传递参数
2.4 使用 Map 传递参数
我们可以将参数封装到一个 Map 对象中,然后传递给 MyBatis 的映射器,示例如下。
1.在 PetMapper接口中,定义一个 delete2() 方法,并使用 Map 传递参数,代码如下。
java">public int delete2(Map<String,Object> map);
2.在 PetMapper.xml 使用 delete 标签定义一个 delete 语句,并接收通过 Map 传递的参数,代码如下。
java"><delete id="delete2" parameterType="Map">
delete from pets where name = #{name} and age = #{age}
</delete>
3.测试代码如下。
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
Map<String,Object> map = new HashMap<>();
map.put("name","旺财");
map.put("age",7);
int i = session.getMapper(PetMapper.class).delete2(map);
System.out.println("删除了"+i+"行记录!");
}
2.5 使用注解传递参数
我们还可以使用 MyBatis 提供的 @Param 注解给注解器传递参数,示例如下。
1.在 PetMapper接口中,定义一个 delete3() 方法,并使用 @Param 注解传递参数,方法如下。
java">public int delete3(@Param("name") String name,@Param("age") int age);
2.在 PetMapper.xml 中使用 delete 标签定义一个 delete 语句,并接收通过 @Param 注解传递的参数,配置如下。
java"> <delete id="delete3">
delete from pets where name = #{name} or age > #{age}
</delete>
3.测试代码如下。
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
int i = session.getMapper(PetMapper.class).delete3("小黑", 7);
System.out.println("删除了"+i+"行记录!");
}
2.6 使用 JavaBean 传递参数
在参数过多的情况下,我们还可以将参数通过 setter 方法封装到 JavaBean(实体类)对象中传递给映射器。
1.在 PetMapper接口中,定义一个 delete4() 方法,并使用 JavaBean 传递参数,方法如下。
java">public int delete4(Pet pet);
2.在 PetMapper.xml 中使用 delete 标签定义一个 delete 语句,并接收通过 JavaBean 传递的参数,配置如下。
java"><delete id="delete3" parameterType="Pet">
delete from pets where name = #{name} or age > #{age}
</delete>
3.测试代码如下。
java"> public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
Pet pet = new Pet();
pet.setName("小黑");
pet.setAge(7);
int i = session.getMapper(PetMapper.class).delete4(pet);
System.out.println("删除了"+i+"行记录!");
}
3.MyBatis update标签
3.1 update标签
MyBatis update 标签用于定义更新语句,执行更新操作。当 MyBatis 执行完一条更新语句后,会返回一个整数,表示受影响的数据库记录的行数。
下面我们通过一个示例演示 update 标签的用法。
1.在 PetMapper.xml 中添加以下更新语句,代码如下。
java"> <update id="update1" >
update pets set name = "BB" where id = #{id}
</update>
2.在接口中增加一个 update1() 方法,代码如下。
java">public int update1(int id);
3.参数为 Int类型的字符串;返回值为 int 类型,表示执行 sql 语句后受影响的记录的行数,测试代码如下。
java"> public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
int i = session.getMapper(PetMapper.class).update1(13);
System.out.println("更新了"+i+"条数据!");
}
3.2 update 标签常用属性
属性名称 | 描述 | 备注 |
---|---|---|
id | 它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用 | 如果命名空间+ id 不唯一,那么 MyBatis 抛出异常 |
parameterType | 传入 SQL 语句的参数类型的全限定名或别名,它是一个可选属性。 | 支持基本数据类型和 JavaBean、Map 等复杂数据类型 |
flushCache | 该属性用于设置执行该操作后,是否会清空二级缓存和本地缓存,默认值为 true。 | - |
timeout | 该属性用于设置 SQL 执行的超时时间,如果超时,就抛异常。 | - |
statementType | 执行 SQL 时使用的 statement 类型, 默认为 PREPARED,可选值:STATEMENT,PREPARED 和 CALLABLE。 | - |
注意:
update 标签中没有 resultType 属性,只有查询操作才需要对返回结果类型进行相应的指定。
3.3 传递多个参数
在上面的示例中,我们在更新语句中只使用了一个 String 类型的参数,而在实际的开发过程中,大多数时候,我们的更新语句都需要使用多个参数,Mybatis 为我们提供以下 3 种方式,来实现给映射器传递多个参数:
- 使用 Map 传递参数
- 使用注解传递参数
- 使用 JavaBean 传递参数
3.4 使用 Map 传递参数
我们可以将参数封装到一个 Map 对象中,然后传递给 MyBatis 的映射器,示例如下。
1.在 PetMapper接口中,定义一个 update2() 方法,并使用 Map 传递参数,代码如下。
java">public int update2(Map<String,Object> map);
2.在 PetMapper.xml 使用 update 标签定义一个 update 语句,并接收通过 Map 传递的参数,代码如下。
java"> <update id="update2" parameterType="Map" >
update pets set species = #{species} where id = #{id}
</update>
3.测试代码如下。
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
Map<String,Object> map = new HashMap<>();
map.put("species","Cat");
map.put("id",13);
int i = session.getMapper(PetMapper.class).update2(map);
System.out.println("更新了"+i+"条数据!");
}
3.5 使用注解传递参数
我们还可以使用 MyBatis 提供的 @Param 注解给注解器传递参数,示例如下。
1.在 PetMapper接口中,定义一个 update3() 方法,并使用 @Param 注解传递参数,方法如下。
java">public int update3(@Param("name") String name,@Param("age") int age,@Param("id") int id);
2.在 PetMapper.xml 中使用 update 标签定义一个 update3 语句,并接收通过 @Param 注解传递的参数,配置如下。
java"><update id="update3">
update pets set name = #{name},age = #{age} where id = #{id}
</update>
3.测试代码如下。
java"> public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
int i = session.getMapper(PetMapper.class).update3("老黄", 10, 15);
System.out.println("更新了"+i+"条数据!");
}
3.6 使用 JavaBean 传递参数
在参数过多的情况下,我们还可以将参数通过 setter 方法封装到 JavaBean(实体类)对象中传递给映射器。
1.在 PetMapper接口中,定义一个 update4() 方法,并使用 JavaBean 传递参数,方法如下。
java">public int update4(Pet pet);
2.在 PetMapper.xml 中使用 update4 标签定义一个 update 语句,并接收通过 JavaBean 传递的参数,配置如下。
java"> <update id="update4" parameterType="Pet" >
update pets set name = #{name},species = #{species} where id = #{id}
</update>
3.测试代码如下。
java">public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
Pet pet = new Pet();
pet.setName("黑子");
pet.setSpecies("Dog");
pet.setId(2);
int i = session.getMapper(PetMapper.class).update4(pet);
System.out.println("更新了"+i+"条数据!");
}
4.MyBatis select标签语法
4.1 MyBatis的select标签
在 MyBatis 中,select 标签是最常用也是功能最强大的 SQL 语言,用于执行查询操作。
select 示例语句如下。
<mapper namespace="org.mybatis.example.mapper.StudentMapper">
<select id="select" resultType="Student">
select * from student
</select>
</mapper>
标签参数说明:
**1.id:**为sql语句起一个映射器的名字,与namespace共同使用,整个项目中namespace+id的名字不能重复
**2.resultType:**返回数据类型,返回数据类型可以为java的类型,也可以为sql的数据类型,如果返回实体类型,会自动为实体映射列和实体属性,如果为自定义类型定义了别名(mybati配置文件),可以直接使用别名(类名)。
案例:需要对表中姓名为张三的数据进行查询,张三是参数
1.在StudentMapper中添加以下查询语句,代码如下。
<select id="select1" resultType="Student" parameterType="String">
select * from student where stu_name=#{name}
</select>
**标签参数说明:**parameterType:参数类型,一个参数就不需要考虑参数名称
2.在StudentMapper接口中增加一个 select1() 方法,代码如下。
java">public List<Student> select1(String name);
3.测试代码如下
java"> public static void main(String[] args) {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
List<Student> list = session.getMapper(PetMapper.class).select1("张三");
list.forEach(system.out::println);
}
4.运行测试结果如下
java">[org.mybatis.example.mapper.StudentMapper.select1]-==> Preparing: select * from student where stu_name=?
[org.mybatis.example.mapper.StudentMapper.select1]-==> Parameters: 张三(String)
[org.mybatis.example.mapper.StudentMapper.select1]-<== Total: 1
Student(stu_id=1, stu_name=张三, stu_age=20, stu_des=一个好人, version=1)
4.2 select标签常用属性
属性名称 | 描述 | 备注 |
---|---|---|
parameterType | 表示传入 SQL 语句传入参数类型的全限定名或别名。它是一个可选属性,MyBatis 能推断出具体传入语句的参数 | 支持基本数据类型和 JavaBean、Map 等复杂数据类型 |
resultType | SQL 语句执行后返回的类型(全限定名或者别名)。如果是集合类型,返回的是集合元素的类型,返回时可以使用 resultType 或 resultMap 之一 | - |
resultMap | 它是映射集的引用,与 元素一起使用,返回时可以使用 resultType 或 resultMap 之一 | 是 MyBatis 最复杂的元素,可以配置映射规则、级联、typeHandler 等 |
flushCache | 用于设置在调用 SQL 语句后是否要求 MyBatis 清空之前查询的本地缓存和二级缓存 | 用于设置在调用 SQL 语句后是否要求 MyBatis 清空之前查询的本地缓存和二级缓存 默认值为 false,如果设置为 true,则任何时候只要 SQL 语句被调用都将清空本地缓存和二级缓存 |
useCache | 启动二级缓存的开关,默认值为 true,表示将査询结果存入二级缓存中 | - |
timeout | 用于设置超时参数,单位是秒(s),超时将抛出异常 | - |
fetchSize | 获取记录的总条数设定 | 默认值是数据库厂商提供的 JDBC 驱动所设置的条数 |
statementType | 告诉 MyBatis 使用哪个 JDBC 的 Statement 工作,取值为 STATEMENT(Statement)、 PREPARED(PreparedStatement)、CALLABLE(CallableStatement) | - |
resultSetType | 这是针对 JDBC 的 ResultSet 接口而言,其值可设置为 FORWARD_ONLY(只允许向前访问)、SCROLL_SENSITIVE(双向滚动,但不及时更新)、SCROLLJNSENSITIVE(双向滚动,及时更新) | - |
4.3 传递多个参数
现在需要根据 id 和 name 来模糊查询网站信息,显然这涉及到了两个参数。给映射器传递多个参数分为以下三种方法。
- 使用Map传递参数
- 使用注解传递参数
- 使用JavaBean传递参数
4.4 使用Map传递参数
1.使用 MyBatis 提供的 Map 接口作为参数实现,如下所示。
<select id="selectByMap" parameterType="Map" resultType="Student">
select * from student where stu_name=#{name} and stu_age=#{age}
</select>
2.在 StudentMapper接口中,方法如下。
java">public Student selectByMap(Map<String,Object> map);
3.测试代码如下。
java"> public static void main(String[] args) throws IOException {
@Cleanup
SqlSession session = SqlSessionUtil.openSession();
Map<String,Object> map = new HashMap<>();
map.put("name","张三");
map.put("age",18);
List<Student> list = session.getMapper(PetMapper.class).selectByMap(map);
list.forEach(system.out::println);
}
注意:
使用 Map 传递参数虽然简单易用,但是由于这样设置参数需要键值对应,业务关联性不强,开发人员需要深入到程序中看代码,造成可读性下降。
4.5 使用注解传递参数
1.使用 MyBatis 的注解 @Param() 传递参数,如下所示。
<select id="selectByMap" parameterType="map" resultType="Student">
select * from student where stu_name=#{name} and stu_age=#{age}
</select>
2.StudentMapper 接口中方法如下。
java">public List<Student> selectStu(@Param("name") String name, @Param("age") Integer age);
当我们把参数传递给后台时,MyBatis 通过 @Param 提供的名称就会知道 #{name} 代表 name 参数,提高了参数可读性。但是如果这条 SQL 拥有 10 个参数的查询,就会造成可读性下降,增强了代码复杂性。实现代码和增加删除更新类似。
4.6 使用JavaBean传递参数
1.在参数过多的情况下,MyBatis 允许组织一个 JavaBean,通过简单的 setter 和 getter 方法设置参数,提高可读性。如下所示。
<select id="selectStudent" resultType="Student">
select * from student where stu_name=#{stu_name}
</select>
2.StudentMapper 接口中方法如下。
java">public List<Student> selectStudent(Student stu);
这就是通过 JavaBean 传递多个参数的方式。
5.有关多个参数使用的区别
以上标签的多种参数传递3 种方式的区别如下。
- 使用 Map 传递参数会导致业务可读性的丧失,继而导致后续扩展和维护的困难,所以在实际应用中我们应该果断废弃该方式。
- 使用 @Param 注解传递参数会受到参数个数的影响。当 n≤5 时,它是最佳的传参方式,因为它更加直观;当 n>5 时,多个参数将给调用带来困难。
- 当参数个数大于 5 个时,建议使用 JavaBean 方式。
6.有关标签参数与方法返回值总结
参数个数 | 参数设置 |
---|---|
0/1个参数 | 标签中可以不用写参数类型,底层默认Object类型进行隐式转换 或者设置parameterType为参数对应的数据类型 |
两个参数 | 设置parameterType=“Map”,设置key和value的数据类型,方法中传入的实参是map集合,通过map.put设置K和V的值 |
多个参数 | 方法一 :使用@Param(“实际参数名”)注解 方法二:设置参数类型为实体类 parameterType=“entity.*”,通过set方法设置参数值,方法中的参数为实体类的类对象 |
返回值个数 | 参数设置 |
---|---|
1个 | 设置返回值为实体类entity.* |
多个 | 设置返回值为实体类entity.*的List集合 |