@ -9,7 +9,6 @@ import java.sql.ResultSet;
import java.sql.SQLException ;
import java.sql.Time ;
import java.sql.Timestamp ;
import java.sql.Types ;
import java.time.LocalDate ;
import java.time.LocalDateTime ;
import java.time.LocalTime ;
@ -26,34 +25,29 @@ import java.util.Map;
import java.util.Map.Entry ;
import java.util.Objects ;
import java.util.Set ;
import java.util.function.Function ;
import java.util.function.Supplier ;
import java.util.stream.Collector ;
import java.util.stream.Collectors ;
import javax.servlet.http.HttpServletRequest ;
import javax.validation.Valid ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Component ;
import org.springframework.web.context.request.RequestContextHolder ;
import org.springframework.web.context.request.ServletRequestAttributes ;
import com.alibaba.fastjson.JSON ;
import com.alibaba.fastjson.JSONArray ;
import com.alibaba.fastjson.JSONObject ;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists ;
import com.alibaba.nacos.shaded.com.google.common.collect.Maps ;
import com.baomidou.mybatisplus.core.mapper.BaseMapper ;
import com.baomidou.mybatisplus.core.toolkit.IdWorker ;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper ;
import com.esotericsoftware.kryo.kryo5.minlog.Log ;
import com.google.api.client.util.Sets ;
import com.pictc.annotations.datalog.JoinCaseType ;
import com.pictc.annotations.datalog.JoinValueType ;
import com.pictc.annotations.datalog.LogJoin ;
import com.pictc.annotations.datalog.LogJoinColumn ;
import com.pictc.annotations.datalog.ValueDirectionType ;
import com.pictc.converts.ConverUtil ;
import com.pictc.datalog.DataOperationContent ;
import com.pictc.datalog.DataOperationListener ;
import com.pictc.datalog.DefaultDataOperationListener ;
import com.pictc.datalog.LogFieldInfo ;
import com.pictc.datalog.LogJoinInfo ;
import com.pictc.datalog.LogTableInfo ;
@ -63,12 +57,12 @@ import com.pictc.exceptions.OrmException;
import com.pictc.jdbc.JdbcContext ;
import com.pictc.jdbc.ResultSetUtils ;
import com.pictc.jdbc.model.JdbcParam ;
import com.xjrsoft.common.enums.YesOrNoEnum ;
import com.xjrsoft.common.exception.BusinessException ;
import com.xjrsoft.common.utils.SecureUtil ;
import com.xjrsoft.module.common.db.utils.CommonCallUtils ;
import com.xjrsoft.module.datalog.entity.DataChangeLog ;
import com.xjrsoft.module.datalog.entity.json.FieldChange ;
import com.xjrsoft.module.datalog.service .DatalogService ;
import com.xjrsoft.module.datalog.mapper .DatalogMapper ;
import com.xjrsoft.module.datalog.vo.DataChangeLogVo ;
import com.xjrsoft.module.datalog.vo.OperationType ;
import com.xjrsoft.module.organization.dto.UserDto ;
@ -91,56 +85,15 @@ public class DataLogTools {
private static Object lock = new Object ( ) ;
public static final String SQL_HAS_TABLE = " select count(*) from log_table_info where tbl_name = ? " ;
public static final String SQL_INST_TABLE = " INSERT INTO log_table_info (tbl_name) VALUES (?); " ;
public static final String SQL_LOG_TABLE_LIST = " select tbl_name FROM log_table_info " ;
public static final String SQL_PLACEHOLDER = " \\ $ \\ {TBL_NAME \\ } " ;
public static final String [ ] SQL_CREATE_TABLE = {
" CREATE TABLE ${TBL_NAME} ( \ r \ n " +
" id VARCHAR(32) NOT NULL, \ r \ n " +
" flow_id VARCHAR(32), \ r \ n " +
" pid VARCHAR(32) DEFAULT '#', \ r \ n " +
" entity_class_name VARCHAR(255), \ r \ n " +
" bus_name VARCHAR(100), \ r \ n " +
" entity_id BIGINT, \ r \ n " +
" field_changes TEXT, \ r \ n " +
" operation_type VARCHAR(20), \ r \ n " +
" operator_id BIGINT, \ r \ n " +
" operator_name VARCHAR(100), \ r \ n " +
" operation_time TIMESTAMPTZ, \ r \ n " +
" operation_ip VARCHAR(50), \ r \ n " +
" PRIMARY KEY (id) \ r \ n " +
" ); " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" flow_id \" IS '流水id'; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" pid \" IS '父表ID,根节点#'; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" entity_class_name \" IS '实体类名称(全类名)'; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" bus_name \" IS '业务名称'; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" entity_id \" IS '操作的实体ID( 主键值) '; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" field_changes \" IS '属性值记录( JSON格式存储字段变更详情) '; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" operation_type \" IS '操作类型: INSERT-新增, UPDATE-修改, DELETE-删除'; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" operator_id \" IS '操作人ID'; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" operator_name \" IS '操作人姓名'; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" operation_time \" IS '操作时间'; " ,
" COMMENT ON COLUMN ${TBL_NAME}. \" operation_ip \" IS '操作IP地址'; " ,
" CREATE INDEX idx_${TBL_NAME}_enityt_id ON ${TBL_NAME} (entity_id) "
} ;
public static final String SQL_INSERT = " INSERT INTO ${TBL_NAME} ( \ r \ n " +
" id, flow_id, pid, entity_class_name, bus_name, \ r \ n " +
" entity_id, field_changes, operation_type, operator_id, \ r \ n " +
" operator_name, operation_time, operation_ip \ r \ n " +
" ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?); " ;
public static final String SQL_LIST = " SELECT * FROM ${TBL_NAME} WHERE entity_id = ? ORDER BY operation_time DESC, flow_id DESC " ;
public static final Set < String > excludeFields = SetUtils . of ( " id " , " tenantId " , " dataVersion " , " createUserId " , " createDate " , " modifyUserId " , " modifyDate " , " modifyDate " , " deleteMark " ) ;
private static DatalogMapper logDbService ;
@Autowired
public void setLogDbService ( DatalogMapper logDbService ) {
DataLogTools . logDbService = logDbService ;
}
public static DataChangeLog createLog ( Class < ? > klazz , OperationType type ) {
DataChangeLog createLog = createLog ( klazz , type , null ) ;
return createLog . setFlowId ( IdUtil . getSnowflakeNextIdStr ( ) ) ;
@ -183,6 +136,10 @@ public class DataLogTools {
}
public static < T > T insert ( T entity ) {
return insert ( entity , new DefaultDataOperationListener < T > ( ) ) ;
}
public static < T > T insert ( T entity , DataOperationListener < T > listener ) {
Class < ? extends Object > klazz = entity . getClass ( ) ;
List < DataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . INSERT ) ;
@ -190,108 +147,209 @@ public class DataLogTools {
initJoinValue ( entity , tabInfo , null ) ;
Long idValue = tabInfo . getIdValue ( entity ) ;
BaseMapper mapper = MybatisTools . getMapper ( tabInfo . getEntityType ( ) ) ;
mapper . insert ( BeanUtil . toBean ( entity , tabInfo . getEntityType ( ) ) ) ;
datalog . setEntityId ( idValue ) ;
buildFields ( d atalog , tabInfo , entity , null ) ;
logs . add ( datalog ) ;
List < LogJoinInfo > joins = tabInfo . getJoins ( ) ;
if ( CollectionUtils . isNotEmpty ( joins ) ) {
for ( LogJoinInfo join : joins ) {
if ( join . getJoin ( ) . caseType ( ) = = JoinCaseType . FULL ) {
buildJoins ( logs , datalog , OperationType . INSERT , tabInfo , join , entity ) ;
DataOperationContent < T > content = null ;
if ( listener ! = null ) {
content = D ataOperationContent . of ( tabInfo , OperationType . INSERT , entity, null ) ;
listener . before ( content ) ;
}
try {
mapper . insert ( BeanUtil . toBean ( entity , tabInfo . getEntityType ( ) ) ) ;
datalog . setEntityId ( idValue ) ;
buildFields ( datalog , tabInfo , entity , null ) ;
logs . add ( datalog ) ;
List < LogJoinInfo > joins = tabInfo . getJoins ( ) ;
if ( CollectionUtils . isNotEmpty ( joins ) ) {
for ( LogJoinInfo join : joins ) {
if ( join . getJoin ( ) . caseType ( ) = = JoinCaseType . FULL ) {
buildJoins ( logs , datalog , OperationType . INSERT , tabInfo , join , entity ) ;
}
}
}
if ( listener ! = null ) {
listener . after ( content ) ;
}
saveLogs ( tabInfo , logs ) ;
} catch ( Exception e ) {
if ( listener ! = null ) {
content . setError ( e ) ;
listener . onError ( content ) ;
}
throw e ;
} finally {
if ( listener ! = null ) {
listener . onFinally ( content ) ;
}
}
saveLogs ( tabInfo , logs ) ;
return entity ;
}
public static < T > T update ( T dto ) {
return update ( dto , new DefaultDataOperationListener < T > ( ) ) ;
}
public static < T > T update ( T dto , DataOperationListener < T > listener ) {
Class < ? extends Object > klazz = dto . getClass ( ) ;
LogTableInfo tabInfo = getAnnotation ( klazz ) ;
Long idValue = tabInfo . getIdValue ( dto ) ;
BaseMapper mapper = MybatisTools . getMapper ( tabInfo . getEntityType ( ) ) ;
Object old = findById ( klazz , idValue ) ;
if ( old ! = null ) {
List < DataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . UPDATE ) ;
initJoinValue ( dto , tabInfo , null ) ;
mapper . updateById ( tabInfo . toEntity ( dto ) ) ;
datalog . setEntityId ( idValue ) ;
buildFields ( d atalog , tabInfo , dto , old ) ;
logs . add ( datalog ) ;
List < LogJoinInfo > joins = tabInfo . getJoins ( ) ;
if ( ! CollectionUtils . isNotEmpty ( joins ) ) {
for ( LogJoinInfo join : joins ) {
if ( join . g etJoin ( ) . caseType ( ) = = JoinCaseType . FULL ) {
buildJoins ( log s , datalog , OperationType . UPDATE , tabInfo, join , dto ) ;
T old = findById ( klazz , idValue ) ;
DataOperationContent < T > content = null ;
if ( listener ! = null ) {
content = DataOperationContent . of ( tabInfo , OperationType . UPDATE , dto , old );
listener . before ( content ) ;
}
try {
if ( old ! = null ) {
List < D ataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . UPDATE ) ;
initJoinValue ( dto , tabInfo , null ) ;
mapper . updateById ( tabInfo . toEntity ( dto ) ) ;
datalog . s etEntityId ( idValue ) ;
buildField s ( datalog , tabInfo , dto , old ) ;
logs . add ( datalog ) ;
List < LogJoinInfo > joins = tabInfo . getJoins ( ) ;
if ( ! CollectionUtils . isNotEmpty ( joins ) ) {
for ( LogJoinInfo join : joins ) {
if ( join . getJoin ( ) . caseType ( ) = = JoinCaseType . FULL ) {
buildJoins ( logs , datalog , OperationType . UPDATE , tabInfo , join , dto ) ;
}
}
}
if ( listener ! = null ) {
listener . after ( content ) ;
}
saveLogs ( tabInfo , logs ) ;
} else {
throw new OrmException ( " 数据不存在 " ) ;
}
} catch ( Exception e ) {
if ( listener ! = null ) {
content . setError ( e ) ;
listener . onError ( content ) ;
}
throw e ;
} finally {
if ( listener ! = null ) {
listener . onFinally ( content ) ;
}
saveLogs ( tabInfo , logs ) ;
} else {
throw new OrmException ( " 数据不存在 " ) ;
}
return dto ;
}
public static < T > T delete ( T dto ) {
return delete ( dto , new DefaultDataOperationListener < T > ( ) ) ;
}
public static < T > T delete ( T entity ) {
public static < T > T delete ( T entity , DataOperationListener < T > listener ) {
Class < ? extends Object > klazz = entity . getClass ( ) ;
List < DataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
LogTableInfo tabInfo = getAnnotation ( klazz ) ;
Long idValue = tabInfo . getIdValue ( entity ) ;
BaseMapper mapper = MybatisTools . getMapper ( tabInfo . getEntityType ( ) ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . DELETE ) ;
d atalog . setEntityId ( idValue ) ;
buildFields ( datalog , tabInfo , entity , null ) ;
logs . add ( datalog ) ;
delete ( entity , tabInfo , mapper ) ;
List < LogJoinInfo > joins = tabInfo . getJoins ( ) ;
if ( ! CollectionUtils . isNotEmpty ( joins ) ) {
for ( LogJoinInfo join : joins ) {
if ( join . getJoin ( ) . caseType ( ) = = JoinCaseType . FULL ) {
buildJoins ( logs , datalog , OperationType . DELETE , tabInfo , join , entity ) ;
T old = findById ( klazz , idValue ) ;
D ataOperationContent < T > content = null ;
if ( listener ! = null ) {
content = DataOperationContent . of ( tabInfo , OperationType . DELETE , old , null ) ;
listener . before ( content ) ;
}
try {
DataChangeLog datalog = createLog ( klazz , OperationType . DELETE ) ;
datalog . setEntityId ( idValue ) ;
buildFields ( datalog , tabInfo , entity , null ) ;
logs . add ( datalog ) ;
delete ( entity , tabInfo , mapper ) ;
List < LogJoinInfo > joins = tabInfo . getJoins ( ) ;
if ( ! CollectionUtils . isNotEmpty ( joins ) ) {
for ( LogJoinInfo join : joins ) {
if ( join . getJoin ( ) . caseType ( ) = = JoinCaseType . FULL ) {
buildJoins ( logs , datalog , OperationType . DELETE , tabInfo , join , entity ) ;
}
}
}
if ( listener ! = null ) {
listener . after ( content ) ;
}
saveLogs ( tabInfo , logs ) ;
} catch ( Exception e ) {
if ( listener ! = null ) {
content . setError ( e ) ;
listener . onError ( content ) ;
}
throw e ;
} finally {
if ( listener ! = null ) {
listener . onFinally ( content ) ;
}
}
saveLogs ( tabInfo , logs ) ;
return entity ;
}
public static boolean deleteByIds ( Class < ? > klazz , @Valid List < Long > ids ) {
public static < T > boolean deleteByIds ( Class < T > klazz , @Valid List < Long > ids ) {
return deleteByIds ( klazz , ids , new DefaultDataOperationListener < T > ( ) ) ;
}
public static < T > boolean deleteByIds ( Class < T > klazz , @Valid List < Long > ids , DataOperationListener < T > listener ) {
for ( Long id : ids ) {
deleteById ( klazz , id ) ;
deleteById ( klazz , id , listener );
}
return true ;
}
public static < T > T deleteById ( Class < T > klazz , Long id ) {
return deleteById ( klazz , id , new DefaultDataOperationListener < T > ( ) ) ;
}
public static < T > T deleteById ( Class < T > klazz , Long id , DataOperationListener < T > listener ) {
LogTableInfo tabInfo = getAnnotation ( klazz ) ;
BaseMapper mapper = MybatisTools . getMapper ( tabInfo . getEntityType ( ) ) ;
T entity = findById ( klazz , id ) ;
if ( entity = = null ) return null ;
DataOperationContent < T > content = null ;
if ( listener ! = null ) {
content = DataOperationContent . of ( tabInfo , OperationType . DELETE , entity , null ) ;
listener . before ( content ) ;
}
List < DataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
delete ( entity , tabInfo , mapper ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . DELETE ) ;
datalog . setEntityId ( id ) ;
buildFields ( datalog , tabInfo , entity , null ) ;
logs . add ( datalog ) ;
List < LogJoinInfo > joins = tabInfo . getJoins ( ) ;
if ( ! CollectionUtils . isNotEmpty ( joins ) ) {
for ( LogJoinInfo join : joins ) {
if ( join . getJoin ( ) . caseType ( ) = = JoinCaseType . FULL ) {
buildJoins ( logs , datalog , OperationType . DELETE , tabInfo , join , entity ) ;
try {
delete ( entity , tabInfo , mapper ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . DELETE ) ;
datalog . setEntityId ( id ) ;
buildFields ( datalog , tabInfo , entity , null ) ;
logs . add ( datalog ) ;
List < LogJoinInfo > joins = tabInfo . getJoins ( ) ;
if ( ! CollectionUtils . isNotEmpty ( joins ) ) {
for ( LogJoinInfo join : joins ) {
if ( join . getJoin ( ) . caseType ( ) = = JoinCaseType . FULL ) {
buildJoins ( logs , datalog , OperationType . DELETE , tabInfo , join , entity ) ;
}
}
}
if ( listener ! = null ) {
listener . after ( content ) ;
}
saveLogs ( tabInfo , logs ) ;
} catch ( Exception e ) {
if ( listener ! = null ) {
content . setError ( e ) ;
listener . onError ( content ) ;
}
throw e ;
} finally {
if ( listener ! = null ) {
listener . onFinally ( content ) ;
}
}
saveLogs ( tabInfo , logs ) ;
return entity ;
}
@ -304,64 +362,117 @@ public class DataLogTools {
}
}
public static boolean enable ( Class < ? > klazz , @Valid List < Long > ids ) {
public static < T > boolean enable ( Class < T > klazz , @Valid List < Long > ids ) {
return enable ( klazz , ids , new DefaultDataOperationListener < T > ( ) ) ;
}
public static < T > boolean enable ( Class < T > klazz , @Valid List < Long > ids , DataOperationListener < T > listener ) {
for ( Long id : ids ) {
enableById ( klazz , id ) ;
enableById ( klazz , id , listener );
}
return true ;
}
public static < T > T enableById ( Class < T > klazz , Long id ) {
LogTableInfo tabInfo = getAnnotation ( klazz ) ;
BaseMapper mapper = MybatisTools . getMapper ( tabInfo . getEntityType ( ) ) ;
Object entity = findNativeById ( klazz , id ) ;
if ( entity = = null ) return null ;
T old = BeanUtils . newInstance ( klazz ) ;
BeanUtil . copyProperties ( entity , old , true ) ;
List < DataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
BeanUtils . setFieldValue ( " valid " , YesOrNoEnum . YES . getTextCode ( ) , entity ) ;
mapper . updateById ( entity ) ;
T dto = ( T ) tabInfo . toDto ( entity ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . UPDATE ) ;
datalog . setEntityId ( id ) ;
buildFields ( datalog , tabInfo , dto , tabInfo . toDto ( old ) ) ;
logs . add ( datalog ) ;
saveLogs ( tabInfo , logs ) ;
return dto ;
return enableById ( klazz , id , new DefaultDataOperationListener < T > ( ) ) ;
}
public static boolean dis able( Class < ? > klazz , @Valid List < Long > ids ) {
public static < T > T en ableById ( Class < T > klazz , Long id , DataOperationListener < T > listener ) {
LogTableInfo tabInfo = getAnnotation ( klazz ) ;
BaseMapper mapper = MybatisTools . getMapper ( tabInfo . getEntityType ( ) ) ;
T old = findById ( klazz , id ) ;
if ( old = = null ) return null ;
DataOperationContent < T > content = null ;
if ( listener ! = null ) {
content = DataOperationContent . of ( tabInfo , OperationType . ENABLE , old , old ) ;
listener . before ( content ) ;
}
T entity = null ;
try {
List < DataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
CommonCallUtils . enableBefore ( tabInfo . getTableName ( ) , id ) ;
entity = findById ( klazz , id ) ;
content . setObj ( entity ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . ENABLE ) ;
datalog . setEntityId ( id ) ;
buildFields ( datalog , tabInfo , entity , old ) ;
logs . add ( datalog ) ;
if ( listener ! = null ) {
listener . after ( content ) ;
}
saveLogs ( tabInfo , logs ) ;
} catch ( Exception e ) {
if ( listener ! = null ) {
content . setError ( e ) ;
listener . onError ( content ) ;
}
throw e ;
} finally {
if ( listener ! = null ) {
listener . onFinally ( content ) ;
}
}
return entity ;
}
public static < T > boolean disable ( Class < T > klazz , @Valid List < Long > ids ) {
return disable ( klazz , ids , new DefaultDataOperationListener < T > ( ) ) ;
}
public static < T > boolean disable ( Class < T > klazz , @Valid List < Long > ids , DataOperationListener < T > listener ) {
for ( Long id : ids ) {
disableById ( klazz , id ) ;
disableById ( klazz , id , listener );
}
return true ;
}
public static < T > T disableById ( Class < T > klazz , Long id ) {
public static < T > T disableById ( Class < T > klazz , Long id , DataOperationListener < T > listener ) {
LogTableInfo tabInfo = getAnnotation ( klazz ) ;
BaseMapper mapper = MybatisTools . getMapper ( tabInfo . getEntityType ( ) ) ;
Object entity = findNative ById ( klazz , id ) ;
if ( entity = = null ) return null ;
T old = BeanUtils . newInstance ( klazz ) ;
BeanUtil . copyProperties ( entity , old , true ) ;
List < DataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
BeanUtils . setFieldValue ( " valid " , YesOrNoEnum . NO . getTextCode ( ) , entity ) ;
mapper . updateById ( entity ) ;
T dto = ( T ) tabInfo . toDto ( entity ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . UPDATE ) ;
datalog . setEntityId ( id ) ;
buildFields ( d atalog , tabInfo , dto , tabInfo . toDto ( old ) ) ;
logs . add ( datalog ) ;
saveLogs ( tabInfo , logs ) ;
return dto ;
T old = findById ( klazz , id ) ;
if ( old = = null ) return null ;
DataOperationContent < T > content = null ;
if ( listener ! = null ) {
content = DataOperationContent . of ( tabInfo , OperationType . DISABLE , old , old ) ;
listener . before ( content ) ;
}
T entity = null ;
try {
List < D ataChangeLog > logs = CollectionUtils . newArrayList ( ) ;
CommonCallUtils . enableBefore ( tabInfo . getTableName ( ) , id ) ;
entity = findById ( klazz , id ) ;
content . setObj ( entity ) ;
DataChangeLog datalog = createLog ( klazz , OperationType . DISABLE ) ;
datalog . setEntityId ( id ) ;
buildFields ( datalog , tabInfo , entity , old ) ;
logs . add ( datalog ) ;
if ( listener ! = null ) {
listener . after ( content ) ;
}
saveLogs ( tabInfo , logs ) ;
} catch ( Exception e ) {
if ( listener ! = null ) {
content . setError ( e ) ;
listener . onError ( content ) ;
}
throw e ;
} finally {
if ( listener ! = null ) {
listener . onFinally ( content ) ;
}
}
return entity ;
}
public static < T > T findById ( Class < T > klazz , Serializable id ) {
public static < T > T findById ( Class < ? > klazz , Serializable id ) {
return findById ( klazz , id , false ) ;
}
public static < T > T findById ( Class < T > klazz , Serializable id , boolean full ) {
public static < T > T findById ( Class < ? > klazz , Serializable id , boolean full ) {
LogTableInfo tabInfo = getAnnotation ( klazz ) ;
BaseMapper mapper = MybatisTools . getMapper ( tabInfo . getEntityType ( ) ) ;
Object old = mapper . selectById ( id ) ;
@ -755,34 +866,35 @@ public class DataLogTools {
public static void saveLogs ( LogTableInfo tableInfo , List < DataChangeLog > logs ) {
String tableName = parseLogTableName ( tableInfo ) ;
initTable ( tableName ) ;
String sql = parseSql( SQL_INSERT, tableName) ;
List < List < JdbcParam > > batchParams = CollectionUtils. newArrayList( ) ;
Map < String , List < DataChangeLog > > pidMap = logs . stream ( ) . collect( Collectors. groupingBy( DataChangeLog: : getPid ) ) ;
// String sql = parseSql( SQL_INSERT, tableName) ;
// List<List<JdbcParam>> batchParams = CollectionUtils. newArrayList() ;
// Map<String, List<DataChangeLog>> pidMap = logs.stream(). collect( Collectors. groupingBy( DataChangeLog::getPid)) ;
//
// for (DataChangeLog item : logs) {
// //没有改变的属性,且没有子表修改时跳过
// if(!item.hasFieldChanges() && !hasChild(item, pidMap)) {
// continue;
// }
//
// List<JdbcParam> params = CollectionUtils.newArrayList();
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getId()));
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getFlowId()));
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getPid()));
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getEntityClassName()));
// params.add(JdbcParam.of(Types.VARCHAR,String.class, item.getBusName()));
// params.add(JdbcParam.of(Types.BIGINT,long.class, item.getEntityId()));
// params.add(JdbcParam.of(Types.VARCHAR,String.class,JSON.toJSONString(item.getFieldChanges())));
// params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperationType().name()));
// params.add(JdbcParam.of(Types.VARCHAR,long.class,item.getOperatorId()));
// params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperatorName()));
// params.add(JdbcParam.of(Types.TIMESTAMP,Timestamp.class,item.getOperationTime()));
// params.add(JdbcParam.of(Types.VARCHAR,String.class,item.getOperationIp()));
// batchParams.add(params);
// }
// executeBatch(sql, batchParams);
for ( DataChangeLog item : logs ) {
//没有改变的属性,且没有子表修改时跳过
if ( ! item . hasFieldChanges ( ) & & ! hasChild ( item , pidMap ) ) {
continue ;
}
List < JdbcParam > params = CollectionUtils . newArrayList ( ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , item . getId ( ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , item . getFlowId ( ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , item . getPid ( ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , item . getEntityClassName ( ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , item . getBusName ( ) ) ) ;
params . add ( JdbcParam . of ( Types . BIGINT , long . class , item . getEntityId ( ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , JSON . toJSONString ( item . getFieldChanges ( ) ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , item . getOperationType ( ) . name ( ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , long . class , item . getOperatorId ( ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , item . getOperatorName ( ) ) ) ;
params . add ( JdbcParam . of ( Types . TIMESTAMP , Timestamp . class , item . getOperationTime ( ) ) ) ;
params . add ( JdbcParam . of ( Types . VARCHAR , String . class , item . getOperationIp ( ) ) ) ;
batchParams . add ( params ) ;
logDbService . insertDataLog ( tableName , item ) ;
}
executeBatch ( sql , batchParams ) ;
}
/**
@ -794,11 +906,8 @@ public class DataLogTools {
synchronized ( lock ) {
//如果没有日志表时,重新创建
if ( ! hasTable ( tableName ) ) {
for ( int i = 0 ; i < SQL_CREATE_TABLE . length ; i + + ) {
execute ( parseSql ( SQL_CREATE_TABLE [ i ] , tableName ) ) ;
}
//将表名进行记录
executeUpdate ( SQL_INST_TABLE , ListUtils . ofArray ( JdbcParam . ofString ( tableName ) ) ) ;
logDbService . createDatalogTable ( tableName ) ;
logDbService . addTableInfo ( tableName ) ;
logTables . add ( tableName ) ;
log . info ( " 新增数据日志表:{} " , tableName ) ;
return true ;
@ -808,18 +917,14 @@ public class DataLogTools {
}
private static String parseSql ( String sql , String tableName ) {
return sql . replaceAll ( SQL_PLACEHOLDER , tableName ) ;
}
private static boolean hasTable ( String tableName ) {
synchronized ( lock ) {
if ( logTables = = null ) {
List < String > tabs = queryListPrimitive ( SQL_LOG_TABLE_LIST , String . class , null ) ;
List < String > tabs = logDbService . getTableList ( ) ;
logTables = new HashSet < String > ( tabs ) ;
}
if ( logTables . contains ( tableName ) ) return true ;
Long count = queryPrimitive ( SQL_HAS_TABLE , long . class , Lists . newArrayList ( JdbcParam . ofString ( tableName ) ) ) ;
Long count = logDbService . getCountByTableName ( tableName ) ;
boolean flag = count ! = null & & count > 0 ;
if ( flag ) {
logTables . add ( tableName ) ;
@ -851,40 +956,41 @@ public class DataLogTools {
if ( initTable ( tableName ) ) {
return null ;
}
List < DataChangeLog > result = CollectionUtils . newArrayList ( ) ;
String sql = parseSql ( SQL_LIST , tableName ) ;
JdbcContext context = null ;
try {
context = new JdbcContext ( true , true ) ;
context. init ( sql ) ;
context. setParams ( ListUtils . ofArray ( JdbcParam . ofLong ( dataId ) ) ) ;
ResultSet set = context . executeQuery ( ) ;
Map < String , String > names = ResultSetUtils . getMapColumns ( set ) ;
while ( set . next ( ) ) {
DataChangeLog log = new DataChangeLog ( ) ;
log . setId ( set . getString ( " id " ) ) ;
log. setFlowId ( set . getString ( " flow_id " ) ) ;
log. setPid ( set . getString ( " pid " ) ) ;
log. setEntityClassName ( set . getString ( " entity_class_name " ) ) ;
log. setBusName ( set . getString ( " bus_name " ) ) ;
log. setEntityId ( set . getLong ( " entity_id " ) ) ;
log. setOperationType ( OperationType . valueOf ( set . getString ( " operation_type " ) ) ) ;
log. setOperationIp ( set . getString( " operation_ip " ) ) ;
log. setOperatorId ( set . getLong ( " operator_id " ) ) ;
log. setOperatorName ( set . getString ( " operator_name " ) ) ;
log. setOperationTime ( ResultSetUtils . getObject ( set , " operation_time " , LocalDateTime . class ) ) ;
String json = set . getString ( " field_changes " ) ;
if ( StringUtils . isNotEmpty ( json ) ) {
log . setFieldChanges ( JSON . parseArray ( json ) . toJavaList ( FieldChange . class ) ) ;
}
result . add ( log ) ;
}
return toVo ( result ) ;
} catch ( SQLException e ) {
throw context . createException ( e ) ;
} finally {
context . end ( ) ;
}
List < DataChangeLog > logs = logDbService . selectByDataId ( tableName , dataId ) ;
return toVo ( logs ) ;
// String sql = parseSql(SQL_LIST, tableName) ;
// JdbcContext context = null;
// try {
// context = new JdbcContext(true,true) ;
// context.init(sql) ;
// context.setParams(ListUtils.ofArray(JdbcParam.ofLong(dataId))) ;
// ResultSet set = context.executeQuery() ;
// Map<String, String> names = ResultSetUtils.getMapColumns(set);
// while (set.next()) {
// DataChangeLog log = new DataChangeLog() ;
// log.setId(set.getString("id")) ;
// log.setFlowId(set.getString("flow_id")) ;
// log.setPid(set.getString("pid")) ;
// log.setEntityClassName(set.getString("entity_class_name")) ;
// log.setBusName(set.getString("bus_name")) ;
// log.setEntityId(set.getLong("entity_id")) ;
// log. setOperationType(OperationType.valueOf(set. getString(" operation_type"))) ;
// log. setOperationIp(set.getString("operation_ip")) ;
// log. setOperatorId(set.getLong("operator_id")) ;
// log. setOperatorName(set.getString("operator_name")) ;
// log.setOperationTime(ResultSetUtils.getObject(set,"operation_time",LocalDateTime.class)) ;
// String json = set.getString("field_changes");
// if(StringUtils.isNotEmpty(json)) {
// log.setFieldChanges(JSON.parseArray(json).toJavaList(FieldChange.class));
// }
// result.add(log);
// }
// return toVo(result);
// } catch (SQLException e) {
// throw context.createException(e);
// } finally {
// context.end();
// }
}
private static List < DataChangeLogVo > toVo ( List < DataChangeLog > list ) {