前言
每种数据库都有自己的主键生成方式,比如MySQL
支持自增的主键, 在插入数据后自动生成主键, 比如Oracle
通过序列的方式, 在插入数据之前生成主键, 再写去表中。
环境准备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public interface UserMapper { int insert(User User); } public class User { Long id; String name; } public class MyTest { @Test public void testInsert() throws IOException { Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader); try(SqlSession sqlSession = factory.openSession()){ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setName("测试用户"); System.out.println(user); int result = userMapper.insert(user); Assert.assertEquals(1, result); Assert.assertNotNull(user.getId()); System.out.println(user); } } }
|
使用JDBC的useGeneratedKeys获取主键值
只支持插入数据后生成主键的数据库。如MySQL
和SQLServer
。
底层是使用了JDBC
的statement.getGeneratedKeys()
。
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ahao.demo.mapper.UserMapper"> <insert id="insert" useGeneratedKeys="true" keyProperty="id"> insert sys_user(id, name) values (#{id}, #{name}) </insert> </mapper>
|
使用selectKey获取主键值
useGeneratedKeys
局限于主键自增的数据库, 不支持Oracle
这种先生成主键, 再把主键插入数据库中的形式。
selectKey
两者都支持, 缺点就是比较笨重, 需要写多一点xml
代码。
1 2 3 4 5 6 7 8 9 10
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ahao.demo.mapper.UserMapper"> <insert id="insert"> <selectKey keyProperty="id" keyColumn="id" resultType="Long" order="AFTER"> select LAST_INSERT_ID() </selectKey> insert sys_user(id, name) values (#{id}, #{name}) </insert> </mapper>
|
keyProperty
指的是实体的field
名称, keyColumn
指的是数据表的column
名称, resultType
指定返回的Java
类型。
order
分为AFTER
和BEFORE
, 因为MySQL
中, 主键是在插入数据之后生成的, 所以选择AFTER
。Oracle
则要选Before
。
需要注意的是, selectKey
的位置不会影响结果, 最好是根据实际情况来选择放置位置, 比如MySQL
就放在SQL
之前, 表示先生成主键后插入数据。
各数据库回写主键的SQL
- MySQL:
SELECT LAST_INSERT_ID()
- Sql Server:
SELECT SCOPE_IDENTITY()
- Oracle:
SELECT SEQ_ID.nextval from dual
- Db2:
VALUES IDENTITY_VAL_LOCAL()
- HSQLDB:
CALL IDENTITY()
不使用实体类获取主键