方法1:使用select last_insert_id()
方法1例子
1、实体类User对象
public class User {
private long id;
private String name;
private String password;
private String phone;
private boolean is_lock;
//省略get set方法
}
2、接口Mapper中的插入方法
public long create(User user)
3、mybatis中Mapper方法对应的xml
<insert id="create">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long" parameterType="com.amiu.entity.User">
select last_insert_id()
</selectKey>
insert into user(id,name,password,phone,is_lock) values (#{id},#{name},#{password},#{phone},#{is_lock})
</insert>
方法1说明
xml说明
意图:将insert插入的数据的主键返回到User对象中; 1、select last_insert_id():得到刚insert进去记录的主键值,只适用于自增主键,
last_insert_id()
是特定的写法;
2、keyProperty:将查询到的主键值,注入到parameterType指定的对象User
的id
属性中 3、order:select last_insert_id()执行顺序,相对于insert语句来说它的执行顺序。本例是AFTER
,也就是说在插入完成后获取主键的值 4、resultType:指定select last_insert_id()的结果类型,也就是id的类型;
方法1重点说明
- select last_insert_id() 只适用于自增主键
- keyProperty="id" 这个“id”是你的Bean的字段,如这里,是我们的User对象的字段“id”
- mybatis直接将我们的insert的id写入了User的字段“id”中;
- 我们获取所插入的id不是Mapper中的方法create(User user)的返回值
- 最终获取的ID
- 我们获取所插入的id不是Mapper中的方法create(User user)的返回值: long id = mapper.create(user); 是错的,这里返回的是
影响的行数
,也就是说一般返回1(插入一行)或0(未成功插入) 这里应该是 : long effectRows = mapper.create(user); - 我们获取所插入的id已经存到了user对象的“id”字段中,所以应该这么获取: mapper.create(user); user.getId(); 是对的,这里返回了插入的id
- 我们获取所插入的id不是Mapper中的方法create(User user)的返回值: long id = mapper.create(user); 是错的,这里返回的是
select last_insert_id()中的坑
在接口Mapper中,有时我们会这么写:
public long create(@Param("user")User user);
我们加上了@Param注解,对应的xml中这么写:
insert into user(id,name,password,phone,is_lock) values (#{user.id},#{user.name},#{user.password},#{user.phone},#{user.is_lock})
这么写的话last_insert_id()是不会成功的,似乎我们添加了@Param("user")后,mybatis就无法找到user插入返回id了,但是数据库中插入的行数是有更新的; 所以select last_insert_id()中的坑就是:如果我们使用last_insert_id()就不能使用注解@Param 有时可能@Param注解是必须的,那么我们可以用方法2
方法2:不使用select last_insert_id()
当有特殊情况,必须使用@Param(),而且要返回插入id应该怎么做呢,我们还有一种方法能返回插入id
接口Mapper中:
public void create(@Param("user")User user);
xml中
<insert id="create" parameterType="com.amiu.shiro.db.User" useGeneratedKeys="true" keyProperty="user.id" >
insert into user(id,name,password,phone,is_lock) values (#{id},#{name},#{password},#{phone},#{is_lock})
</insert>
xml要点
1、parameterType="com.amiu.shiro.db.User" 返回id所接收的类,必须写全,类中存在的字段,insert语句中也必须写全 2、keyProperty="user.id"传回的id存放的字段,user是Mapper中的参数 引用传来的参数user的属性,必须写user.xxx 3、虽然id是自增的,但是我们下面也得写上 insert into user(id) values(#{user.id}) 4、可直接写INSERT INTO user VALUES(xxx),必定插入本表的所有字段
parameterType
:传入参数,也是ID接收参数,如本例是:create(@Param("user")User user),中的参数useruseGeneratedKeys
:是否使用id自增keyProperty
:传回的id存放在user中的哪个字段中,本例是id字段 特别提醒,如遇到数据库order这样的字段,要加上insert into user(order
)(数据库保留字)
以上的方法也能返回插入id,并且能起别名,但是也有一个缺点,就是不能有返回值,如果我们加上 resultType="java.lang.Long",会报错,暂时还不知道是否能解决。