update docs

This commit is contained in:
开源海哥 2023-03-25 16:41:48 +08:00
parent f06fa5b6df
commit d3e75696cd
11 changed files with 228 additions and 435 deletions

View File

@ -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: [

View File

@ -0,0 +1,3 @@
# 数据审计
文档正在完善中,请稍后。

View File

@ -1,4 +1,4 @@
# Entity 的 @Column 配置
# E@Column 注解的使用
Mybatis-Flex 提供了 `@Column` 用来对字段进行更多的配置,以下是 `@Column` 的代码定义:

View File

@ -1,169 +1,77 @@
# Entity 的主键配置
# 数据填充
在 Entity 类中Mybatis-Flex 是使用 `@Id` 注解来标识主键的,如下代码所示:
数据填充指的是,当 Entity 数据被插入 或者 更新的时候,会为字段进行一些默认的数据设置。这个非常有用,比如说当某个 entity 被插入时候
会设置一些数据插入的时间、数据插入的用户 id多租户的场景下设置当前租户信息等等。
```java
@Table("tb_account")
public class Account {
Mybatis-Flex 提供了两种方式,帮助开发者进行数据填充。
// id 为自增主键
@Id(keyType = KeyType.Auto)
private Long id;
//getter setter
}
```
`@Id` 注解的内容如下:
```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 是 Generatorvalue 则代表的是使用的那个 keyGenerator 的名称
*
*/
String value() default "";
- 1、通过 `@Table` 注解的 `onInsert``onUpdate` 配置进行操作。这部分可以参考 [@Table 注解](./table) 章节。
- 2、通过 `@Column` 注解的 `onInsertValue``onUpdateValue` 配置进行操作。这部分可以参考 [@Column 注解](./column) 章节。
/**
* sequence 序列执行顺序
* 是在 entity 数据插入之前执行,还是之后执行,之后执行的一般是数据主动生成的 id
*
* @return 执行之前还是之后
*/
boolean before() default true;
}
```
keyType 为主键的生成方式KeyType 有 4 种类型:
## 疑惑点
**1、`@Table` 注解的 `onInsert``@Column` 注解的 `onInsertValue` 有什么区别?**
```java
public enum KeyType {
答:`@Table` 注解的 `onInsert` 主要是在 Java 应用层面进行数据设置,而 `@Column` 注解的 `onInsertValue` 则是在数据库层面进行数据设置。
/**
* 自增的方式
*/
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 {
```java 9
@Table("tb_article")
public class Article {
@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(onInsertValue = "now()")
private Date created;
}
```
第 2 步:注册 UUIDKeyGenerator
当数据被插入时,其执行的 Sql 如下:
```java
KeyGeneratorFactory.register("myUUID", new UUIDKeyGenerator());
```sql
INSERT INTO `tb_article`(title, created)
VALUES (?, now())
```
第 3 步:在 Entity 里使用 "myUUID" 生成器
`@Column(onInsertValue = "now()")` 中的 `now()` 是 Sql 的一部分(一个函数),我们可以配置更加复杂,例如:
```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")
@Id(keyType = KeyType.Auto)
private Long id;
private String title;
@Column(onUpdateValue = "version + 1")
private int version;
}
```
## 全局配置
当数据被 update 的时候,其执行的 sql 如下:
一般的项目中,通常是许多的 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);
```sql
update tb_article set title = ?,version = version + 1
```
此时Entity 类 Account.java 只需要如下配置即可。
更复杂的场景,我们可以配置如下:
```java
@Table("tb_account")
public class Account {
```java 9
@Table("tb_article")
public class Article {
@Id()
@Id(keyType = KeyType.Auto)
private Long id;
private String title;
@Column(onUpdateValue = "(select xxx from other_table where ...)")
private int version;
}
```

View File

@ -1,8 +1,8 @@
# Entity 的主键配置
# @Id 主键的使用
在 Entity 类中Mybatis-Flex 是使用 `@Id` 注解来标识主键的,如下代码所示:
```java
```java 5
@Table("tb_account")
public class Account {

View File

@ -1,83 +1,14 @@
# Entity 的主键配置
# 数据脱敏
在 Entity 类中Mybatis-Flex 是使用 `@Id` 注解来标识主键的,如下代码所示:
## 数据脱敏是什么
```java
@Table("tb_account")
public class Account {
随着《网络安全法》的颁布施行,对个人隐私数据的保护已经上升到法律层面。 数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,
实现敏感隐私数据的可靠保护。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供使用,
如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。
// id 为自增主键
@Id(keyType = KeyType.Auto)
private Long id;
## @ColumnMask
//getter setter
}
```
`@Id` 注解的内容如下:
```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 是 Generatorvalue 则代表的是使用的那个 keyGenerator 的名称
*
*/
String value() default "";
/**
* sequence 序列执行顺序
* 是在 entity 数据插入之前执行,还是之后执行,之后执行的一般是数据主动生成的 id
*
* @return 执行之前还是之后
*/
boolean before() default true;
}
```
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` 注解标识而已,比如:
Mybatis-Flex 提供了 `@ColumnMask()` 注解,以及内置的 9 种脱敏规则,帮助开发者方便的进行数据脱敏。例如:
```java
@Table("tb_account")
@ -86,84 +17,68 @@ 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 {
@Override
public Object generate(Object entity, String keyColumn) {
return UUID.randomUUID().toString().replace("-", "");
}
@ColumnMask(Masks.CHINESE_NAME)
private String userName;
}
```
第 2 步:注册 UUIDKeyGenerator
以上的示例中,使用了 `CHINESE_NAME` 的脱敏规则,其主要用于处理 "中文名字" 的场景。当我们查询到 userName 为 `张三丰` 的时候,其内容自动被处理成 `张**`
除此之外Mybatis-Flex 还提供了如下的 8 中脱敏规则,方便开发者直接使用:
- 手机号脱敏
- 固定电话脱敏
- 身份证号脱敏
- 身份证号脱敏
- 地址脱敏
- 邮件脱敏
- 密码脱敏
- 银行卡号脱敏
## 自定义脱敏规则
当 Mybaits-Flex 内置的 9 中脱敏规则无法满足要求时,我们还可以自定义脱敏规则,其步骤如下:
1、通过 `MaskFactory` 注册新的脱敏规则:
```java
KeyGeneratorFactory.register("myUUID", new UUIDKeyGenerator());
MaskFactory.registerMaskProcesser("自定义规则名称"
, data -> {
return data;
})
```
第 3 步:在 Entity 里使用 "myUUID" 生成器:
```java
2、使用自定义的脱敏规则
```java 7
@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")
@Id(keyType = KeyType.Auto)
private Long id;
@ColumnMask("自定义规则名称")
private String userName;
}
```
## 全局配置
## 取消脱敏处理
一般的项目中,通常是许多的 Entity 使用同一个数据库,同时使用一种主键生成方式,比如说都使用 自增
或者都使用通过序列Sequence生成此时我们是没有必要为每个 Entity 单独配置一样内容的
在某些场景下,程序希望查询得到的数据是原始数据,而非脱敏数据。比如要去查询用户的手机号,然后给用户发送短信。又或者说,我们进入编辑页面编辑用户数据,
如果编辑页面展示的是脱敏数据,然后再次点击保存,那么数据库的真实数据也会被脱敏覆盖。
Mybatis-Flex 提供了一种全局配置的方式,代码如下
因此MaskFactory 提供了 `skipMask``restoreMask` 两个方法来处理这种场景:
```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;
```java 2,7
try {
MaskFactory.skipMask()
//此处查询到的数据不会进行脱敏处理
accountMapper.selectListByQuery(...)
} finally {
MaskFactory.restoreMask()
}
```
::: tip 提示
在具体的应用中,我们通常会把 `skipMask()``restoreMask()` 放到统一的拦截器里,对某一类业务进行统一拦截和处理。
:::

5
docs/zh/qq_group.md Normal file
View File

@ -0,0 +1,5 @@
# Mybatis-Flex QQ 交流群
群号: 532992631
![](../assets/images/qq_group.png)

View File

@ -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 使用了 APTAnnotation Processing Tool技术在项目编译的时候
会自动根据 Entity 类定义的字段帮你生成 "ACCOUNT" 类以及 Entity 对应的 Mapper 类, 通过开发工具构建项目(如下图),
或者执行 maven 编译命令: `mvn clean package` 都可以自动生成。这个原理和 lombok 一致。
![](../../assets/images/build_idea.png)
> 更多关于 APT 的配置,请进入 [APT 配置章节](./apt) 了解。

View File

@ -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 是 Generatorvalue 则代表的是使用的那个 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 一致,用于在数据被更新的时候,设置一些默认数据。

View File

@ -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、强大**:支持任意关系型数据库,还可以通过方言持续扩展,同时支持 **多(复合)主键**、**逻辑删除**、**乐观锁配置**、**数据脱敏**、**数据审计**、
**数据填充** 等等功能。

View File

@ -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