Fork me on GitHub

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这个对象不是线程安全的,而且每个线程都需要有各自的这个对象,虽然把它抽取出来放到工具类中也能运行,但是存在隐患问题,错误就放在这了,不改了,用以惊醒!





posted @ 2020-04-27 20:06  90后程序猿  阅读(598)  评论(0)    收藏  举报
/* 看板娘 */