MyBatis中的主键生成策略

在数据库(MySQL,Oracle…)中,我们都会为每张表设置主键。主键也是一个字段,只不过为其赋予非空唯一的特性。
主键的作用是保证一张表中的数据唯一性。

这次我们使用用户表介绍在使用MyBatis向数据库表新增数据(一条或者多条)时,主键该怎么设置?
在Java项目中,主键对应的Java类型一般是Integer,Long或者String。

建表及插值SQL语句

CREATE TABLE `sys_user` (
  `id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `user_name` varchar(255) DEFAULT NULL COMMENT '用户名',
  `user_password` varchar(255) DEFAULT NULL COMMENT '密码',
  `user_email` varchar(255) COMMENT '邮箱',
  `user_info` text COMMENT '简介',
  `head_img` blob COMMENT '头像',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

-- 这里我们先手动插入6条数据,default表示为创建该表时每个字段的默认值,now()获取当前时间
INSERT INTO `sys_user` VALUES (DEFAULT, 'admin', 'admin', default, '管理员', "", NOW());
INSERT INTO `sys_user` VALUES (DEFAULT, 'xq', 'xq', default, '开发者', "", NOW());
INSERT INTO `sys_user` VALUES (DEFAULT, 'zs', 'zs', default, '开发者', "", NOW());
INSERT INTO `sys_user` VALUES (DEFAULT, 'ls', 'ls', default, '运维人员', "", NOW());
INSERT INTO `sys_user` VALUES (DEFAULT, 'ww', 'ww', default, '运维人员', "", NOW());
INSERT INTO `sys_user` VALUES (DEFAULT, 'zl', 'zl', default, '运维人员', "", NOW());

用户实体类

创建用户表对应的实体类,我们可以使用MyBatis逆向工程生成或者MyBatis-Plus自动代码生成。

/**
 * 用户实体类
 */
@Data
public class SysUser{
	/**
	 * ID
	 */
	private Long id;
	/**
	 * 用户名
	 */
	private String userName;
	/**
	 * 密码
	 */
	private String userPassword;
	/**
	 * 邮箱
	 */
	private String userEmail;
	/**
	 * 简介
	 */
	private String userInfo;
	/**
	 * 头像
	 */
	private byte[] headImg;
	/**
	 * 创建时间
	 */
	private Date createTime;
}

这里单独使用MyBatis,没有结合其他框架来使用。简单介绍我们在开发中如何使用MyBatis。

  1. 根据需求创建表
  2. 根据表创建实体类
  3. 创建Mapper接口(编写各种增删改查接口方法)
  4. 创建Mapper.xml(编写各种增删改查SQL语句)
  5. 结合Junit单元测试框架测试

由于是介绍MyBatis中的主键生成策略,所以只需要编写新增接口方法,以及编写新增SQL语句。

SysUserMapper接口

public interface SysUserMapper {
    /**
     * 新增用户
     * @param user
     */
    int insertSysUser(SysUser user);
}

SysUserMapper.xml

mapper标签的namespace属性值需要写上面接口的全限定路径,这样MyBatis才能将Mapper接口绑定Mapper.xml。
哈哈,这里先给出Mapper.xml模板代码,具体的SQL语句在下面再给出。

<?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="cn.zwq.mybatis.mapper.SysUserMapper">
	
</mapper

接下来就是重点了,MyBatis中的主键生成策略有几种方式,我们将一 一介绍。

1.使用JDBC方式返回主键自增的值

这种方式只适用支持主键自增的数据库,比如:MySQL,SQL Server。如果数据库不支持主键自增,那么这种方式就不适用了,比如:Oracle
insert标签是让我们编写新增SQL语句。类似的还有select标签、update标签和delete标签。
下图是insert标签中的属性,红色框中是比较常用的属性。
在这里插入图片描述

<insert id="insertSysUser" useGeneratedKeys="true" keyProperty="id" >
    insert into sys_user(user_name,user_password,user_email,user_info,head_img,create_time) 
    values (
	    #{userName},
	    #{userPassword},
	    default,
	    #{userInfo},
	    #{headImg,jdbcType=BLOB},
	    #{createTime,jdbcType=TIMESTAMP}
    );
</insert>

在上面代码中,新增数据的时候没有为主键id设置值,而是设置了一些属性,就是这些属性能帮我们自动获取主键的值(主键自增长)。
下面讲解这些属性的作用:

  1. insert标签的id属性就是Mapper接口方法,上面通过namespace绑定接口,这里通过id绑定接口方法。
  2. 上面我们将useGeneratedKeys属性设置为true, MyBatis会使用JDBC getGeneratedKeys方法来取出由数据库内部生成的主键。
  3. 获得主键值后将其赋值给keyProperty属性配置的id属性(实体类中的属性)。当需要设置多个属性时,使用逗号隔开,这种情况下通常还需要设置 keyColumn 属性按顺序指定数据库的列,这里列的值会和 keyProperty 配置的属性一一对应。

2.使用selectKey返回主键的值

有些数据库(比如:Oracle)不提供主键自增的功能,而是使用序列得到一个值,然后将这个值赋给主键id ,再将数据插入数据库。对于这种情况 ,我们使用<selectKey>标签来获取主键的值,这种方式不仅适用于不提供主键自增功能的数据库,也适用于提供主键自增功能的数据库。

这里分别演示MySQL和Oracle两个数据库在这种方式下的主键生成方式。

MySQL

上面接口方法不变,只是改变insert标签代码。我们可以看到useGeneratedKeys属性和keyProperty属性不用设置了。改为添加selectKey标签

  1. selectKey标签的keyColumn、keyProperty和上面useGeneratedKeys的用法含义相同。
  2. resultType属性用于设置返回值类型。
  3. order属性的设置和使用的数据库有关。MySQL数据库中,order属性设置的值是AFTER,因为当前记录的主键值在insert语句执行成功后才能获取。
<insert id="insertSysUser">
    insert into sys_user(user_name,user_password,user_email,user_info,head_img,create_time)
    values (
        #{userName},
        #{userPassword},
        default,
        #{userInfo},
        #{headImg,jdbcType=BLOB},
        #{createTime,jdbcType=TIMESTAMP}
    );
    <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
        SELECT LAST_INSERT_ID ()
    </selectKey>
</insert>

Oracle

我们可以看到,在Oracle数据库中,order属性设置为BEFORE,这是因为Oracle中需要先从序列获取值,然后将值作为主键插入到数据库中。

Oracle方式的insert语句中明确写出了id列和值#{id},因为执行selectKey中的语句后id就有值了,我们需要把这个序列值作为主键值插入到数据库中,所以必须指定id列,如果不指定这一列,数据库就会因为主键不能为空而抛出异常。

selectKey元素放置的位置不会影响selectKey中的方法在insert前面或者后面执行的顺序,影响执行顺序的是order属性。

<insert id="insertSysUser">
    <selectKey keyColumn="id" resultType="long" keyProperty="id" order="BEFORE">
        SELECT SEQ_ID.nextval from dual
    </selectKey>
    insert into sys_user(id,user_name,user_password,user_email,user_info,head_img,create_time)
    values (
        #{id},
        #{userName},
        #{userPassword},
        default,
        #{userInfo},
        #{headImg,jdbcType=BLOB},
        #{createTime,jdbcType=TIMESTAMP}
    );
</insert>

假如主键是varchar类型,那么对应Java就是String类型,这个时候就不需要使用MyBatis的主键生成策略。我们在新增数据时,直接为主键赋值即可,一般是使用java.util.UUID生成32位位不规则不重复的字符串来充当主键。

这样我们就介绍了我们在使用MyBatis时,对主键的处理方式。大家觉得🆗的话,不妨来个👍。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mybatis-plus提供了多种主键生成策略,常用的有以下几种: 1. 默认的主键生成策略:使用数据库自增长方式生成主键。对于MySQL数据库,使用AUTO_INCREMENT关键字,对于Oracle数据库,使用SEQUENCE序列。 2. UUID主键生成策略:使用Java的UUID类生成主键生成主键是32位的16进制字符串,不重复且无序。 3. 雪花算法主键生成策略:雪花算法是Twitter开源的一个分布式ID生成算法,可以保证在分布式环境下生成的ID全局唯一且有序。 在使用mybatis-plus时,可以通过注解@TableId和@TableField来指定主键和字段的属性,包括主键生成策略。例如: ``` @TableId(value = "id", type = IdType.AUTO) private Long id; @TableId(value = "uuid", type = IdType.UUID) private String uuid; @TableId(value = "id", type = IdType.ID_WORKER) private Long idWorker; @TableId(value = "id", type = IdType.SNOWFLAKE) private Long snowflakeId; ``` 其,@TableId注解的value属性指定了数据库表对应的字段名,type属性指定了主键生成策略MyBatis-Plus是一个基于MyBatis的增强工具,提供了许多方便开发的特性和功能,可以大大减少我们在开发的代码量和复杂度。 以下是使用MyBatis-Plus的主要策略: 1. 使用代码生成器:MyBatis-Plus提供了一个代码生成器,可以自动生成Mapper、Entity和Service层的代码,大大减少了手写代码的工作量。我们只需要配置好生成器的相关信息,就可以快速生成我们需要的代码。 2. 使用MyBatis-Plus的BaseMapper:MyBatis-Plus的BaseMapper提供了很多基础的CRUD操作,如selectById、selectBatchIds、insert、update、delete等,可以大大减少我们手写Mapper的工作量。同时,我们也可以扩展BaseMapper,添加自定义的方法。 3. 使用MyBatis-Plus的Wrapper:MyBatis-Plus的Wrapper提供了一种更加灵活的查询方式,可以通过构建Wrapper对象来构造复杂的查询条件。Wrapper可以用于查询、更新和删除操作。 4. 使用MyBatis-Plus的分页插件:MyBatis-Plus提供了一个分页插件,可以方便地进行分页查询操作。我们只需要在Mapper接口定义对应的方法,然后在Service层调用即可。 5. 使用MyBatis-Plus的自动填充功能:MyBatis-Plus的自动填充功能可以自动为我们的实体类填充一些公共字段,如创建时间、更新时间等。我们只需要在实体类定义对应的字段和注解,就可以自动填充这些字段。 总的来说,MyBatis-Plus是一个非常方便实用的工具,可以大大提高我们的开发效率和代码质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值