数据变化拦截客户端
组件编码
hzero-boot-data-change
一、简介
1.1 概述
数据变化拦截客户端的功能是有针对性对增删改sql进行拦截,并获取拦截到的影响的数据改变前后的值。为数据分发功能和数据审计功能提供基础数据支持
1.2 组件坐标
<dependency>
<groupId>org.hzero.boot</groupId>
<artifactId>hzero-boot-data-change</artifactId>
<version>${hzero.boot.version}</version>
</dependency>
1.3 功能特性
- 为数据分发组件提供基础数据
- 为数据审计组件提供基础数据
二、使用说明
数据变更监控是数据分发客户端的基础功能,数据分发和数据审计是扩展功能。
- 配置已提供的功能包含数据变更监控,数据分发,数据审计。开启数据分发,数据审计任意之一都必须开启数据监控。
# application.yml
hzero:
data:
change:
enable: true # 是否启用数据变更拦截功能
- 自行开发扩展功能步骤
- 新建类实现
DataChangeBaseHandler
类,实现对应抽象方法 - 方法说明:
-
canProcess(EntityTable table)
入参为当前操作数据的EntityTable类,返回值为是否进行处理。如果返回true,会记录当前数据更改记录
-
doProcess(List changeDataList)
客户化逻辑,changeDataList是变化的数据对象
-
doCommit
拦截到的事务提交触发的方法调用,表示数据已经持久化。具体使用方式可以参考数据分发和数据审计
-
- 新建类实现
三、局限性
由于底层实现原因,在使用数据分发框架实现数据审计功能或者数据分发功能的时候,需要注意一下几点限制:
版本 0.12.0.RELEASE
-
暂不支持联合主键和无主键的情况。如果是联合主键,默认会取第一个键作为主键,如果没有主键,将不会对数据进行拦截
-
暂不支持无实体类映射的动态sql(在1.1.0版本已经支持)
-
必须正确使用mybatis标签,比如不能在
<select>
标签下写insert相关的SQL,否则会导致无法拦截 -
如果在A表的mapper XML文件下通过sql修改,新增 ,删除 B表的数据,将不会拦截到
-
通过手动sql实现的批量更新操作在高并发下可能会出现并发问题,如果开启了审计或者分发功能,慎用。
-
支持
insert into select
,但是在使用改语法的时候还需要注意以下几点(1.1.0版本有重大升级,如需使用此功能,请升级到1.1.0及以上的版本。详情查看版本更新日志)-
mapper接口入参使用
@Param
注解的时候值不能为collection
,比如@Param(“collection”)。否则会导致SQL取不到正确的参数值。 -
mapper接口入参如果是对象或者map,则对象的属性值或者map的Key名称不能为
collection
。否则会导致SQL取不到正确的参数值。 -
xml中的SQL不能使用
collection
。形如xx = #{collection},或者<foreach collection="collection">
。可将collection用list
代替
-
版本 1.1.0.RELEASE
支持自定义mapper
- 支持自定义mapper对象,即mapper接口不继承hzero的BaseMapper。由于没有继承BaseMapper,所有无法通过mapper映射到对应的实体信息。如果想要正常使用数据拦截的功能,需要写一个类实现AbstractEntityTableSelector抽象类,并放入容器中,实现EntityTable getEntityTable(SqlInfo sqlInfo)方法。这个方法入参是包含了表名和mappedStatementId的对象。需要根据自己的个性化需求构建返回值为EntityTable的对象,其中该对象的name(表名),keyProperties(主键字段),keyColumns(主键列名)是必输入的。
支持自定义批量插入sql和单条插入sql
-
支持自定义单条插入语句,包含以下两种方式
- 1)支持通过mapper接口传入一个对象,然后在xml中通过mybatis的动态sql拼接sql语句。但是需要注意一下两点:
- (1) 如果需要主键生成策略是自增,需要自己在开启主键生成策略配置(hzero内置插入方法已经自动配置了),并设置主键字段,具体语法参见mybatis相关语法。
- (2) 如果主键是外部生成的,即主键值在参数对象中,无需开启主键生成策略配置,但是需要通过keyProperty标签或者注解指明主键字段(需要注意的是如果参数对象添加了 @Param(“XX”注解),在设置主键字段的时候格式应该是keyProperty = XX.主键字段 。这是mybatis的语法)。如果mapper接口继承了hzero的BaseMapper,且参数对象没有添加了 @Param,则无需配置keyProperty
- 2)支持通过mapper接口传入一个完整的sql ,但是插入的字段必须包含主键字段。比如
insert into student (id,name,sex)values ('1','张三',‘男’)
但是不支持
insert into student values ('1','张三',‘男’)
否则在拦截时无法获取的主键ID
- 1)支持通过mapper接口传入一个对象,然后在xml中通过mybatis的动态sql拼接sql语句。但是需要注意一下两点:
-
支持自定义批量插入语句,包含以下两种方式
-
- 支持通过mapper接口传入一个对象列表,然后在xml中通过mybatis的动态sql拼接sql。无论是否开启主键回写都需要手动设置keyProperty标签,语法参见mybatis
-
2)支持通过mapper接口传入一个完整的批量插入sql ,但是插入的字段必须包含主键字段。批量插入支持以下两种形式
- (1)
insert into 表名(字段1,字段2 ,,,)values(值1,值2,值3 ,,,),values(值1,值2,值3 ,,,)
类型 。例如
insert into student (id,name,sex)values ('1','张三',‘男’),values ('2','李四',‘女’)
但是需要注意必须显示说明插入的字段,即不能省略
(字段1,字段2 ,,,)
,例如insert into student values ('1','张三',‘男’),values ('2','李四',‘女’)
- (2)
insert into 表名(字段1,字段2 ,,,)select ,,,
类型。例如
insert into student (id,name,sex)select ‘1’,‘张三’,‘男’ UNION '2','李四',‘女’
或者
insert into student (id,name,sex)select personId,personName,personSex from person where person.age >20
但是需要注意必须显示说明插入的字段,即不能省略(字段1,字段2 ,,,)且不允许select *
- (1)
-
四、版本更新日志
版本 0.12.0.RELEASE [2019-09-30]
- 初始版本发布
版本 1.1.0.RELEASE
- 支持自定义mapper
- 指定自定义单条插入和批量插入