generatedvalue mysql_2.3 generatedvalue

2.3 主键策略

在 2.2 中介绍了所有其他注解的作用和用法,由于主键策略比较复杂,单独用一节来阐述。

首先主键策略和数据库关系很大,有些数据库支持主键自增,而有些数据库只能通过序列来获得。

新增的@KeySql 注解用于替换 @GeneratedValue 注解,因此 @KeySql 能以更简单方式实现原来的功能,下面的示例都先使用 @KeySql 进行配置,然后在使用 @GeneratedValue,大家可以自己选择。

2.3.1 JDBC 支持通过 getGeneratedKeys 方法取回主键的情况

这种情况首先需要数据库支持自增,其次数据库提供的 JDBC 支持 getGeneratedKeys 方法。

常见的如 MySql,SqlServer 支持这种模式。

这种情况下,配置主键策略最简单。

用法如下:

@Id

@KeySql(useGeneratedKeys = true)

private Long id;

或:

@Id

@GeneratedValue(generator = "JDBC")

private Long id;

为了让大家容易理解这里配置和 MyBatis 写法的关系,大家可以看看对应生成的 XML 代码:

insert into country (id, countryname, countrycode)

values (#{id},#{countryname},#{countrycode})

SqlServer 中使用时,需要设置 id 的 insertable=false

2.3.2 支持自增的数据库

支持自增的数据库列表如下:

DB2: VALUES IDENTITY_VAL_LOCAL()

MYSQL: SELECT LAST_INSERT_ID()

SQLSERVER: SELECT SCOPE_IDENTITY()

CLOUDSCAPE: VALUES IDENTITY_VAL_LOCAL()

DERBY: VALUES IDENTITY_VAL_LOCAL()

HSQLDB: CALL IDENTITY()

SYBASE: SELECT @@IDENTITY

DB2_MF: SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1

INFORMIX: select dbinfo('sqlca.sqlerrd1') from systables where tabid=1

这个列表只是列举了比较常见的数据库,其他类似的也支持。

列表数据库名字后面对应的 SQL 是插入后取 id 的 SQL 语句。

这类数据库主键策略配置示例如下:

@Id

//DEFAULT 需要配合 IDENTITY 参数(ORDER默认AFTER)

@KeySql(dialect = IdentityDialect.DEFAULT)

private Integer id;

//建议直接指定数据库

@Id

@KeySql(dialect = IdentityDialect.MYSQL)

private Integer id;

或:

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Integer id;

@GeneratedValue 用法还要配合 IDENTITY 参数(以及 ORDER 参数),这个参数值需要配置为对应的数据库,就是上面列表中的名字,具体的配置方法看后面章节的内容。

这种配置对应的 XML 形式为:

SELECT LAST_INSERT_ID()

insert into country (id, countryname, countrycode)

values (#{id},#{countryname},#{countrycode})

IDENTITY 参数以及 ORDER 参数会决定 selectKey 中的 SQL 和 order 属性的值(这里是 AFTER)。

2.3.3 通过序列和任意 SQL 获取主键值

像 Oracle 中通过序列获取主键就属于这种情况,实际上 2.3.2 中的 SQL 也可以在这里配置。

除了类似序列获取值外,还可以是获取 UUID 的 SQL 语句,例如 select uuid()。

2.3.3 和 2.3.2 的区别主要在于,2.3.2 是插入表之后才有 id 的值,2.3.3 是插入数据库前需要获取一个值作为主键。

在 Oracle 中,我们可以用下面的方式进行配置:

@Id

@KeySql(sql = "select SEQ_ID.nextval from dual", order = ORDER.BEFORE)

private Integer id;

或:

@Id

@GeneratedValue(

strategy = GenerationType.IDENTITY,

generator = "select SEQ_ID.nextval from dual")

private Integer id;

使用 @GeneratedValue 时也要配置一个 ORDER 全局参数,2.3.2 中提到的 AFTER,在 2.3.3 中需要配置为 BEFORE,具体配置方式看后面章节的内容。

这种配置对应的 XML 代码如下:

select SEQ_ID.nextval from dual

insert into country (id, countryname, countrycode)

values (#{id},#{countryname},#{countrycode})

这种用法中,values 中必须出现主键的值,否则就插不到数据库。

除了 Oracle 这种外,还有一种更普遍的用法,就是使用 UUID。

例如下面的配置:

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY,generator = "select uuid()")

private String id;

注意 SQL 返回值类型和这里接收的类型(String)一致。

2.3.4 @KeySql 介绍

上面的例子中都列举了 @KeySql 方式的用法。下面全面的看看这个注解:

@Target({ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)

public @interface KeySql {

/**

* 是否使用 JDBC 方式获取主键,优先级最高,设置为 true 后,不对其他配置校验

*

* @return

*/

boolean useGeneratedKeys() default false;

/**

* 优先级第二,根据配置的数据库类型取回主键,忽略其他配置

*

* @return

*/

IdentityDialect dialect() default IdentityDialect.DEFAULT;

/**

* 取主键的 SQL

*

* @return

*/

String sql() default "";

/**

* 和 sql 可以配合使用,默认使用全局配置中的 ORDER

*

* @return

*/

ORDER order() default ORDER.DEFAULT;

}

通过上面的注释,大家可以看到主要的 3 个参数的优先级,useGeneratedKeys 优先级最高,其次是 dialect,最后是 sql。其中 order 只对 sql 方式有效。

useGeneratedKeys 和 dialect 相当于预设的基本用法,和数据库以及驱动紧密相关。

sql 和 order 更灵活。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值