Mybatis映射器之insert元素解析
1. 概述
insert元素相对于select元素要简单很多,mybatis会在插入之后返回一个整数,表示插入成功后插入的条数,insert元素的属性配置如下:
虽然属性很多,但是我们在实际使用的只有几个,如下就是定义一个插入角色Role的sql语句:
<insert id="insert" parameterType="com.yhl.mybatis.model.Role">
insert into t_role(role_name,note) values (#{roleName,jdbcType=VARCHAR},#{note,jdbcType=VARCHAR})
</insert>
2. 主键回填和自定义
如前所述,插入语句的配置规则更加丰富,在插入语句里面有一些额外的属性和子元素用来处理主键的生成,而且有多种生成方式。
首先,如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就OK了。例如,如果上面的 Role表已经对 id 使用了自动生成的列类型,那么语句可以修改为:
<insert id="insert" parameterType="com.yhl.mybatis.model.Role" useGeneratedKeys="true" keyProperty="id">
insert into t_role(role_name,note) values (#{roleName,jdbcType=VARCHAR},#{note,jdbcType=VARCHAR})
</insert>
如上所示,这样我们在传入Role的时候就无需设置id值了,mybatis会在插入完成后回填JavaBean的id值,后面我们便可以直接使用这个id。接下来我们测试下:
public class Application {
public static void main(String[] args) {
SqlSession session = MybatisUtils.getSqlSession();
RoleMapper mapper = session.getMapper(RoleMapper.class);
Role role = new Role();
role.setRoleName("test2");
role.setNote("test2");
int count =mapper.insert(role);
System.out.println(role.getId());
}
}
最终会输入出插入的role的id。
如果你的数据库还支持多行插入, 你也可以传入一个Roles数组或集合,并返回自动生成的主键。如下sql所示:
<insert id="insertRoles" useGeneratedKeys="true" keyProperty="id">
insert into t_role (role_name,note) values
<foreach item="item" collection="list" separator=",">
(#{item.roleName}, #{item.note})
</foreach>
</insert>
我们在接口中定义方法:
int insertRoles(List<Role> list);
继续测试下上面的方法:
List<Role> roles = new ArrayList<>();
Role role = new Role();
role.setRoleName("list1");
role.setNote("list1");
roles.add(role);
Role role1 = new Role();
role1.setRoleName("list2");
role1.setNote("list2");
roles.add(role1);
int count =mapper.insertRoles(roles);
System.out.println(role.getId());
我们跟踪执行过程,如下图所示,两个role都已经插入成功且id回填了:
3. 不支持自动生成id的
对于不支持自动生成类型的数据库或可能不支持自动生成主键的 JDBC 驱动,MyBatis 有另外一种方法来生成主键。
这里有一个简单(甚至很傻)的示例,它可以生成一个随机 ID(你最好不要这么做,但这里展示了 MyBatis 处理问题的灵活性及其所关心的广度):
<insert id="insert1" parameterType="com.yhl.mybatis.model.Role">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
</selectKey>
insert into t_role (id, role_name, note)
values (#{id}, #{roleName}, #{note})
</insert>
在上面的示例中,selectKey 元素将会首先运行,role的 id 会被设置,然后插入语句会被调用。这给你了一个和数据库中来处理自动生成的主键类似的行为,避免了使 Java 代码变得复杂。
selectKey 元素描述如下:
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
如下图所示: