Mybatis 获取自增主键值(Mysql,Oracle)
在某些场景下,我们需要使用mybatis返回生成的主键值。Mybatis在insert和update标签中就提供了这种功能。
<insert id=”indetifyId” useGeneratedKeys=”true” keyProperty=”id” keyColumn="id">
</insert>
1
2
3
useGeneratedKeys: 是否自动生成主键,默认false
keyProperty :返回的主键值赋给那个属性
keyColumn: 数据库中的自增主键的列名,默认是数据库表的第一列。当主键列不是表中的第一列的时候需要设置,PostgreSQL必须设置。
主键自动生成,取决于数据库是否支持自增主键。实际上当设置了useGeneratedKeys=“true”,Mybatis会调用JDBC的getGeneratedKeys方法,并将获取的主键值赋值给keyProperty 指定的属性。
准备
Mysql数据库
create table user(
ID bigint not null auto_increment,
USER_NAME varchar(50) not null,
USER_PASSWORD varchar(30) not null,
CREATE_TIME datetime,
....
primary key(ID)
)
1
2
3
4
5
6
7
8
实体
package com.test.User
public class User{
private Long userId;
private String userName;
private String userPassword;
...
setter getter....
}
1
2
3
4
5
6
7
8
9
10
Mapper
public interface UserMapper{
int insertUser(User user); //新增用户
}
1
2
3
Service
@Service
public UserServiceImple implements UserService{
@Autowired
UserMapper userMapper;
public Long inserUser(User user){
//user数据操作,例如加密
int inserts=userMapper.insertUser(user);
if(inserts == 0)//插入失败
return -1L;
return user.getUserId();//返回主键值
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
获取主键值
对于支持主键自增的数据库(MySql)
<insert id=”insertUser” useGeneratedKeys=”true” keyProperty=”userId” >
insert into user(
user_name, user_password, create_time)
values(#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})
</insert>
1
2
3
4
5
parameterType 可以不写,Mybatis可以推断出传入的数据类型。
不支持主键自增的数据库(Oracle)
对于像Oracle这样的数据,没有提供主键自增的功能,而是使用序列的方式获取自增主键。
可以使用<selectKey>标签来获取主键的值,这种方式不仅适用于不提供主键自增功能的数据库,也适用于提供主键自增功能的数据库,
select Key 一般的用法
<selectKey keyColumn="id" resultType="long" keyProperty="id" order="BEFORE">
</selectKey>
1
2
3
属性描述
keyPropertyselectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
keyColumn匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
resultType结果的类型,MyBatis 通常可以推算出来。MyBatis 允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map。
order值可为BEFORE 或 AFTER。如果是 BEFORE,那么它会先执行selectKey设置 keyProperty 然后执行插入语句。如果为AFTER则相反。
statementType使用何种语句类型,默认PREPARED。 有STATEMENT,PREPARED 和 CALLABLE 语句的映射类型。
<insert id=”insertUser” >
<selectKey keyColumn="id" resultType="long" keyProperty="userId" order="BEFORE">
SELECT USER_ID.nextval from dual
</selectKey>
insert into user(
id,user_name, user_password, create_time)
values(#{userId},#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})
</insert>
1
2
3
4
5
6
7
8
resultType 可以不写。
Oracle 数据库中的值要设置为 BEFORE ,这是因为 Oracle中需要先从序列获取值,然后将值作为主键插入到数据库中。
扩展:
如果Mysql 使用selectKey的方式获取主键,需要注意下面两点:
order : AFTER
获取递增主键值 :SELECT LAST_ INSERT_ ID ()