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