| | |
| | | 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.CommonMapper; |
| | | 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.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.*; |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.Executors; |
| | | |
| | | public class InitMysqlData { |
| | | |
| | | /** |
| | | * 项目启动就执行后就执行该方法 |
| | | */ |
| | | @PostConstruct |
| | | //@PostConstruct 2022-06-17屏掉,暂时用不上 |
| | | public static void initData(String packPath, CommonService commonService){ |
| | | |
| | | //项目启动的时候填入 |
| | | if(!StringUtils.isEmpty(packPath)){ |
| | | Set<Class<?>> classes = VariableAesKey.classData(packPath); |
| | | Map<String,String> aesKeysFild = new HashMap<>(); |
| | | boolean isAes = false; |
| | | String tableName = null; |
| | | String fildName = null; |
| | | String fildValue = null; |
| | | |
| | | SqlSentence sqlSentence = new SqlSentence(); |
| | | Map<String,Object> values = new HashMap<>(); |
| | | |
| | | for(Class<?> cl:classes){ |
| | | //表名称 |
| | | boolean hasAnnotation = cl.isAnnotationPresent(Table.class); |
| | | if(!hasAnnotation){ |
| | | //解析表数据 |
| | | 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; |
| | | } |
| | | Table table = cl.getAnnotation(Table.class); |
| | | tableName = table.name(); |
| | | 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; |
| | | } |
| | | |
| | | aesKeysFild = new HashMap<>(); |
| | | isAes = false; |
| | | if(isUpdate){ |
| | | values = map; |
| | | sqlSentence.sqlSentence("UPDATE "+fieldData.getTableName()+" SET "+setField.toString()+" WHERE "+fieldData.getId()+" = #{m."+fieldData.getId()+"}",values); |
| | | |
| | | // 取得本类的全部属性 |
| | | Field[] fields = cl.getDeclaredFields(); |
| | | fields = VariableAesKey.getPatentFields(fields,cl); |
| | | for (Field field:fields) { |
| | | fildName = null; |
| | | // 判断方法中是否有指定注解类型的注解 |
| | | hasAnnotation = field.isAnnotationPresent(MysqlHexAes.class); |
| | | if (hasAnnotation) { |
| | | // 根据注解类型返回方法的指定类型注解 |
| | | MysqlHexAes mysqlHexAes = field.getAnnotation(MysqlHexAes.class); |
| | | |
| | | //String aesKeyField = mysqlHexAes.aesKeyField(); |
| | | String aesKey = mysqlHexAes.aesKey(); |
| | | |
| | | if(StringUtils.isEmpty(aesKey)){ |
| | | aesKey = VariableAesKey.AES_KEY; |
| | | if(StringUtils.isEmpty(aesKey)){ |
| | | throw new RuntimeException("mysql的AES秘钥不能为空:"+field.getName()); |
| | | } |
| | | } |
| | | |
| | | hasAnnotation = field.isAnnotationPresent(Column.class); |
| | | if(hasAnnotation){ |
| | | Column column = field.getAnnotation(Column.class); |
| | | fildName = column.name(); |
| | | } |
| | | if(StringUtils.isEmpty(fildName)){ |
| | | fildName = field.getName(); |
| | | } |
| | | |
| | | sqlSentence.sqlSentence("SELECT id,"+fildName+" FROM "+tableName,values); |
| | | List<Map<String,Object>> list = commonService.selectListMap(CommonMapper.class,sqlSentence); |
| | | for(Map<String,Object> map:list){ |
| | | fildValue = (String)map.get(fildName); |
| | | System.out.println("fildValue:"+fildValue); |
| | | if(StringUtils.isEmpty(fildValue)){ |
| | | continue; |
| | | } |
| | | if(fildValue.length()%32==0 && MysqlHexAesTool.isHexStrValid(fildValue)){ |
| | | continue; |
| | | } |
| | | values.clear(); |
| | | values.put("id",map.get("id")); |
| | | values.put("filedData",fildValue); |
| | | sqlSentence.sqlSentence("UPDATE "+tableName+" SET "+fildName+" = #{m.filedData} WHERE id = #{m.id}",values); |
| | | if(commonService.updateSentence(sqlSentence)!=1){ |
| | | throw new ServiceException("更新超过1条,更新失败!"); |
| | | } |
| | | } |
| | | } |
| | | 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; |
| | | } |
| | | |
| | | |