Mybatis实战 之 获取主键
首先在Mybatis 在执行增、删、改操作时允许返回的值有:Integer、Long、Boolean、void。因而我们可以根据特定的业务需求来获取特定的返回值。下面我们来学习一下Mybatis 在执行insert 语句时是如何获得主键值的。
实例
首先我们需要清楚一点:Mysql 默认支持自增主键,Oracle 不支持自增主键。因而要获取insert语句后的主键值需要至少一下两种处理方法。
Mysql 获取自增主键。
由于Mysql支持获取自增主键,因而在Mybatis的实现上较为简单,下面是一个例子:Mapper.xml
<insert id="insertSelective" parameterType="com.sstps.market.entity.Product" useGeneratedKeys="true" keyProperty="pid"> insert into products <trim prefix="(" suffix=")" suffixOverrides=","> <if test="pid != null"> pid, </if> <if test="pname != null"> pname, </if> <if test="type != null"> type, </if> <if test="price != null"> price, </if> <if test="createTime != null"> createTime, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="pid != null"> #{pid,jdbcType=INTEGER}, </if> <if test="pname != null"> #{pname,jdbcType=VARCHAR}, </if> <if test="type != null"> #{type,jdbcType=VARCHAR}, </if> <if test="price != null"> #{price,jdbcType=DOUBLE}, </if> <if test="createTime != null"> #{createTime,jdbcType=TIMESTAMP}, </if> </trim> </insert>
Java
int ret = martkeService.insertSelective(product); System.out.println("获取自增主键:"+product.getPid());
小结
Mysql 获取自增主键需要使用 useGeneratedKeys=”true” 和 keyProperty=”pid”(pid 为POJO中的属性对应在DB中表的主键字段)
使用POJO 入参,执行SQL语句之后直接通过POJO 获取主键值即product.getPid(),MyBatis会自动地把自增主键封装到POJO对象中即product对象中。
Oracle 获取非自增主键。
由于Oracle 不支持自增主键,因而需要做一些特殊处理。我们知道在Oracle中插入一条数据对应的主键Id是从序列中获得的,因而我们可以再执行语句前后获取这一个特定的序列值。
在执行语句前获得主键值:
Mapper
<insert id="insertSelective" parameterType="com.sstps.market.entity.Product" > <selectKey keyProperty="pid" order="BEFORE" resultType="Integer"> <!-- 从dual序列中获取下一个可用值,并将其封装给 Product POJO 的 pid 属性,因而在执行语句时,我们直接使用POJO 入参即可--> select products_seq.nextval from dual </selectKey> insert into products <trim prefix="(" suffix=")" suffixOverrides=","> <if test="pid != null"> pid, </if> <if test="pname != null"> pname, </if> <if test="type != null"> type, </if> <if test="price != null"> price, </if> <if test="createTime != null"> createTime, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="pid != null"> #{pid,jdbcType=INTEGER}, </if> <if test="pname != null"> #{pname,jdbcType=VARCHAR}, </if> <if test="type != null"> #{type,jdbcType=VARCHAR}, </if> <if test="price != null"> #{price,jdbcType=DOUBLE}, </if> <if test="createTime != null"> #{createTime,jdbcType=TIMESTAMP}, </if> </trim> </insert>
Java
int ret = martkeService.insertSelective(product); System.out.println("获取自增主键:"+product.getPid());
小结
- 在使用BEFORE(执行SQL语句前获得主键值)时,我们需要从dual序列中获取下一个可用值,并将其封装给 Product POJO 的 pid 属性,因而在执行语句时,我们直接使用POJO 入参即可。
在执行语句后获得主键值:
Mapper
<insert id="insertSelective" parameterType="com.sstps.market.entity.Product" > <selectKey keyProperty="pid" order="AFTER" resultType="Integer"> <!-- 先执行SQL语句,其中主键pid由 products_seq.nextval 获得,然后通过 products_seq.currval 获得当前序列值,然后将该序列值封装到Product POJO 中的 pid 属性中 --> select products_seq.currval from dual </selectKey> insert into products <trim prefix="(" suffix=")" suffixOverrides=","> <if test="pid != null"> pid, </if> <if test="pname != null"> pname, </if> <if test="type != null"> type, </if> <if test="price != null"> price, </if> <if test="createTime != null"> createTime, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="pid != null"> <!-- products 为表名 --> #{products_seq.nextval}, </if> <if test="pname != null"> #{pname,jdbcType=VARCHAR}, </if> <if test="type != null"> #{type,jdbcType=VARCHAR}, </if> <if test="price != null"> #{price,jdbcType=DOUBLE}, </if> <if test="createTime != null"> #{createTime,jdbcType=TIMESTAMP}, </if> </trim> </insert>
Java
int ret = martkeService.insertSelective(product); System.out.println("获取自增主键:"+product.getPid());
小结
在使用AFTER(先执行SQL语句然后获取主键值)时先执行SQL语句,其中主键pid由 products_seq.nextval 获得,然后通过 products_seq.currval 获得当前序列值,然后将该序列值封装到Product POJO 中的 pid 属性中
小结
- 在使用Mybatis 获取执行语句返回的主键值时需要对不同的数据路类型做不同的处理。