Mybatis- 使用数据库产生的主键

281 阅读2分钟
  1. 需求分析:
    当数据库的主键使用自增主键的时候, 希望在通过 Mybatis 插入数据后, 能够获取到这个由数据库产生的主键.

  2. 自增主键示例代码:

    /**
     * 用户实体
     */
    public class User {
        private Integer id;
        private String name;
        
        // 省略其它代码
    }
    
    /**
     * Mapper 接口
     */
    public interface UserMapper {
        int insert(User user);
    }
    
    <!--Xml 文件配置-->
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user(
                    id,
                    username
                    )
             VALUES (
                    #{id},
                    #{username}
                    )
    </insert>
    
    /**
     * 测试代码
     */
    @Test
    public void testInsert() {
        // 省略获取 Mapper 代码
        User user = new User();
        user.setName("test");
        userMapper.insert(user);
        // 因为 insert 会获取到数据库的自增 id, 所以这里 id 不为空
        Assert.assertNotNull(user.getId());
    }
    

    这里的关键配置是 Xml 文件中的: useGeneratedKeys="true" keyProperty="id". 在将 useGeneratedKeys 设置为 true 后, Mybatis 会使用 JDBC 的 getGeneratedKeys 方法取出由数据库内部生成的主键. 获得主键值后将其赋值给 keyProperty 配置的 id 属性. 当需要设置多个属性时, 使用逗号隔开, 这种情况下还需要设置 keyColumn 属性, 按顺序制定数据库的列, 这里的列值和 keyPropery 配置的属性一一对应. 上面的配置适用于支持自增主键的数据库, 如 MySQL.

  3. 非自增主键示例代码:

    <insert id="insert">
        <selectKey keyColumn="id" resultType="int" keyProperty="id" order="BEFORE">
            SELECT SEQ_ID.nextval FROM dual
        </selectKey>
        INSERT INTO user(
                    id,
                    username
                    )
             VALUES (
                    #{id},
                    #{username}
                    )
    </insert>
    

    这里 selectKey 的执行顺序为 BEFORE, 因此它先于 insert 语句执行. 在它执行之后, insert 语句中的 id 就有值了, 这里必须制定 keyColumn 属性.

    也可以使用 selectKey 来改写上面 MySQL 的代码:

    <insert id="insert">
        INSERT INTO user(
                    username
                    )
             VALUES (
                    #{username}
                    )
        <selectKey keyColumn="id" resultType="int" keyProperty="id" order="AFTER">
            SELECT 1274316
        </selectKey>
    </insert>
    

    这里 selectKey 的 order 属性为 AFTER, 表示它在 insert 语句执行后执行. 在执行 insert 语句后, 数据库已经自动产生了一个 id, 然后通过查询语句将这个 id 的值查询出来, 赋值给 id 属性.

  4. 参考:
    [1] : MyBatis从入门到精通