Skip to content

Commit e6aae28

Browse files
committed
新增UUID相关文档
1 parent 79f443a commit e6aae28

File tree

2 files changed

+97
-9
lines changed

2 files changed

+97
-9
lines changed

wiki/mapper3/10.Mapper-UUID.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#通用 Mapper UUID 简单示例
2+
通用 Mapper 中对 UUID 的用法主要提到了一种专有的写法,如下写法:
3+
```java
4+
@GeneratedValue(generator = "UUID")
5+
```
6+
这种方式实现很容易理解,就是在你 insert 之前,调用 UUID 的公共方法在 `<bind>` 标签中生成了一个值,插入到了数据库,由于这个值是临时的,并没有 `set` 到对象,因此这种方式是不支持回写的。
7+
8+
由于回写方式很常见,因此用这种方式很难满足要求。
9+
10+
上面这些在文档中都提到了。
11+
12+
而且在文档中也提到了一种可以回写的方式,由于很多人不理解或者尝试失败,因此很早就有必要写一篇如何使用可回写 UUID 的方式(我曾经远程协助一个朋友解决过这个问题,这个朋友答应我把自己的用法写下来分享给大家,可惜食言了)。
13+
14+
##可回写的 UUID
15+
最简单的可回写 UUID 方式就是像 Oracle 序列那样直接写一个返回 UUID 的 SQL 就能实现,这是第一种写法:
16+
```java
17+
@Id
18+
@GeneratedValue(strategy = GenerationType.IDENTITY,generator = "select uuid()")
19+
private String id;
20+
```
21+
使用这种方式的时候必须注意,由于是执行 SQL,所以底层是使用 `<selectKey>` 实现的,并且因为需要先得到 UUID 的值才能插入数据库,因此还需要配置 `ORDER` 属性,使用 Java 方式配置时,用下面的方式进行配置:
22+
```java
23+
Config config = new Config();
24+
// 其他配置
25+
// 主键自增回写方法执行顺序,默认AFTER,可选值为(BEFORE|AFTER)
26+
config.setOrder("BEFORE");
27+
mapperHelper.setConfig(config);
28+
```
29+
30+
使用 Spring 方式进行配置时如下:
31+
```xml
32+
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
33+
<property name="basePackage" value="com.isea533.mybatis.mapper"/>
34+
<property name="properties">
35+
<value>
36+
mappers=tk.mybatis.mapper.common.Mapper
37+
ORDER=BEFORE
38+
</value>
39+
</property>
40+
</bean>
41+
```
42+
注意是增加 `ORDER=BEFORE` 这一行,如果你还有其他配置,都可以按这种方式一行一个 `key=value`
43+
44+
这么配置以后就可以正确的获取 UUID 的值了。
45+
46+
##任意类型的主键回写值
47+
你可能没注意到上面 UUID 类型的主键中,`id` 属性的类型是 `String`,因为`select uuid()` 返回的字符串,所以 Java 中的类型要和数据库类型匹配。
48+
49+
因此,如果你使用一个 `select myId()` 函数返回一个自定义类型的主键值,你需要让 Java 中的类型和这个匹配。
50+
51+
##通用主键 SQL 配置
52+
如果你每一个实体类中都有一个 `id` 属性,并且配置的注解都一样,都执行同样的 SQL 去返回值。如果都去配置这个注解会很麻烦。想要解决这种重复性配置,最简单的方式就是提取基类,让使用相同方式主键策略的实体类继承同一个基类就能解决。
53+
54+
但是如果你需要适用不同的数据库,这种方式麻烦点的解决办法就是针对不同的数据库创建不同的基类,放在不同的项目中,但是使用相同的包名,具体应用到生产环境时使用对应数据库的基类 jar 包就可以。除此之外还有一种方式,这种方式就是使用 `IDENTITY`,这个参数用于配置取回主键的方式。
55+
56+
默认提供的 `IDENTITY` 可选值参考文档 [GenerationType.IDENTITY](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/3.Use.md#2-generatedvalue-strategy-=-generationtype-identity-_7)
57+
58+
这个参数除了这些可选值外,还可以是可以执行的 SQL,也就是说最前面的配置方式可以改为:
59+
```java
60+
@Id
61+
@GeneratedValue(strategy = GenerationType.IDENTITY)
62+
private String id;
63+
```
64+
在 Java 方式中用下面的方式进行配置:
65+
```java
66+
Config config = new Config();
67+
// 其他配置
68+
config.setIDENTITY("select uuid()");
69+
// 主键自增回写方法执行顺序,默认AFTER,可选值为(BEFORE|AFTER)
70+
config.setOrder("BEFORE");
71+
mapperHelper.setConfig(config);
72+
```
73+
使用 Spring 方式进行配置时如下:
74+
```xml
75+
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
76+
<property name="basePackage" value="com.isea533.mybatis.mapper"/>
77+
<property name="properties">
78+
<value>
79+
mappers=tk.mybatis.mapper.common.Mapper
80+
IDENTITY=select uuid()
81+
ORDER=BEFORE
82+
</value>
83+
</property>
84+
</bean>
85+
```
86+
这里仍然要注意设置 `ORDER=BEFORE`,如果你用 `IDENTITY` 提供的那些可选参数,就不要设置(默认为`AFTER`),可选参数中仍然是针对的数据库支持自增的情况,那些情况仍然是插入数据库后才会有主键值,这点一定要明白!
87+
88+
在这种情况下,如果换了数据库,只需要修改一下配置就能解决,例如 SQL SERVER 的:
89+
```sql
90+
IDENTITY=select replace(newid(), '-', '')
91+
```
92+
93+
##总结
94+
关于 UUID 的内容就上面这些,还需要提醒一点的就是由于 `ORDER` 是一个全局的配置,所以使用时要注意保证所有主键方式都是一致的 `ORDER` 方式,主键自增的时候使用 `@GeneratedValue(generator = "JDBC")` 这种方式通过 JDBC 接口去获取返回值更好。当然使用批量插入时,MySql 支持多主键回写,但是 SqlServer 仅能返回最后一个插入的主键,所以选择使用某种方式时,一定要有所了解,做好测试,避免数据库差异带来的问题。

wiki/mapper3/3.Use.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,6 @@ private Integer id;
121121

122122
注意`<selectKey>`中的内容就是`IDENTITY`参数值对应数据库的SQL
123123

124-
**______________________下面这个提醒很重要______________________**
125-
126-
**重要提醒:**`IDENTITY`除了上面这些选项外,还可以是任意可以执行的SQL,例如MySql的`select uuid()`,SqlServer的`select newid()`等等,这种情况下需要保证主键的类型和SQL的返回值一致。
127-
128-
利用这一个特点,我们就可以使用可以回写的UUID值,如果想获得更特殊的主键值,可以自己写函数调用。
129-
130-
**______________________上面这个提醒很重要______________________**
131-
132124
###3.`@GeneratedValue(generator = "UUID")`
133125
```java
134126
//可以用于任意字符串类型长度超过32位的字段
@@ -146,6 +138,8 @@ private String username;
146138
</insert>
147139
```
148140

141+
**注意:这种方式不能回写,如果想要回写,请看 [通用 Mapper UUID 简单示例](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/10.Mapper-UUID.md)**
142+
149143
###4.Oracle使用序列
150144
```java
151145
@Id
@@ -199,7 +193,7 @@ values
199193
```
200194
这样配置后,直接继承了`Mapper`接口的才会被扫描,`basePackage`可以配置的范围更大。
201195

202-
如果想在Spring4中使用泛型注入,还需要包含`Mapper<T>`所在的包,具体请看 [在Spring4中使用通用Mapper](http://git.oschina.net/free/Mapper/blob/master/wiki/UseMapperInSpring4.md)
196+
如果想在Spring4中使用泛型注入,还需要包含`Mapper<T>`所在的包,具体请看 [在Spring4中使用通用Mapper](http://git.oschina.net/free/Mapper2/blob/master/wiki/mapper/4.Spring4.md)
203197

204198
##5. 代码中使用
205199

0 commit comments

Comments
 (0)