一、主键生成方式
1、支持主键自增,例如:MySQL数据库
2、不支持主键自增,例如:Oracle 数据库
常见需求:插入一条新数据,立马获取新数据的主键,然后查询这条数据
二、原生 JDBC 中的主键生成
在原生 JDBC 中有这样一个方法
conn.prepareStatement(sql, autoGeneratedKeys)
statement.execute(sql, autoGeneratedKeys)
使用重载的 prepareStatement(sql, flag) 来生成 preparedStatement 对象
//使用重载的prepareStatement(sql,flag)来生成prepareStatement对象
// int RETURN_GENERATED_KEYS = 1;
//在插入的同时获得数据的主键值
preparedStatement = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
这个方法可以让数据库自动生成主键
//通过getGeneratedKeys()方法,获取了新生成的主键resultset对象
ResultSet rs = preparedStatement.getGeneratedKeys();
ResultSet rs = statement.getGeneratedKeys();
这个方法可以获取一个结果集,这个里面就包括了主键值
//通过getGenerateKeys获取包含了新生成主键的ResultSet对象
//在ResultSet中只有一列GENERATED_KEY,用于存放新生成的主键值。
resultSet = preparedStatement.getGeneratedKeys();
if(resultSet.next()){
System.out.println(resultSet.getObject(1));
}
注意: 前提是数据表的主键是自动增加的,取得数据库自动生成的主键。
三、获取主键值
1、支持主键自增
若数据支持自动生成主键的字段(比如:mysql 和 SQLServer),则可以设置 useGeneratedKeys="true",然后再把 keyProperty 设置到目标属性上
mysql支持自增主键,自增主键值的获取,mybatis也是利用statement.getGenreatedKeys();useGeneratedKeys="true";使用自增主键获取主键值策略;keyProperty;指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性
<!-- public void insertEmp(Emp emp); -->
<!--
useGeneratedKeys:可以使用自动生成的主键
keyProperty:将自动生成的主键赋值给传递过来的参数的哪一个属性
-->
<insert id="insertEmp" useGeneratedKeys="true" keyProperty="eid" databaseId="mysql">
<!-- insert into emp values(null, #{ename}, #{age}, #{sex}) -->
insert into emp values(null, '${ename}', ${age}, '${sex}')
</insert>
2、获取非自增主键的值
Oracle不支持自增;Oracle使用序列来模拟自增;
每次插入的数据的主键是从序列中拿到的值;如何获取到这个值;
select EMPLOYEES_SEQ.nextval from dual 从emp表的序列中获取下一个主键的值
nextval 获取下一个主键的值
currval 获取当前记录的主键的值
而对于不支持自增型主键的数据库(如 Oracle),则可以使用 selectKey 子元素:
selectKey 标签用于从序列中获取主键的值;
keyProperty:查出的主键值封装给javaBean的哪个属性
resultType:查出的数据的返回值类型
order="BEFORE":当前sql在插入sql之前运行
AFTER:当前sql在插入sql之后运行
(1)方式一:BEFOR 运行顺序
在插入数据之前,先运行selectKey查询id的sql;查出id值封装给javaBean的id属性;
再运行插入的SQL;就可以取出JavaBean对象 id 属性对应的值。
Demo:
<insert id="insertEmployee" parameterType="Emp" databaseId="oracle">
<selectKey order="BEFORE" keyProperty="id" resultType="Integer">
select employee_seq.nextval from dual <!-- 查询主键的SQL语句 -->
</selectKey>
insert into orcl_employee(id,last_name,email,gender) values(#{id},#{lastName},#{email},#{gender})
</insert>
(2)方式二:AFTER 运行顺序
先运行插入的SQL语句(从序列中取出新值作为id),再运行selectKey 查询 id 的SQL(获取序列的当前值)。
Demo:
<insert id="insertEmployee" parameterType="Emp" databaseId="oracle">
<selectKey order="AFTER" keyProperty="id" resultType="Integer">
select employee_seq.currval from dual
</selectKey>
insert into orcl_employee(id,last_name,email,gender) values(employee_seq.nextval,#{lastName},#{email},#{gender})
</insert>
四、selectKey 的常用属性