MyBatis(四)映射文件 之 主键生成策略

一、主键生成方式

  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 的常用属性

  

原文地址:https://www.cnblogs.com/niujifei/p/15228015.html