findbetter.me

Just to find a better me

insert主键返回 selectKey使用

有时候新增一条数据,知道新增成功即可,但是有时候,需要这条新增数据的主键,以便逻辑使用,再将其查询出来明显不符合要求,效率也变低了。

这时候,通过一些设置,mybatis可以将insert的数据的主键返回,直接拿到新增数据的主键,以便后续使用。

这里主要说的是selectKey标签

设计表的时候有两种主键,一种自增主键,一般为int类型,一种为非自增的主键,例如用uuid等。

首先说自增类型的主键。

1  映射xml中添加如下代码,注释写的很清楚了,不多做赘述。

 

[html] view plain copy
 
  1. <!--新增信息,并拿到新增信息的表主键信息。  
  2.     新增数据,得到主键的外层写法没什么特别,跟普通的insert一样。只不过里面加了selectKey-->  
  3. <insert id="insertAndgetkey" parameterType="com.soft.mybatis.model.User">  
  4.     <!--selectKey  会将 SELECT LAST_INSERT_ID()的结果放入到传入的model的主键里面,  
  5.         keyProperty 对应的model中的主键的属性名,这里是 user 中的id,因为它跟数据库的主键对应  
  6.         order AFTER 表示 SELECT LAST_INSERT_ID() 在insert执行之后执行,多用与自增主键,  
  7.               BEFORE 表示 SELECT LAST_INSERT_ID() 在insert执行之前执行,这样的话就拿不到主键了,  
  8.                     这种适合那种主键不是自增的类型  
  9.         resultType 主键类型 -->  
  10.     <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">  
  11.         SELECT LAST_INSERT_ID()  
  12.     </selectKey>  
  13.     insert into t_user (username,password,create_date) values(#{username},#{password},#{createDate})  
  14. </insert>  

2 接口 UserDao

[java] view plain copy
 
  1. /** 
  2.  * 新增用户信息,并得到新增数据的主键 
  3.  *      主键自增 
  4.  * @return 
  5.  */  
  6. int insertAndGeyKey(User user);  


3 实现类 UserDaoImpl

 

[java] view plain copy
 
  1. public int insertAndGeyKey(User user) {  
  2.     SqlSession sqlSession = null;  
  3.     try {  
  4.         sqlSession = SqlsessionUtil.getSqlSession();  
  5.         int key =  sqlSession.insert("test.insertAndgetkey",user);  
  6.         // commit  
  7.         sqlSession.commit();  
  8.         return key;  
  9.     } catch (Exception e) {  
  10.         sqlSession.rollback();  
  11.         e.printStackTrace();  
  12.     } finally {  
  13.         SqlsessionUtil.closeSession(sqlSession);  
  14.     }  
  15.     return 0;  
  16. }  

接下来就是测试了,

UserDaoTest

[java] view plain copy
 
  1. /** 
  2.  * 注意,user.xml中已经说过,selectKey会将得到的主键放入model的主键属性中, 
  3.  * 所以这里获取主键的方法一定是通过model.get主键才能获取新增的主键 
  4.  * @throws Exception 
  5.  */  
  6. @Test  
  7. public void insertAndGeyKey() throws Exception {  
  8.     User user = new User();  
  9.     user.setUsername("新增得到主键5");  
  10.     user.setPassword("123456");  
  11.     user.setCreateDate(new Date());  
  12.     int  result = dao.insertAndGeyKey(user);  
  13.     System.out.println("insertAndGeyKey :" + result);  
  14.     // 获取新增数据主键  
  15.     System.out.println("新增数据的主键 :" + user.getId());  
  16. }  

数据库表新增数据主键为 34 



junit测试结果  得到主键 34  测试成功。

 

2 自增主键的获取方法,说完了,下面来讲讲非自增主键的获取方法。大致一样,些许不同。

由于只有一张表,这里又新建了一张表,对应的xml,别忘了将新建的xml添加到sqlMapConfig.xml中。

[html] view plain copy
 
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper  
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  5. <!-- namespace命名空间,有种java package的感觉,sql隔离,这个名字必须唯一  
  6. 并且不能省略不写也不能为空,不过名字倒是可以随意,只要不跟另外一个文件中的名字一样即可-->  
  7. <mapper namespace="customer">  
  8.   
  9.     <!-- 跟普通的insert没有什么不同的地方 -->  
  10.     <insert id="insert" parameterType="com.soft.mybatis.model.Customer">  
  11.         <!-- 跟自增主键方式相比,这里的不同之处只有两点  
  12.                     1  insert语句需要写id字段了,并且 values里面也不能省略  
  13.                     2 selectKey 的order属性需要写成BEFORE 因为这样才能将生成的uuid主键放入到model中,  
  14.                     这样后面的insert的values里面的id才不会获取为空  
  15.               跟自增主键相比就这点区别,当然了这里的获取主键id的方式为 select uuid()  
  16.               当然也可以另写别生成函数。-->  
  17.         <selectKey keyProperty="id" order="BEFORE" resultType="String">  
  18.             select uuid()  
  19.         </selectKey>  
  20.         insert into t_customer (id,c_name,c_sex,c_ceroNo,c_ceroType,c_age)  
  21.         values (#{id},#{name},#{sex},#{ceroNo},#{ceroType},#{age})  
  22.     </insert>  
  23. </mapper>  


接口  CustomerDao

 

[java] view plain copy
 
  1. package com.soft.mybatis.dao;  
  2.   
  3. import com.soft.mybatis.model.Customer;  
  4.   
  5. /** 
  6.  * Created by xuweiwei on 2017/9/10. 
  7.  */  
  8. public interface CustomerDao {  
  9.   
  10.     int add(Customer customer);  
  11. }  

实现类 CustomerDaoImpl

 

[java] view plain copy
 
  1. package com.soft.mybatis.dao.impl;  
  2.   
  3. import com.soft.mybatis.Util.SqlsessionUtil;  
  4. import com.soft.mybatis.dao.CustomerDao;  
  5. import com.soft.mybatis.model.Customer;  
  6. import org.apache.ibatis.session.SqlSession;  
  7.   
  8. /** 
  9.  * Created by xuweiwei on 2017/9/10. 
  10.  */  
  11. public class CustomerDaoImpl implements CustomerDao {  
  12.   
  13.     public int add(Customer customer) {  
  14.         SqlSession sqlSession = null;  
  15.         try {  
  16.             sqlSession = SqlsessionUtil.getSqlSession();  
  17.             int key =  sqlSession.insert("customer.insert", customer);  
  18.             // commit  
  19.             sqlSession.commit();  
  20.             return key;  
  21.         } catch (Exception e) {  
  22.             sqlSession.rollback();  
  23.             e.printStackTrace();  
  24.         } finally {  
  25.             SqlsessionUtil.closeSession(sqlSession);  
  26.         }  
  27.         return 0;  
  28.     }  
  29. }  

准备工作完毕,下面进行测试。

执行前的数据 

测试类  CustomerDaoImplTest

 

[java] view plain copy
 
  1. package com.soft.mybatis.dao.impl;  
  2.   
  3. import com.soft.mybatis.dao.CustomerDao;  
  4. import com.soft.mybatis.model.Customer;  
  5. import org.junit.Test;  
  6.   
  7. import static org.junit.Assert.*;  
  8.   
  9. /** 
  10.  * Created by xuweiwei on 2017/9/10. 
  11.  */  
  12. public class CustomerDaoImplTest {  
  13.     private CustomerDao customerDao = new CustomerDaoImpl();  
  14.   
  15.     @Test  
  16.     public void add() throws Exception {  
  17.         Customer customer = new Customer();  
  18.         customer.setName("全球鹰1");  
  19.         customer.setAge(15);  
  20.         customer.setCeroNo("888888888888");  
  21.         customer.setCeroType(2);  
  22.         customer.setSex(1);  
  23.         int result = customerDao.add(customer);  
  24.         System.out.println("插入结果 : "+result);  
  25.         System.out.println("插入主键id : "+customer.getId());  
  26.     }  
  27.   
  28. }  

测试结果


数据库

可以看到新增的数据的主键已经获取到了。

注意点:获取主键,一定要从穿进去的model中获取。

附  新增customer表的建表ddl

 

[java] view plain copy
 
    1. CREATE TABLE `t_customer` (  
    2.   `id` varchar(50) NOT NULL,  
    3.   `c_name` varchar(20) DEFAULT NULL COMMENT '姓名',  
    4.   `c_sex` tinyint(4) DEFAULT NULL COMMENT '性别',  
    5.   `c_ceroNo` varchar(18) DEFAULT NULL COMMENT '证件号码',  
    6.   `c_ceroType` tinyint(4) DEFAULT NULL COMMENT '1 身份证 2其他',  
    7.   `c_age` int(3) DEFAULT NULL COMMENT '年龄',  
    8.   PRIMARY KEY (`id`)  
    9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8  
posted @ 2019-04-21 22:33  FindBetterMe  阅读(210)  评论(0编辑  收藏  举报