mybatis进行插入操作时,如果表的主键是自增的,针对不同的数据库相应的操作也不同。
- 插入以后,不返回主键:
- Oracle Sequence 配置
1. <sqlid='TABLE_NAME'>TEST_USER</sql>
2. <sqlid='TABLE_SEQUENCE'>SEQ_TEST_USER_ID.nextval</sql>
3.
4. <!-- 注意这里直接调用sequence的nextval函数 -->
5. <insertid="insert"parameterType="User">
6. <includerefid="TABLE_NAME"/> (ID,NAME,AGE)
7. <includerefid="TABLE_SEQUENCE"/> ,#{name}, #{age} )
8. </insert>
当插入语句如上配置时,那么针对如下语句
1. User=newUser();
2. .setName("test");
3. .setAge(24);
4.
5. .insert(user);
6.
System.out.println(user.id);// user.id 为空user.id
- 为空,也就是说如上的配置并不能在完成插入操作后将插入时的主键值存放到保存的对象中。
- Mysql自增主键配置 由于mysql数据库中,可以设置表的主键为自增,所以对于Mysql数据库在mybatis配置插入语句时,不指定插入ID字段即可。主键的自增交由Mysql来管理。
2. <sqlid='TABLE_NAME'>TEST_USER</sql>
3. <!-- 注意这里的插入SQL中是没有指明ID字段的! -->
4. <insertid="insert"parameterType="User">
5. <includerefid="TABLE_NAME"/> (NAME,AGE)
6. values (#{name}, #{age} )
7. </insert>
同样,针对Mysql如此配置mybaits,插入完成后user.id
为空。
2.插入后返回主键值。
使用mybatis提供的<selectKey />
来单独配置针对自增逐渐的处理。
- Oracle Sequence 配置
1. <sqlid='TABLE_NAME'>TEST_USER</sql>
2. <sqlid='TABLE_SEQUENCE'>SEQ_TEST_USER_ID.nextval</sql>
3.
4. <!-- 注意这里需要先查询自增主键值 -->
5. <insertid="insert"parameterType="User">
6. <selectKeykeyProperty="id"resultType="int"order="BEFORE">
7. <includerefid="TABLE_SEQUENCE"/> from dual
8. </selectKey>
9. <includerefid="TABLE_NAME"/> (ID,NAME,AGE)
10. values ( #{id}, #{name}, #{age} )
11. </insert>
当使用了<selectKey />
后,在实际的插入操作时,mybatis会执行以下两句SQL:
1. select.nextval from;// 语句1
2. into(ID,NAME,AGE)(?,?,?);// 语句2
在执行插入 语句2 之前,会先执行 语句1 以获取当前的ID值,然后mybatis使用反射调用User
对象的setId
方法,将 语句1 查询出的值保存在User
对象中,然后才执行 语句2 这样就保证了执行完插入后
1. User=newUser();
2. .setName("test");
3. .setAge(24);
4.
5. .insert(user);
6. System.out.println(user.id);// user.id 不为空
user.id
是有值的。
- Mysql自增主键配置
针对于Mysql这种自己维护主键的数据库,可以直接使用以下配置在插入后获取插入主键,
1. <sqlid='TABLE_NAME'>TEST_USER</sql>
2. <insertid="insert"useGeneratedKeys="true"keyProperty="id"parameterType="User">
3. <includerefid="TABLE_NAME"/> ( NAME, AGE )
4. values ( #{name}, #{age} )
5. </insert>
当然,由于Mysql的自增主键可以通过SQL语句
1. select();
来获取的。因此针对Mysql,Mybatis也可配置如下:
1. <sqlid='TABLE_NAME'>TEST_USER</sql>
2. <!-- 注意这里需要先查询自增主键值 -->
3. <insertid="insert"parameterType="User">
4. <selectKeykeyProperty="id"resultType="int"order="BEFORE">
5. SELECT LAST_INSERT_ID()
6. </selectKey>
7. <includerefid="TABLE_NAME"/> (ID,NAME,AGE)
8. values ( #{id}, #{name}, #{age} )
9. </insert>
只不过该中配置需要额外的一条查询SQL!
3.小结:
- 当数据插入操作不关心插入后数据的主键(唯一标识),那么建议使用 不返回自增主键值 的方式来配置插入语句,这样可以避免额外的SQL开销.
- 当执行插入操作后需要立即获取插入的自增主键值,比如一次操作中保存一对多这种关系的数据,那么就要使用 插入后获取自增主键值 的方式配置.