mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-08 01:28:24 +08:00
update docs
This commit is contained in:
parent
f06fa5b6df
commit
d3e75696cd
@ -25,6 +25,7 @@ export default defineConfig({
|
||||
{ text: 'Mybatis-Flex 是什么', link: '/zh/what-is-mybatisflex' },
|
||||
{ text: '快速开始', link: '/zh/getting-started' },
|
||||
{ text: 'Maven 依赖', link: '/zh/maven' },
|
||||
{ text: 'QQ 交流群', link: '/zh/qq_group' },
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -38,9 +39,9 @@ export default defineConfig({
|
||||
{
|
||||
text: '核心功能',
|
||||
items: [
|
||||
{ text: '实体类配置', link: '/zh/table' },
|
||||
{ text: '主键配置', link: '/zh/id' },
|
||||
{ text: '列配置', link: '/zh/column' },
|
||||
{ text: '@Table 注解', link: '/zh/table' },
|
||||
{ text: '@Id 注解', link: '/zh/id' },
|
||||
{ text: '@Column 注解', link: '/zh/column' },
|
||||
{ text: 'Db + Row', link: '/zh/db_row' },
|
||||
{ text: '逻辑删除', link: '/zh/logic_delete' },
|
||||
{ text: '乐观锁', link: '/zh/version' },
|
||||
@ -60,7 +61,7 @@ export default defineConfig({
|
||||
|
||||
footer: {
|
||||
message: 'Released under the Apache License.',
|
||||
copyright: 'Copyright © 2022-present Mybatis-Flex '
|
||||
copyright: 'Copyright © 2022-present Mybatis-Flex,<span style="font-size: 12px">备案号:<a style="color:#777" target="_blank" rel="noopener" href="http://beian.miit.gov.cn/">黔ICP备19009310号-9 </a></span>'
|
||||
}
|
||||
},
|
||||
head: [
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
# 数据审计
|
||||
|
||||
文档正在完善中,请稍后。
|
||||
@ -1,4 +1,4 @@
|
||||
# Entity 的 @Column 配置
|
||||
# E@Column 注解的使用
|
||||
|
||||
Mybatis-Flex 提供了 `@Column` 用来对字段进行更多的配置,以下是 `@Column` 的代码定义:
|
||||
|
||||
|
||||
188
docs/zh/fill.md
188
docs/zh/fill.md
@ -1,169 +1,77 @@
|
||||
# Entity 的主键配置
|
||||
# 数据填充
|
||||
|
||||
在 Entity 类中,Mybatis-Flex 是使用 `@Id` 注解来标识主键的,如下代码所示:
|
||||
数据填充指的是,当 Entity 数据被插入 或者 更新的时候,会为字段进行一些默认的数据设置。这个非常有用,比如说当某个 entity 被插入时候
|
||||
会设置一些数据插入的时间、数据插入的用户 id,多租户的场景下设置当前租户信息等等。
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
Mybatis-Flex 提供了两种方式,帮助开发者进行数据填充。
|
||||
|
||||
- 1、通过 `@Table` 注解的 `onInsert` 和 `onUpdate` 配置进行操作。这部分可以参考 [@Table 注解](./table) 章节。
|
||||
- 2、通过 `@Column` 注解的 `onInsertValue` 和 `onUpdateValue` 配置进行操作。这部分可以参考 [@Column 注解](./column) 章节。
|
||||
|
||||
|
||||
|
||||
## 疑惑点
|
||||
**1、`@Table` 注解的 `onInsert` 和 `@Column` 注解的 `onInsertValue` 有什么区别?**
|
||||
|
||||
答:`@Table` 注解的 `onInsert` 主要是在 Java 应用层面进行数据设置,而 `@Column` 注解的 `onInsertValue` 则是在数据库层面进行数据设置。
|
||||
|
||||
例如:
|
||||
|
||||
```java 9
|
||||
@Table("tb_article")
|
||||
public class Article {
|
||||
|
||||
// id 为自增主键
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
//getter setter
|
||||
private String title;
|
||||
|
||||
@Column(onInsertValue = "now()")
|
||||
private Date created;
|
||||
}
|
||||
```
|
||||
|
||||
`@Id` 注解的内容如下:
|
||||
当数据被插入时,其执行的 Sql 如下:
|
||||
|
||||
```java
|
||||
public @interface Id {
|
||||
|
||||
/**
|
||||
* ID 生成策略,默认为 none
|
||||
*
|
||||
* @return 生成策略
|
||||
*/
|
||||
KeyType keyType() default KeyType.None;
|
||||
|
||||
/**
|
||||
* 若 keyType 类型是 sequence, value 则代表的是
|
||||
* sequence 序列的 sql 内容
|
||||
* 例如:select SEQ_USER_ID.nextval as id from dual
|
||||
*
|
||||
* 若 keyType 是 Generator,value 则代表的是使用的那个 keyGenerator 的名称
|
||||
*
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
|
||||
/**
|
||||
* sequence 序列执行顺序
|
||||
* 是在 entity 数据插入之前执行,还是之后执行,之后执行的一般是数据主动生成的 id
|
||||
*
|
||||
* @return 执行之前还是之后
|
||||
*/
|
||||
boolean before() default true;
|
||||
}
|
||||
```sql
|
||||
INSERT INTO `tb_article`(title, created)
|
||||
VALUES (?, now())
|
||||
```
|
||||
|
||||
keyType 为主键的生成方式,KeyType 有 4 种类型:
|
||||
`@Column(onInsertValue = "now()")` 中的 `now()` 是 Sql 的一部分(一个函数),我们可以配置更加复杂,例如:
|
||||
|
||||
```java
|
||||
public enum KeyType {
|
||||
```java 9
|
||||
@Table("tb_article")
|
||||
public class Article {
|
||||
|
||||
/**
|
||||
* 自增的方式
|
||||
*/
|
||||
Auto,
|
||||
|
||||
/**
|
||||
* 通过执行数据库 sql 生成
|
||||
* 例如:select SEQ_USER_ID.nextval as id from dual
|
||||
*/
|
||||
Sequence,
|
||||
|
||||
/**
|
||||
* 通过 IKeyGenerator 生成器生成
|
||||
*/
|
||||
Generator,
|
||||
|
||||
/**
|
||||
* 其他方式,比如说在代码层用户手动设置
|
||||
*/
|
||||
None,
|
||||
}
|
||||
```
|
||||
|
||||
## 多主键、复合主键
|
||||
|
||||
Mybatis-Flex 多主键就是在 Entity 类里有多个 `@Id` 注解标识而已,比如:
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id(keyType=KeyType.Auto)
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
@Id(keyType=KeyType.Generator, value="uuid")
|
||||
private String otherId;
|
||||
private String title;
|
||||
|
||||
//getter setter
|
||||
}
|
||||
```
|
||||
当我们保存数据的时候,Account 的 id 主键为自增,而 otherId 主键则通过 uuid 生成。
|
||||
|
||||
## 主键生成器
|
||||
|
||||
第 1 步:编写一个类,实现 `IKeyGenerator` 接口,例如:
|
||||
|
||||
```java
|
||||
public class UUIDKeyGenerator implements IKeyGenerator {
|
||||
|
||||
@Override
|
||||
public Object generate(Object entity, String keyColumn) {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
@Column(onUpdateValue = "version + 1")
|
||||
private int version;
|
||||
}
|
||||
```
|
||||
|
||||
第 2 步:注册 UUIDKeyGenerator
|
||||
当数据被 update 的时候,其执行的 sql 如下:
|
||||
|
||||
```java
|
||||
KeyGeneratorFactory.register("myUUID", new UUIDKeyGenerator());
|
||||
```sql
|
||||
update tb_article set title = ?,version = version + 1
|
||||
```
|
||||
|
||||
第 3 步:在 Entity 里使用 "myUUID" 生成器:
|
||||
更复杂的场景,我们可以配置如下:
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
```java 9
|
||||
@Table("tb_article")
|
||||
public class Article {
|
||||
|
||||
@Id(keyType=KeyType.Generator, value="myUUID")
|
||||
private String otherId;
|
||||
|
||||
//getter setter
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 使用序列 Sequence 生成
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id(keyType=KeyType.Sequence, value="select SEQ_USER_ID.nextval as id from dual")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 全局配置
|
||||
|
||||
一般的项目中,通常是许多的 Entity 使用同一个数据库,同时使用一种主键生成方式,比如说都使用 自增,
|
||||
或者都使用通过序列(Sequence)生成,此时,我们是没有必要为每个 Entity 单独配置一样内容的。
|
||||
|
||||
Mybatis-Flex 提供了一种全局配置的方式,代码如下:
|
||||
|
||||
```java
|
||||
FlexGlobalConfig.KeyConfig keyConfig = new FlexGlobalConfig.KeyConfig();
|
||||
keyConfig.setKeyType(KeyType.Sequence);
|
||||
keyConfig.setValue("select SEQ_USER_ID.nextval as id from dual")
|
||||
keyConfig.setBefore(true);
|
||||
|
||||
FlexGlobalConfig.getDefaultConfig().setKeyConfig(keyConfig);
|
||||
```
|
||||
|
||||
此时,Entity 类 Account.java 只需要如下配置即可。
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id()
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
private String title;
|
||||
|
||||
@Column(onUpdateValue = "(select xxx from other_table where ...)")
|
||||
private int version;
|
||||
}
|
||||
```
|
||||
@ -1,8 +1,8 @@
|
||||
# Entity 的主键配置
|
||||
# @Id 主键的使用
|
||||
|
||||
在 Entity 类中,Mybatis-Flex 是使用 `@Id` 注解来标识主键的,如下代码所示:
|
||||
|
||||
```java
|
||||
```java 5
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
|
||||
191
docs/zh/mask.md
191
docs/zh/mask.md
@ -1,169 +1,84 @@
|
||||
# Entity 的主键配置
|
||||
# 数据脱敏
|
||||
|
||||
在 Entity 类中,Mybatis-Flex 是使用 `@Id` 注解来标识主键的,如下代码所示:
|
||||
## 数据脱敏是什么
|
||||
|
||||
随着《网络安全法》的颁布施行,对个人隐私数据的保护已经上升到法律层面。 数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,
|
||||
实现敏感隐私数据的可靠保护。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供使用,
|
||||
如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。
|
||||
|
||||
## @ColumnMask
|
||||
|
||||
Mybatis-Flex 提供了 `@ColumnMask()` 注解,以及内置的 9 种脱敏规则,帮助开发者方便的进行数据脱敏。例如:
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
// id 为自增主键
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
//getter setter
|
||||
@ColumnMask(Masks.CHINESE_NAME)
|
||||
private String userName;
|
||||
}
|
||||
```
|
||||
|
||||
`@Id` 注解的内容如下:
|
||||
以上的示例中,使用了 `CHINESE_NAME` 的脱敏规则,其主要用于处理 "中文名字" 的场景。当我们查询到 userName 为 `张三丰` 的时候,其内容自动被处理成 `张**`。
|
||||
|
||||
除此之外,Mybatis-Flex 还提供了如下的 8 中脱敏规则,方便开发者直接使用:
|
||||
|
||||
- 手机号脱敏
|
||||
- 固定电话脱敏
|
||||
- 身份证号脱敏
|
||||
- 身份证号脱敏
|
||||
- 地址脱敏
|
||||
- 邮件脱敏
|
||||
- 密码脱敏
|
||||
- 银行卡号脱敏
|
||||
|
||||
## 自定义脱敏规则
|
||||
|
||||
当 Mybaits-Flex 内置的 9 中脱敏规则无法满足要求时,我们还可以自定义脱敏规则,其步骤如下:
|
||||
|
||||
1、通过 `MaskFactory` 注册新的脱敏规则:
|
||||
|
||||
```java
|
||||
public @interface Id {
|
||||
|
||||
/**
|
||||
* ID 生成策略,默认为 none
|
||||
*
|
||||
* @return 生成策略
|
||||
*/
|
||||
KeyType keyType() default KeyType.None;
|
||||
|
||||
/**
|
||||
* 若 keyType 类型是 sequence, value 则代表的是
|
||||
* sequence 序列的 sql 内容
|
||||
* 例如:select SEQ_USER_ID.nextval as id from dual
|
||||
*
|
||||
* 若 keyType 是 Generator,value 则代表的是使用的那个 keyGenerator 的名称
|
||||
*
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
|
||||
/**
|
||||
* sequence 序列执行顺序
|
||||
* 是在 entity 数据插入之前执行,还是之后执行,之后执行的一般是数据主动生成的 id
|
||||
*
|
||||
* @return 执行之前还是之后
|
||||
*/
|
||||
boolean before() default true;
|
||||
}
|
||||
MaskFactory.registerMaskProcesser("自定义规则名称"
|
||||
, data -> {
|
||||
return data;
|
||||
})
|
||||
```
|
||||
|
||||
keyType 为主键的生成方式,KeyType 有 4 种类型:
|
||||
|
||||
```java
|
||||
public enum KeyType {
|
||||
|
||||
/**
|
||||
* 自增的方式
|
||||
*/
|
||||
Auto,
|
||||
|
||||
/**
|
||||
* 通过执行数据库 sql 生成
|
||||
* 例如:select SEQ_USER_ID.nextval as id from dual
|
||||
*/
|
||||
Sequence,
|
||||
|
||||
/**
|
||||
* 通过 IKeyGenerator 生成器生成
|
||||
*/
|
||||
Generator,
|
||||
|
||||
/**
|
||||
* 其他方式,比如说在代码层用户手动设置
|
||||
*/
|
||||
None,
|
||||
}
|
||||
```
|
||||
|
||||
## 多主键、复合主键
|
||||
|
||||
Mybatis-Flex 多主键就是在 Entity 类里有多个 `@Id` 注解标识而已,比如:
|
||||
|
||||
```java
|
||||
2、使用自定义的脱敏规则
|
||||
```java 7
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id(keyType=KeyType.Auto)
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
@Id(keyType=KeyType.Generator, value="uuid")
|
||||
private String otherId;
|
||||
|
||||
//getter setter
|
||||
}
|
||||
```
|
||||
当我们保存数据的时候,Account 的 id 主键为自增,而 otherId 主键则通过 uuid 生成。
|
||||
|
||||
## 主键生成器
|
||||
|
||||
第 1 步:编写一个类,实现 `IKeyGenerator` 接口,例如:
|
||||
|
||||
```java
|
||||
public class UUIDKeyGenerator implements IKeyGenerator {
|
||||
|
||||
@Override
|
||||
public Object generate(Object entity, String keyColumn) {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
@ColumnMask("自定义规则名称")
|
||||
private String userName;
|
||||
}
|
||||
```
|
||||
|
||||
第 2 步:注册 UUIDKeyGenerator
|
||||
## 取消脱敏处理
|
||||
|
||||
```java
|
||||
KeyGeneratorFactory.register("myUUID", new UUIDKeyGenerator());
|
||||
```
|
||||
在某些场景下,程序希望查询得到的数据是原始数据,而非脱敏数据。比如要去查询用户的手机号,然后给用户发送短信。又或者说,我们进入编辑页面编辑用户数据,
|
||||
如果编辑页面展示的是脱敏数据,然后再次点击保存,那么数据库的真实数据也会被脱敏覆盖。
|
||||
|
||||
第 3 步:在 Entity 里使用 "myUUID" 生成器:
|
||||
因此,MaskFactory 提供了 `skipMask`、`restoreMask` 两个方法来处理这种场景:
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
```java 2,7
|
||||
try {
|
||||
MaskFactory.skipMask()
|
||||
|
||||
@Id(keyType=KeyType.Generator, value="myUUID")
|
||||
private String otherId;
|
||||
|
||||
//getter setter
|
||||
//此处查询到的数据不会进行脱敏处理
|
||||
accountMapper.selectListByQuery(...)
|
||||
} finally {
|
||||
MaskFactory.restoreMask()
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 使用序列 Sequence 生成
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id(keyType=KeyType.Sequence, value="select SEQ_USER_ID.nextval as id from dual")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 全局配置
|
||||
|
||||
一般的项目中,通常是许多的 Entity 使用同一个数据库,同时使用一种主键生成方式,比如说都使用 自增,
|
||||
或者都使用通过序列(Sequence)生成,此时,我们是没有必要为每个 Entity 单独配置一样内容的。
|
||||
|
||||
Mybatis-Flex 提供了一种全局配置的方式,代码如下:
|
||||
|
||||
```java
|
||||
FlexGlobalConfig.KeyConfig keyConfig = new FlexGlobalConfig.KeyConfig();
|
||||
keyConfig.setKeyType(KeyType.Sequence);
|
||||
keyConfig.setValue("select SEQ_USER_ID.nextval as id from dual")
|
||||
keyConfig.setBefore(true);
|
||||
|
||||
FlexGlobalConfig.getDefaultConfig().setKeyConfig(keyConfig);
|
||||
```
|
||||
|
||||
此时,Entity 类 Account.java 只需要如下配置即可。
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id()
|
||||
private Long id;
|
||||
|
||||
}
|
||||
```
|
||||
::: tip 提示
|
||||
在具体的应用中,我们通常会把 `skipMask()` 和 `restoreMask()` 放到统一的拦截器里,对某一类业务进行统一拦截和处理。
|
||||
:::
|
||||
|
||||
5
docs/zh/qq_group.md
Normal file
5
docs/zh/qq_group.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Mybatis-Flex QQ 交流群
|
||||
|
||||
群号: 532992631
|
||||
|
||||

|
||||
@ -30,7 +30,7 @@ public class AccountController {
|
||||
}
|
||||
}
|
||||
```
|
||||
在以上的示例中,其核心代码为:构造 QueryWrapper,通过 Mapper 查询,如下所示:
|
||||
在以上的示例中,其核心代码如下所示:
|
||||
|
||||
```java
|
||||
//构造 QueryWrapper
|
||||
@ -357,4 +357,14 @@ Firebird 下执行的代码如下:
|
||||
SELECT * FROM "tb_account" ORDER BY "id" DESC ROWS 20 TO 30
|
||||
```
|
||||
|
||||
## 存在疑问?
|
||||
|
||||
**疑问1:示例代码中的 QueryWrapper 所需要的 "ACCOUNT" 从哪里来的?**
|
||||
|
||||
答:答:Mybatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编译的时候,
|
||||
会自动根据 Entity 类定义的字段帮你生成 "ACCOUNT" 类以及 Entity 对应的 Mapper 类, 通过开发工具构建项目(如下图),
|
||||
或者执行 maven 编译命令: `mvn clean package` 都可以自动生成。这个原理和 lombok 一致。
|
||||
|
||||

|
||||
|
||||
> 更多关于 APT 的配置,请进入 [APT 配置章节](./apt) 了解。
|
||||
204
docs/zh/table.md
204
docs/zh/table.md
@ -1,169 +1,97 @@
|
||||
# Entity 的主键配置
|
||||
# @Table 注解的使用
|
||||
|
||||
在 Entity 类中,Mybatis-Flex 是使用 `@Id` 注解来标识主键的,如下代码所示:
|
||||
在 Mybatis-Flex 中,`@Table` 主要是用于给 Entity 实体类添加标识,用于描述 实体类 和 数据库表 的关系,以及对实体类进行的一些
|
||||
功能辅助。
|
||||
|
||||
|
||||
`@Table` 的定义如下:
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public @interface Table {
|
||||
|
||||
/**
|
||||
* 显式指定表名称
|
||||
*/
|
||||
String value();
|
||||
|
||||
/**
|
||||
* 数据库的 schema
|
||||
*/
|
||||
String schema() default "";
|
||||
|
||||
/**
|
||||
* 默认为 驼峰属性 转换为 下划线字段
|
||||
*/
|
||||
boolean camelToUnderline() default true;
|
||||
|
||||
/**
|
||||
* 监听 entity 的 insert 行为
|
||||
*/
|
||||
Class<? extends InsertListener> onInsert() default NoneListener.class;
|
||||
|
||||
/**
|
||||
* 监听 entity 的 update 行为
|
||||
*/
|
||||
Class<? extends UpdateListener> onUpdate() default NoneListener.class;
|
||||
}
|
||||
```
|
||||
|
||||
其使用方式如下:
|
||||
|
||||
```java 1
|
||||
@Table(value = "tb_account", onUpdate = MyUpdateListener.class)
|
||||
public class Account {
|
||||
|
||||
// id 为自增主键
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
//getter setter
|
||||
}
|
||||
```
|
||||
|
||||
`@Id` 注解的内容如下:
|
||||
## value
|
||||
|
||||
```java
|
||||
public @interface Id {
|
||||
用于配置指定 实体类 与 表名 的映射关系。
|
||||
|
||||
/**
|
||||
* ID 生成策略,默认为 none
|
||||
*
|
||||
* @return 生成策略
|
||||
*/
|
||||
KeyType keyType() default KeyType.None;
|
||||
## camelToUnderline
|
||||
|
||||
/**
|
||||
* 若 keyType 类型是 sequence, value 则代表的是
|
||||
* sequence 序列的 sql 内容
|
||||
* 例如:select SEQ_USER_ID.nextval as id from dual
|
||||
*
|
||||
* 若 keyType 是 Generator,value 则代表的是使用的那个 keyGenerator 的名称
|
||||
*
|
||||
*/
|
||||
String value() default "";
|
||||
默认值为 ture,用于指定当前 实体类 的字段 与 表的列是否是 **驼峰转下划线** 的关系,比如:实体类中定义的 userName 属性,对应的表字段为 user_name。
|
||||
|
||||
若 camelToUnderline 配置为 false,那么,实体类中定义的 userName 属性,对应的表字段为 userName(除非使用 `@Column` 注解另行指定)。
|
||||
|
||||
/**
|
||||
* sequence 序列执行顺序
|
||||
* 是在 entity 数据插入之前执行,还是之后执行,之后执行的一般是数据主动生成的 id
|
||||
*
|
||||
* @return 执行之前还是之后
|
||||
*/
|
||||
boolean before() default true;
|
||||
}
|
||||
```
|
||||
## onInsert
|
||||
|
||||
keyType 为主键的生成方式,KeyType 有 4 种类型:
|
||||
用于监听 Entity 实体类数据被新增到数据库,我们可以在实体类被新增时做一些前置操作。比如:
|
||||
|
||||
```java
|
||||
public enum KeyType {
|
||||
- 数据填充。
|
||||
- 数据修改。
|
||||
|
||||
/**
|
||||
* 自增的方式
|
||||
*/
|
||||
Auto,
|
||||
示例代码如下:
|
||||
|
||||
/**
|
||||
* 通过执行数据库 sql 生成
|
||||
* 例如:select SEQ_USER_ID.nextval as id from dual
|
||||
*/
|
||||
Sequence,
|
||||
|
||||
/**
|
||||
* 通过 IKeyGenerator 生成器生成
|
||||
*/
|
||||
Generator,
|
||||
|
||||
/**
|
||||
* 其他方式,比如说在代码层用户手动设置
|
||||
*/
|
||||
None,
|
||||
}
|
||||
```
|
||||
|
||||
## 多主键、复合主键
|
||||
|
||||
Mybatis-Flex 多主键就是在 Entity 类里有多个 `@Id` 注解标识而已,比如:
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
```java 2
|
||||
//配置 onInsert = MyInsertListener.class
|
||||
@Table(value = "tb_account", onInsert = MyInsertListener.class)
|
||||
public class Account {
|
||||
|
||||
@Id(keyType=KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
@Id(keyType=KeyType.Generator, value="uuid")
|
||||
private String otherId;
|
||||
|
||||
//getter setter
|
||||
}
|
||||
```
|
||||
当我们保存数据的时候,Account 的 id 主键为自增,而 otherId 主键则通过 uuid 生成。
|
||||
|
||||
## 主键生成器
|
||||
|
||||
第 1 步:编写一个类,实现 `IKeyGenerator` 接口,例如:
|
||||
|
||||
```java
|
||||
public class UUIDKeyGenerator implements IKeyGenerator {
|
||||
public class MyInsertListener implements InsertListener {
|
||||
|
||||
@Override
|
||||
public Object generate(Object entity, String keyColumn) {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
public void onInsert(Object entity) {
|
||||
Account account = (Account)entity;
|
||||
|
||||
//设置 account 被新增时的一些默认数据
|
||||
account.setInsertTime(new Date());
|
||||
account.setInsertUserId("...");
|
||||
|
||||
//多租户的场景下,设置当前 租户 ID ..
|
||||
account.setTenantId("....");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
第 2 步:注册 UUIDKeyGenerator
|
||||
> 需要注意的是:onInsert 监听中,通过 mybatis 的 xml mapper 插入数据,或者通过 Db + Row 中插入数据,并不会触发 onInsert 行为,只有通过
|
||||
> AccountMapper 进行插入数据才会触发。
|
||||
|
||||
```java
|
||||
KeyGeneratorFactory.register("myUUID", new UUIDKeyGenerator());
|
||||
```
|
||||
## onUpdate
|
||||
|
||||
第 3 步:在 Entity 里使用 "myUUID" 生成器:
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id(keyType=KeyType.Generator, value="myUUID")
|
||||
private String otherId;
|
||||
|
||||
//getter setter
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 使用序列 Sequence 生成
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id(keyType=KeyType.Sequence, value="select SEQ_USER_ID.nextval as id from dual")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 全局配置
|
||||
|
||||
一般的项目中,通常是许多的 Entity 使用同一个数据库,同时使用一种主键生成方式,比如说都使用 自增,
|
||||
或者都使用通过序列(Sequence)生成,此时,我们是没有必要为每个 Entity 单独配置一样内容的。
|
||||
|
||||
Mybatis-Flex 提供了一种全局配置的方式,代码如下:
|
||||
|
||||
```java
|
||||
FlexGlobalConfig.KeyConfig keyConfig = new FlexGlobalConfig.KeyConfig();
|
||||
keyConfig.setKeyType(KeyType.Sequence);
|
||||
keyConfig.setValue("select SEQ_USER_ID.nextval as id from dual")
|
||||
keyConfig.setBefore(true);
|
||||
|
||||
FlexGlobalConfig.getDefaultConfig().setKeyConfig(keyConfig);
|
||||
```
|
||||
|
||||
此时,Entity 类 Account.java 只需要如下配置即可。
|
||||
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@Id()
|
||||
private Long id;
|
||||
|
||||
}
|
||||
```
|
||||
使用方式同 onInsert 一致,用于在数据被更新的时候,设置一些默认数据。
|
||||
@ -1 +1,23 @@
|
||||
# Mybatis-Flex 是什么
|
||||
|
||||
Mybatis-Flex 是一个优雅的 Mybatis 增强框架,它非常轻量、同时拥有极高的性能与灵活性。我们可以轻松的使用 Mybaits-Flex 链接任何数据库,其内置的
|
||||
QueryWrapper 帮助我们极大的减少了 SQL 编写的工作的同时,减少出错的可能性。
|
||||
|
||||
总而言之,Mybatis-Flex 能够极大地提高了我们开发的效率和开发体验,让我们有更多的时间去专注于自己的事情。
|
||||
|
||||
|
||||
## 特征
|
||||
|
||||
**1、轻量**:除了 MyBatis,没有任何第三方依赖。Mybatis-Flex 没有任何拦截器,其原理是通过 SqlProvider 的方式实现的。在执行过程中没有任何的 Sql 解析。
|
||||
这带来了几个好处:1、极高的性能;2、极易对代码进行跟踪和调试,因而把控性更高。
|
||||
|
||||
|
||||
**2、灵活**:支持 Entity 的增删改查、以及分页查询的同时,Mybatis-Flex 提供了 Db + Row 工具,可以无需实体类对数据库进行增删改查以及分页查询。
|
||||
与此同时,Mybatis-Flex 内置的 QueryWrapper 可以轻易的帮助我们实现 **多表查询**、**链接查询**、**子查询**等等常见的 SQL 场景。
|
||||
|
||||
|
||||
**3、强大**:支持任意关系型数据库,还可以通过方言持续扩展,同时支持 **多(复合)主键**、**逻辑删除**、**乐观锁配置**、**数据脱敏**、**数据审计**、
|
||||
**数据填充** 等等功能。
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2,11 +2,12 @@ package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.NoneListener;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Table("tb_account")
|
||||
@Table(value = "tb_account",onUpdate = NoneListener.class)
|
||||
public class Account {
|
||||
|
||||
@Id
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user