mybatis的自增返回主键 selectKey、useGeneratedKeys、keyProperty
mybatis的自增返回主键的两种方式
- 第一种:使用 selectKey标签,如下所示
<?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="user">
<!-- 插入操作 -->
<insert id="insertUser1" parameterType="com.java.src.pojo.User">
<!--
keyproperty:返回的数据是pojo对象的哪个属性
resultType:返回数据类型
order:定义此条SQL是在主SQL前还是后运行 after/before:后/前
-->
<selectKey keyProperty="id" resultType="string" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
INSERT INTO `user` (`id`, `username`, `birthday`, `gender`, `address`) VALUES (#{id}, #{username}, #{birthday}, #{gender}, #{address})
</insert>
</mapper>
此种方式是在主SQL前或后定义一个执行的方法,这个方法可以是任何方法,因此我们使用这种方式可以在主SQL运行完后在运行一下查询插入数据的id值并将其返回;
- 第二种:使用useGenerateKeys、keyproperty来简便设定自增并返回主键
代码如下:
<?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="user">
<!--
插入操作
useGeneratedKeys:开启自增
keyProperty:自增返回数据名称
-->
<insert id="insertUser2" parameterType="com.java.src.pojo.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `user` (`id`, `username`, `birthday`, `gender`, `address`) VALUES (#{id}, #{username}, #{birthday}, #{gender}, #{address})
</insert>
</mapper>
-
注意:
当使用第一种方法时返回的自增对象(以ID为例)必须是int类型的,否则会返回的都是“0”,如果ID类型为varchar类型的,最好使用第二种;如下图:
id类型不为int时: -
使用第一种(
<selectKey>)

-
使用第二种(
useGeneratedKeys、keyProperty)

所以,建议一般尽量使用第二种,既简单有足够完善~
sqlSessionUtils
package com.java.src.utils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class sqlSessionUtils {
private static SqlSession sqlSession;
static{
try {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
// 创建获取到sql语句配置文件的输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 使用sql语句配置文件的输入流对象配合SqlSessionFactoryBuilder对象创建sqlSessionFactory(sqlsession工厂)对象
SqlSessionFactory sqlSessionFactory = ssfb.build(resourceAsStream);
// 创建sqlsession工厂的对象 true:开启自动提交事务
sqlSession = sqlSessionFactory.openSession(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
return sqlSession;
}
}
Error:
sqlSessionUtils 这个工具类中存在一个错误,如下代码:
// 创建sqlsession工厂的对象 true:开启自动提交事务
sqlSession = sqlSessionFactory.openSession(true);
错误在于sqlSession这个对象不是线程安全的,而且每个线程都需要有各自的这个对象,虽然把它抽取出来放到工具类中也能运行,但是存在隐患问题,错误就放在这了,不改了,用以惊醒!

浙公网安备 33010602011771号