这次坑让我知道一个之前没想到过得知识点:
select last_insert_id()只能获取按照默认键方式插入的记录的key。
可以先做个测试,然后再来看下面的天坑,觉得啰嗦的可以直接看坑
建表语句
CREATE TABLE
goods3(
goodsIdINT(11) NOT NULL AUTO_INCREMENT,
goodsNameVARCHAR(20) NOT NULL,
goodsPriceDOUBLE DEFAULT NULL,
goodsStateINT(1) DEFAULT '1', PRIMARY KEY (
goodsId) ) ENGINE=INNODB DEFAULT CHARSET=utf8
连续两次以default作为key的形式插入值,每次插完都调用
SELECT LAST_INSERT_ID()
INSERT INTO goods3 VALUES(DEFAULT,'wdnm',DEFAULT,DEFAULT)
SELECT LAST_INSERT_ID() #值为1
INSERT INTO goods3 VALUES(DEFAULT,'wdnm',DEFAULT,DEFAULT)
SELECT LAST_INSERT_ID() #值为2
然后我们再试着不用default来插入一下试试
INSERT INTO goods3 VALUES(1000,'wdnm',DEFAULT,DEFAULT)
SELECT LAST_INSERT_ID()
#值还是为2,说明我们自定义主键的这次插入并没有使得LAST_INSERT_ID()的值变化
获取主键有两种方法,一种是在insert里面写useGeneratedKeys和keyProperty;
另一种是使用标签,先看几组测试,再说遇到的坑
使用第一种获取主键的方法
先看看用标签来获取的,坑就是在这里踩的
TestA1
先利用default插入,可以发现,确实是得到了返回的key
<insert id="insertIntoGoods3" parameterType="bean.GoodsInfo">
<selectKey resultType="java.lang.Integer" keyProperty="goodsId"
order="AFTER">
select last_insert_id()
</selectKey>
insert into goods values(default,#{
goodsName},default ,default)
</insert>
public void Method1WithNoId(){
InputStream in = Goods1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in);
SqlSession session = ssf.openSession();
GoodsMapper gm = session.getMapper(GoodsMapper.class);
GoodsInfo gi = new GoodsInfo();
gi.setGoodsName("戒骄戒躁");
gm.insertIntoGoods3(gi);
session.commit();
System.out.println("返回的主键为:"+gi.getGoodsId());
}
然后我们试着用自己传入的主键来插入值,
TestA2
<insert id="insertIntoGoods4" parameterType="bean.GoodsInfo">
<selectKey resultType="java.lang.Integer" keyProperty="goodsId"
order="AFTER">
select last_insert_id()
</selectKey>
insert into goods values(#{
goodsId},#{
goodsName},default ,default)
</insert>
public void Method1WithId(){
InputStream in = Goods1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in);
SqlSession session = ssf.openSession();
GoodsMapper gm = session.getMapper(GoodsMapper.class);
GoodsInfo gi = new GoodsInfo();
gi.setGoodsId(1000);
gi.setGoodsName("戒骄戒躁");
gm.insertIntoGoods4(gi);
session.commit();
System.out.println("返回的主键为:"+gi.getGoodsId());
}
有没有觉得很神奇,当时不知道select last_insert_id()只能查找按照default插入的值的,我纠结了很久为啥返回个主键是0.
但是,使用下面这种方法就可以规避上面的返回值是0的情况,它这种是直接使用JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键,所以就算是自己写的主键也可以正常返回。
TestB1
<insert id="insertIntoGoods1" parameterType="bean.GoodsInfo"
useGeneratedKeys="true" keyProperty="goodsId">
insert into goods values(default ,#{
goodsName},default ,default)
</insert>
//调用使用default的方法
public void Method1WithNoId(){
InputStream in = Goods1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in);
SqlSession session = ssf.openSession();
GoodsMapper gm = session.getMapper(GoodsMapper.class);
GoodsInfo gi = new GoodsInfo();
gi.setGoodsName("戒骄戒躁");
gm.insertIntoGoods1(gi);
session.commit();
System.out.println("返回的主键为:"+gi.getGoodsId());
}
TestB2
<!--这里相对于上面唯一的改变就是把values中的default改成goodsId-->
<insert id="insertIntoGoods2" parameterType="bean.GoodsInfo" useGeneratedKeys="true" keyProperty="goodsId">
insert into goods values(#{
goodsId} ,#{
goodsName},default ,default)
</insert>
public void Method1WithId(){
InputStream in = Goods1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in);
SqlSession session = ssf.openSession();
GoodsMapper gm = session.getMapper(GoodsMapper.class);
GoodsInfo gi = new GoodsInfo();
gi.setGoodsId(10);
gi.setGoodsName("戒骄戒躁");
gm.insertIntoGoods2(gi);
session.commit();
System.out.println("返回的主键为:"+gi.getGoodsId());
}