ANDRU-PC\Andru
2023-09-18 691dee7a71996cd99fdfe30bd61b2da95cc88ecd
提交 | 用户 | age
93b505 1 package com.hx.mybatis.aes.springbean;
C 2
3 import com.gitee.sunchenbin.mybatis.actable.annotation.Column;
4 import com.gitee.sunchenbin.mybatis.actable.annotation.Table;
5 import com.hx.common.annotations.MysqlHexAes;
a48817 6 import com.hx.common.dao.mapper.CommonMapper;
93b505 7 import com.hx.common.service.CommonService;
C 8 import com.hx.exception.ServiceException;
9 import com.hx.mybatisTool.SqlSentence;
10 import com.hx.util.StringUtils;
11 import com.hx.util.mysql.aes.MysqlHexAesTool;
12
13 import java.lang.reflect.Field;
b1097d 14 import java.util.*;
f36821 15 import java.util.concurrent.ExecutorService;
C 16 import java.util.concurrent.Executors;
93b505 17
C 18 public class InitMysqlData {
19
20     /**
21      * 项目启动就执行后就执行该方法
22      */
d14a10 23     //@PostConstruct 2022-06-17屏掉,暂时用不上
93b505 24     public static void initData(String packPath, CommonService commonService){
C 25
26         //项目启动的时候填入
27         if(!StringUtils.isEmpty(packPath)){
28             Set<Class<?>> classes = VariableAesKey.classData(packPath);
29
30             SqlSentence sqlSentence = new SqlSentence();
31             Map<String,Object> values = new HashMap<>();
32
b1097d 33             //解析表数据
C 34             List<FieldData> fieldDatas = entityhandle(classes);
35
f36821 36             int pageSize = 500;
C 37             //创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
38             ExecutorService fixedThreadPool = Executors.newFixedThreadPool(20);
39             try{
40                 for(FieldData fieldData:fieldDatas){
41                     //获取条数
42                     sqlSentence.sqlSentence("SELECT COUNT(0) FROM "+fieldData.getTableName(),values);
43                     int total = commonService.selectCountSql(sqlSentence);
44                     if(total ==0 ){
45                         continue;
b1097d 46                     }
f36821 47                     int pageTotal = total/pageSize+1;
C 48                     for(int i= 0;i<pageTotal;i++){
49                         int finalI = i;
50                         fixedThreadPool.execute(new Runnable() {
51                             @Override
52                             public void run() {
53                                 //更新数据
54                                 updateData(fieldData,commonService, finalI,pageSize);
55                             }
56                         });
93b505 57                     }
C 58                 }
f36821 59             }catch (Exception e){
C 60                 e.printStackTrace();
61             }finally {
62                 fixedThreadPool.shutdown();
93b505 63             }
C 64         }
65     }
66
f36821 67     /**更新数据*/
C 68     public static void updateData(FieldData fieldData,CommonService commonService,int pageNum,int pageSize){
69         SqlSentence sqlSentence = new SqlSentence();
70         Map<String,Object> values = new HashMap<>();
71
72         //查询数据
73         StringBuilder selectField = new StringBuilder();
74         selectField.append(fieldData.getId());
75         for(String fieldName:fieldData.getEncrypFields()){
76             selectField.append(","+fieldName);
77         }
326104 78         pageNum = pageNum*pageSize;
Z 79
f36821 80         sqlSentence.sqlSentence("SELECT "+selectField.toString()+" FROM "+fieldData.getTableName()+" LIMIT "+pageNum+","+pageSize,values);
C 81         List<Map<String,Object>> list = commonService.selectListMap(CommonMapper.class,sqlSentence);
82
e0e1d7 83         boolean isUpdate = false;
f36821 84         for (Map<String,Object> map:list){
e0e1d7 85             isUpdate = false;
f36821 86             StringBuilder setField = new StringBuilder();
C 87             for (Map.Entry<String, Object> entry : map.entrySet()) {
88                 String mapKey = entry.getKey();
89                 String mapValue = (String) entry.getValue();
90                 if(StringUtils.isEmpty(mapValue)){
91                     continue;
92                 }
93                 if(mapValue.length()%32==0 && MysqlHexAesTool.isHexStrValid(mapValue)){
94                     continue;
95                 }
96                 if(fieldData.getId().equals(mapKey)){
97                     continue;
98                 }
99                 if(setField.length()>0){
100                     setField.append(",");
101                 }
102                 setField.append(mapKey+" = #{m."+mapKey+"}");
e0e1d7 103                 isUpdate = true;
f36821 104             }
C 105
e0e1d7 106             if(isUpdate){
C 107                 values = map;
108                 sqlSentence.sqlSentence("UPDATE "+fieldData.getTableName()+" SET "+setField.toString()+" WHERE "+fieldData.getId()+" = #{m."+fieldData.getId()+"}",values);
a48817 109
e0e1d7 110                 if(commonService.updateSentence(sqlSentence)!=1){
C 111                     throw new ServiceException("更新超过1条,更新失败!");
112                 }
f36821 113             }
C 114         }
115
116     }
117
b1097d 118     /**获取到表的数据*/
C 119     public static List<FieldData> entityhandle(Set<Class<?>> classes){
120
121         List<FieldData> fildDatas = new ArrayList<>();
122         //存储单表字段信息
123         FieldData fildData;
124         //存储需要加密的字段
125         Set<String> encrypFields;
126
127         String fildName;
128
129         for(Class<?> cl:classes){
130             fildData = new FieldData();
131             encrypFields = new HashSet<>();
132
133             //表名称
134             if(!cl.isAnnotationPresent(Table.class)){
135                 continue;
136             }
137             Table table = cl.getAnnotation(Table.class);
138             fildData.setTableName(table.name());
139
140             // 取得本类的全部属性
141             Field[] fields = cl.getDeclaredFields();
142             fields = VariableAesKey.getPatentFields(fields,cl);
143             for (Field field:fields) {
144
145                 fildName = null;
146                 if(field.isAnnotationPresent(Column.class)){
147                     Column column = field.getAnnotation(Column.class);
148                     fildName = column.name();
149                     if(StringUtils.isEmpty(fildName)){
150                         fildName = field.getName();
151                     }
152                     if(column.isKey()){
153                         fildData.setId(fildName);
154                     }
155                 }else{
156                     fildName = field.getName();
157                 }
158
159                 // 判断方法中是否有指定注解类型的注解
160                 if (!field.isAnnotationPresent(MysqlHexAes.class)) {
161                     continue;
162                 }
163                 // 根据注解类型返回方法的指定类型注解
164                 MysqlHexAes mysqlHexAes = field.getAnnotation(MysqlHexAes.class);
165                 //判断版本号是不是一样的
166                 if(!StringUtils.isEmpty(VariableAesKey.INIT_VERSION)){
167                     if(!VariableAesKey.INIT_VERSION.equals(mysqlHexAes.initVersion())){
168                         continue;
169                     }
170                 }else{
171                     if(!StringUtils.isEmpty(mysqlHexAes.initVersion())){
172                         continue;
173                     }
174                 }
175
176                 String aesKey = mysqlHexAes.aesKey();
177                 if(StringUtils.isEmpty(aesKey)){
178                     aesKey = VariableAesKey.AES_KEY;
179                     if(StringUtils.isEmpty(aesKey)){
180                         throw new RuntimeException("mysql的AES秘钥不能为空:"+field.getName());
181                     }
182                 }
183
184                 encrypFields.add(fildName);
185             }
186             //是否有需要加密得字段
187             if(encrypFields.size()<=0){
188                 continue;
189             }
190             fildData.setEncrypFields(encrypFields);
191             fildDatas.add(fildData);
192         }
193         return fildDatas;
194     }
195
93b505 196
C 197 }