审计
---
融租易支持在代码级别记录用户对指定表的操作记录.

操作包括 : 插入, 更新, 删除.

## 1. 代码准备

再代码层面, 有两个注解 `AuditEnabled`,`AuditEntry`

#### 1.1 AuditEnabled

这个注解加在 DTO 类上, 表示这个 DTO 代表的 表需要开启审计功能.

```java
@Table("SYS_USER")
@AuditEnabled
public class User {

}
```

#### 1.2 AuditEntry

这个注解加在 `Service 接口的方法`上, 表示, 再这个方法的执行周期内开启审计功能.

> 这个方法内部可能会对多个表进行操作, 也可能调用其他的方法 f1, f1 在去操作其他的某个表.   
 这些调用涉及到的审计操作, 全部共享一个审计的 session (auditSessionId相同). 
 
```java
public interface UserService {
    @AuditEntry
    User updateUser(User user);
}
```

## 2. 表结构

所有需要开启审计功能的表, 需要有一个与之相对应的 `审计表`.

命名规则 : `基表名`_a

可以在 `AuditEnabled` 注解中通过参数 `auditTable` 来指定.

>这个规则可以 实现接口 `IAuditTableNameProvider` 来自定义.   
实现类需要定义为 spring bean

审计表字段`包含所有字段`, 但不包含`基表的唯一索引, 主键约束`等

另外必须包括审计专用字段:
* `audit_id` (bigint) 自增长主键
* `audit_transaction_type` (varchar (10)) 审计操作(insert,update,delete)
* `audit_timestamp` (datetime) 审计时间
* `audit_session_id` (varchar(64)) 审计 session id

## 3 基本原理

`AuditInterceptor` 会拦截所有的 Mybatis 通过 dto 执行的操作,

根据当前有没有 `audit session` , 以及  dto 上的 AuditEnabled 注解 来决定是不是要执行 审计操作.

如果需要执行, 则动态生成 SQL 语句, 完成对新记录的`备份` 操作.

`插入`,`更新` 执行的操作是 先操作, 后记录.
`删除` 执行的操作是 先记录, 后操作.

也就是说, 审计表中插入的都是`最新的快照`.

> 基于这个原理的审计, 只能做到行级的记录, 无法具体到字段级.   
但是结合一定的比较手段, 可以知道, 某次修改, 到底修改了哪些字段.

另外, 由于 audit session 的存在, 我们大概也可以知道,某次提交,同时修改了哪些数据.

当然操作的记录如何展示出来, 是需要另外开发页面的.