@TableId 注解用于将某个成员变量指定为数据表主键,以下为使用示例:
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("user")
public class User {@TableId(value = "id")private Integer id;@TableField(value = "name")private String name;
}
下面将介绍 @TableId 注解的属性:
1、value
该属性用于指定数据表主键字段名称,不是必填的,默认为空字符串。上述示例中,将User中的id字段标识为主键,并且对应数据表中的id字段。
2、type
该属性用于指定数据库表主键类型,如:ID自增、UUID等。该属性的值是一个IdType枚举类型,默认为IdType.NONE。
提前构建单元测试,以下所有示例场景全部通用,如下所示:
@Test
public void test(){User user =new User();user.setName("赵六");userMapper.insert(user);
}
2.1 NONE
该类型为 type 属性的默认主键类型,当我们设置@TableId类型为NONE时,且不手动设置主键值,MyBatis Plus将默认给出一个Long类型的数字或字符串(根据主键数据类型变化)。
以下为数据库表主键自增,业务代码未设置主键值:
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(10) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user` (`id`, `name`) values('1','张三');
insert into `user` (`id`, `name`) values('2','李四');
insert into `user` (`id`, `name`) values('3','王五');
执行单元测试,输出日志如下,其中1197658113就是 MyBatis Plus 自动设置的值:
==> Preparing: INSERT INTO user ( id, name ) VALUES ( ?, ? )
==> Parameters: 1197658113(Integer), 赵六(String)
<== Updates: 1
另外当数据库表未设置主键自增,业务代码未设置主键值时,其执行情况和上述情形一样,都是给出一个Long类型的数字或字符串。
2.2 AUTO
特别说明:这种ID生成策略是使用数据库ID自增,在使用该策略的时候一定要确保对应的数据表设置了ID主键自增,否则无效。
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("user")
public class User {@TableId(value = "id", type = IdType.AUTO)private Integer id;@TableField(value = "name")private String name;
}
以下为数据库表未设置主键自增,业务代码未设置主键值:
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` INT(11) NOT NULL,`name` VARCHAR(10) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`, `name`) VALUES('1','张三');
INSERT INTO `user` (`id`, `name`) VALUES('2','李四');
INSERT INTO `user` (`id`, `name`) VALUES('3','王五');
执行单元测试,输出日志会报错,如下所示:
### The error occurred while setting parameters
### SQL: INSERT INTO user ( name ) VALUES ( ? )
### Cause: java.sql.SQLException: Field 'id' doesn't have a default value
; Field 'id' doesn't have a default value; nested exception is java.sql.SQLException: Field 'id' doesn't have a default value
以下为数据库表设置了主键自增,业务代码未设置主键值:
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` INT(11) NOT NULL,`name` VARCHAR(10) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`, `name`) VALUES('1','张三');
INSERT INTO `user` (`id`, `name`) VALUES('2','李四');
INSERT INTO `user` (`id`, `name`) VALUES('3','王五');
执行单元测试,输出日志如下所示(查看数据库表中数据,主键ID正常递增,符合预期):
==> Preparing: INSERT INTO user ( name ) VALUES ( ? )
==> Parameters: 赵六(String)
<== Updates: 1
2.3 INPUT
特别说明:这种ID生成策略,需要将表的自增策略删除掉,侧重点在于由使用者自己设置。如果没有设置主键ID的值,则会报错,错误提示就是主键ID没有给值;如果设置了主键ID,则数据就能添加成功。
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("user")
public class User {@TableId(value = "id", type = IdType.INPUT)private Integer id;@TableField(value = "name")private String name;
}
以下为数据库表未设置主键自增,业务代码未设置主键值:
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` INT(11) NOT NULL,`name` VARCHAR(10) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`, `name`) VALUES('1','张三');
INSERT INTO `user` (`id`, `name`) VALUES('2','李四');
INSERT INTO `user` (`id`, `name`) VALUES('3','王五');
执行单元测试,输出日志会报错,如下所示:
### The error occurred while setting parameters
### SQL: INSERT INTO user ( id, name ) VALUES ( ?, ? )
### Cause: java.sql.SQLIntegrityConstraintViolationException: Column 'id' cannot be null
; Column 'id' cannot be null; nested exception is java.sql.SQLIntegrityConstraintViolationException: Column 'id' cannot be null
以下为数据库表设置了主键自增,业务代码未设置主键值:
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(10) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user` (`id`, `name`) values('1','张三');
insert into `user` (`id`, `name`) values('2','李四');
insert into `user` (`id`, `name`) values('3','王五');
执行单元测试,输出日志如下所示:
==> Preparing: INSERT INTO user ( id, name ) VALUES ( ?, ? )
==> Parameters: null, 赵六(String)
<== Updates: 1
从上面可以日志得知,当我们没有设置主键id值时,MyBatis Plus也不会主动设置该字段的值。但是由于数据库中表定义了主键ID递增,所以还是会执行成功。
2.4 ASSIGN_ID
ASSIGN_ID表示分配ID,要求其主键类型为数字或者字符串,使用接口 IdentifierGenerator 的 nextId 方法(默认实现类为 DefaultIdentifierGenerator 雪花算法)。
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("user")
public class User {@TableId(value = "id", type = IdType.ASSIGN_ID)private Integer id;@TableField(value = "name")private String name;
}
执行单元测试,输出日志如下所示:
==> Preparing: INSERT INTO user ( id, name ) VALUES ( ?, ? )
==> Parameters: 690143233(Integer), 赵六(String)
<== Updates: 1
上面日志中的id字段的值“690143233”是通过调用 DefaultIdentifierGenerator 的 nextId 方法获取。
2.5 ASSIGN_UUID
ASSIGN_UUID表示分配UUID,适用于主键类型为String,使用接口 IdentifierGenerator 的 nextUUID 方法。
构建数据库中user表的数据结构:
CREATE TABLE `user` (`id` varchar(256) NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
构建对应的实体类:
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("user")
public class User {@TableId(value = "id", type = IdType.ASSIGN_UUID)private String id;@TableField(value = "name")private String name;
}
执行单元测试,输出日志如下所示:
==> Preparing: INSERT INTO user ( id, name ) VALUES ( ?, ? )
==> Parameters: 2aa75775d5217f16c4605e9e5074eea1(String), 赵六(String)
<== Updates: 1
上面日志中的“2aa75775d5217f16c4605e9e5074eea1”用户ID是通过IdentifierGenerator的nextUUID方法获得。