package com.hx.mybatis.aes.springbean;
|
|
import com.gitee.sunchenbin.mybatis.actable.annotation.Column;
|
import com.gitee.sunchenbin.mybatis.actable.annotation.Table;
|
import com.hx.common.annotations.MysqlHexAes;
|
import com.hx.common.dao.mapper.CommonMapper;
|
import com.hx.common.service.CommonService;
|
import com.hx.exception.ServiceException;
|
import com.hx.mybatisTool.SqlSentence;
|
import com.hx.util.StringUtils;
|
import com.hx.util.mysql.aes.MysqlHexAesTool;
|
|
import javax.annotation.PostConstruct;
|
import java.lang.reflect.Field;
|
import java.util.*;
|
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.Executors;
|
|
public class InitMysqlData {
|
|
/**
|
* 项目启动就执行后就执行该方法
|
*/
|
@PostConstruct
|
public static void initData(String packPath, CommonService commonService){
|
|
//项目启动的时候填入
|
if(!StringUtils.isEmpty(packPath)){
|
Set<Class<?>> classes = VariableAesKey.classData(packPath);
|
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
//解析表数据
|
List<FieldData> fieldDatas = entityhandle(classes);
|
|
int pageSize = 500;
|
//创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
|
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(20);
|
try{
|
for(FieldData fieldData:fieldDatas){
|
//获取条数
|
sqlSentence.sqlSentence("SELECT COUNT(0) FROM "+fieldData.getTableName(),values);
|
int total = commonService.selectCountSql(sqlSentence);
|
if(total ==0 ){
|
continue;
|
}
|
int pageTotal = total/pageSize+1;
|
for(int i= 0;i<pageTotal;i++){
|
int finalI = i;
|
fixedThreadPool.execute(new Runnable() {
|
@Override
|
public void run() {
|
//更新数据
|
updateData(fieldData,commonService, finalI,pageSize);
|
}
|
});
|
}
|
}
|
}catch (Exception e){
|
e.printStackTrace();
|
}finally {
|
fixedThreadPool.shutdown();
|
}
|
}
|
}
|
|
/**更新数据*/
|
public static void updateData(FieldData fieldData,CommonService commonService,int pageNum,int pageSize){
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
//查询数据
|
StringBuilder selectField = new StringBuilder();
|
selectField.append(fieldData.getId());
|
for(String fieldName:fieldData.getEncrypFields()){
|
selectField.append(","+fieldName);
|
}
|
pageNum = pageNum*pageSize;
|
|
sqlSentence.sqlSentence("SELECT "+selectField.toString()+" FROM "+fieldData.getTableName()+" LIMIT "+pageNum+","+pageSize,values);
|
List<Map<String,Object>> list = commonService.selectListMap(CommonMapper.class,sqlSentence);
|
|
boolean isUpdate = false;
|
for (Map<String,Object> map:list){
|
isUpdate = false;
|
StringBuilder setField = new StringBuilder();
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
String mapKey = entry.getKey();
|
String mapValue = (String) entry.getValue();
|
if(StringUtils.isEmpty(mapValue)){
|
continue;
|
}
|
if(mapValue.length()%32==0 && MysqlHexAesTool.isHexStrValid(mapValue)){
|
continue;
|
}
|
if(fieldData.getId().equals(mapKey)){
|
continue;
|
}
|
if(setField.length()>0){
|
setField.append(",");
|
}
|
setField.append(mapKey+" = #{m."+mapKey+"}");
|
isUpdate = true;
|
}
|
|
if(isUpdate){
|
values = map;
|
sqlSentence.sqlSentence("UPDATE "+fieldData.getTableName()+" SET "+setField.toString()+" WHERE "+fieldData.getId()+" = #{m."+fieldData.getId()+"}",values);
|
|
if(commonService.updateSentence(sqlSentence)!=1){
|
throw new ServiceException("更新超过1条,更新失败!");
|
}
|
}
|
}
|
|
}
|
|
/**获取到表的数据*/
|
public static List<FieldData> entityhandle(Set<Class<?>> classes){
|
|
List<FieldData> fildDatas = new ArrayList<>();
|
//存储单表字段信息
|
FieldData fildData;
|
//存储需要加密的字段
|
Set<String> encrypFields;
|
|
String fildName;
|
|
for(Class<?> cl:classes){
|
fildData = new FieldData();
|
encrypFields = new HashSet<>();
|
|
//表名称
|
if(!cl.isAnnotationPresent(Table.class)){
|
continue;
|
}
|
Table table = cl.getAnnotation(Table.class);
|
fildData.setTableName(table.name());
|
|
// 取得本类的全部属性
|
Field[] fields = cl.getDeclaredFields();
|
fields = VariableAesKey.getPatentFields(fields,cl);
|
for (Field field:fields) {
|
|
fildName = null;
|
if(field.isAnnotationPresent(Column.class)){
|
Column column = field.getAnnotation(Column.class);
|
fildName = column.name();
|
if(StringUtils.isEmpty(fildName)){
|
fildName = field.getName();
|
}
|
if(column.isKey()){
|
fildData.setId(fildName);
|
}
|
}else{
|
fildName = field.getName();
|
}
|
|
// 判断方法中是否有指定注解类型的注解
|
if (!field.isAnnotationPresent(MysqlHexAes.class)) {
|
continue;
|
}
|
// 根据注解类型返回方法的指定类型注解
|
MysqlHexAes mysqlHexAes = field.getAnnotation(MysqlHexAes.class);
|
//判断版本号是不是一样的
|
if(!StringUtils.isEmpty(VariableAesKey.INIT_VERSION)){
|
if(!VariableAesKey.INIT_VERSION.equals(mysqlHexAes.initVersion())){
|
continue;
|
}
|
}else{
|
if(!StringUtils.isEmpty(mysqlHexAes.initVersion())){
|
continue;
|
}
|
}
|
|
String aesKey = mysqlHexAes.aesKey();
|
if(StringUtils.isEmpty(aesKey)){
|
aesKey = VariableAesKey.AES_KEY;
|
if(StringUtils.isEmpty(aesKey)){
|
throw new RuntimeException("mysql的AES秘钥不能为空:"+field.getName());
|
}
|
}
|
|
encrypFields.add(fildName);
|
}
|
//是否有需要加密得字段
|
if(encrypFields.size()<=0){
|
continue;
|
}
|
fildData.setEncrypFields(encrypFields);
|
fildDatas.add(fildData);
|
}
|
return fildDatas;
|
}
|
|
|
}
|