設計一個業務改動信息時的自定義記錄,例如新增、修改、刪除數據等。並且記錄的規則可以通過配置的方式控制。大家需要根據各自業務場景參考,歡迎討論。偽代碼如下: 實體類: @TableName("tbl_user") User{ String id String name Integer age Stri ...
設計一個業務改動信息時的自定義記錄,例如新增、修改、刪除數據等。並且記錄的規則可以通過配置的方式控制。大家需要根據各自業務場景參考,歡迎討論。偽代碼如下:
實體類:
@TableName("tbl_user")
User{
String id
String name
Integer age
String addr
}
DAO層:
UserDao{
getById(Long id);
list(Wrapper wrapper);
}
自定義註解:
MybatisPropAnno{ String value Class<?> daoClazz }
Http介面請求參數:
SaveReq{ @MybatisPropAnno(value="name", daoClazz = UserDao.class) String userName; @MybatisPropAnno(value="age", daoClazz = UserDao.class) Integer userAge; } UpdateReq{ @MybatisPropAnno(value="id", daoClazz = UserDao.class) String userNo; @MybatisPropAnno(value="name", daoClazz = UserDao.class) String userName; @MybatisPropAnno(value="age", daoClazz = UserDao.class) Integer userAge; @MybatisPropAnno(value="id", daoClazz = DepartDao.class) String departId; String departAddress; }
Http介面:
TestController{ public void save(SaveReq saveReq){ operTypeInheritedThreadLocal.set(Enum."添加數據"); sthInheritedThreadLocal.set(saveReq); }; public void update(UpdateReq updateReq){ operTypeInheritedThreadLocal.set(Enum."更新數據"); sthInheritedThreadLocal.set(updateReq); }; @MybatisLogAnno("刪除數據") public void delete(){}; @MybatisLogAnno("查詢數據") public void query(){}; public void other(){}; }
SQL攔截器:
SqlInterceptor{ public Object intercept(Mybatis param){ OperType operType = operTypeInheritedThreadLocal.get if(operType == null){ return ; } // insert/update/delete/select String type = param.getSqlType(); if(operType == select){ return ; } String sql = param.getSql(); String tableName = sql.getTableName(); List<Field> fields = Reflect.getFields(sthInheritedThreadLocal.get()); for(Field field : fields){ MybatisPropAnno propAnno = field.getAnnotation(MybatisPropAnno); if(propAnno == null){ continue; } if(propAnno.getDaoClazz.getEntity.getTableName.equals(tableName )){ User oldUser = new JSONObject(); User newUser = new JSONObject(); if(type == insert){ oldUser = new JSONObject(); newUser = getInsertInfo(sql); } if(type == update){ oldUser = SpringContext.get(daoClazz).getById(field.value()); newUser = getUpdateInfo(sql); insertChangeLog(new JSONObject(), JSON.toJson(newUser)); } if(type == delete){ oldUser = SpringContext.get(daoClazz).getById(field.value()); newUser = new JSONObject(); } insertChangeLog(operType, traceId, oldUser, newUser); break; } } } }
Spring切麵:
SpringAop { public Object doAround(){ operTypeInheritedThreadLocal.remove } }
資料庫設計:
Table:dc_change_log
id changeTime changeType traceId oldInfo newInfo httpMethod table operator changeDesc
1 2020-01-01 添加用戶 123 {} {"name":"lil"} com.xx.TestCtrl.saveUser tbl_user admin descxxxxxxxxxxxx
2 2020-01-01 修改用戶 124 {"name":"lil"} {"name":"a"} com.xx.TestCtrl.updateUser tbl_user admin descxxxxxxxxxxxx
3 2020-01-01 修改用戶 124 {"addr":"南山"} {"addr":"福田"} com.xx.TestCtrl.updateUser tbl_department admin descxxxxxxxxxxxx
Table:dc_change_rule
id httpMethod table showRule
1 com.xx.TestCtrl.saveUser tbl_user [{"propKey":"name", "propDesc":"name detail info"}]
1 com.xx.TestCtrl.updateUser tbl_user [{"propKey":"name", "propDesc":"name detail info"}]
1 com.xx.TestCtrl.updateUser tbl_department [{"propKey":"addr", "propDesc":"addr detail info"}]