Java110MybatisInterceptor.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. package com.java110.db;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.java110.core.client.RestTemplate;
  5. import com.java110.core.context.Environment;
  6. import com.java110.core.factory.Java110TransactionalFactory;
  7. import com.java110.db.dao.IQueryServiceDAO;
  8. import com.java110.dto.order.OrderItemDto;
  9. import com.java110.utils.constant.ServiceConstant;
  10. import com.java110.utils.factory.ApplicationContextFactory;
  11. import com.java110.utils.util.DateUtil;
  12. import com.java110.utils.util.StringUtil;
  13. import org.apache.ibatis.executor.Executor;
  14. import org.apache.ibatis.mapping.*;
  15. import org.apache.ibatis.plugin.*;
  16. import org.apache.ibatis.reflection.MetaObject;
  17. import org.apache.ibatis.session.Configuration;
  18. import org.apache.ibatis.type.TypeHandlerRegistry;
  19. import org.slf4j.Logger;
  20. import com.java110.core.log.LoggerFactory;
  21. import org.springframework.http.*;
  22. import java.sql.Timestamp;
  23. import java.text.DateFormat;
  24. import java.util.*;
  25. @Intercepts({
  26. @Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
  27. Object.class})
  28. })
  29. public class Java110MybatisInterceptor implements Interceptor {
  30. private static Logger logger = LoggerFactory.getLogger(Java110MybatisInterceptor.class);
  31. IQueryServiceDAO queryServiceDAOImpl;
  32. RestTemplate restTemplate;
  33. @Override
  34. public Object intercept(Invocation invocation) throws Throwable {
  35. if (StringUtil.isEmpty(Java110TransactionalFactory.getOId())) { //未开启事务
  36. return invocation.proceed();
  37. }
  38. MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
  39. SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
  40. Object parameter = null;
  41. if (invocation.getArgs().length > 1) {
  42. parameter = invocation.getArgs()[1];
  43. }
  44. BoundSql boundSql = mappedStatement.getBoundSql(parameter);
  45. Configuration configuration = mappedStatement.getConfiguration();
  46. Map<String, Object> sqlValue = new HashMap<>();
  47. //获取sql语句
  48. String sql = showSql(configuration, boundSql, sqlValue, sqlCommandType);
  49. if(Environment.isStartBootWay()){
  50. restTemplate = ApplicationContextFactory.getBean("outRestTemplate", RestTemplate.class);
  51. }else {
  52. restTemplate = ApplicationContextFactory.getBean("restTemplate", RestTemplate.class);
  53. }
  54. switch (sqlCommandType) {
  55. case INSERT:
  56. dealInsertSql(mappedStatement, parameter, sql, sqlValue);
  57. break;
  58. case UPDATE:
  59. dealUpdateSql(mappedStatement, parameter, sql, sqlValue);
  60. break;
  61. case DELETE:
  62. dealDeleteSql(mappedStatement, parameter, sql, sqlValue);
  63. break;
  64. }
  65. return invocation.proceed();
  66. }
  67. /**
  68. * 处理删除sql
  69. *
  70. * @param mappedStatement
  71. * @param parameter
  72. */
  73. private void dealDeleteSql(MappedStatement mappedStatement, Object parameter, String sql, Map<String, Object> sqlValue) {
  74. String tmpTable = sql.substring(sql.indexOf("from") + 4, sql.indexOf("where")).trim();
  75. String tmpTableHasT = tmpTable;
  76. if(tmpTable.indexOf(" ") > 0){
  77. tmpTable = tmpTable.substring(0,tmpTable.indexOf(" "));
  78. }
  79. String tmpWhere = sql.substring(sql.indexOf("where"));
  80. //插入操作时之前的 没有数据 所以 preValue 为空对象
  81. JSONArray preValues = new JSONArray();
  82. String execSql = "select * from " + tmpTableHasT + " " + tmpWhere;
  83. queryServiceDAOImpl = ApplicationContextFactory.getBean("queryServiceDAOImpl", IQueryServiceDAO.class);
  84. List<Map<String, Object>> deleteDatas = queryServiceDAOImpl.executeSql(execSql, null);
  85. if (deleteDatas != null && deleteDatas.size() > 0) {
  86. for (Map<String, Object> map : deleteDatas) {
  87. dealReturnMap(map);
  88. preValues.add(map);
  89. }
  90. }
  91. JSONArray afterValues = new JSONArray();
  92. JSONObject logText = new JSONObject();
  93. logText.put("preValue", preValues);
  94. logText.put("afterValue", afterValues);
  95. OrderItemDto orderItemDto = new OrderItemDto();
  96. orderItemDto.setbId("-1");
  97. orderItemDto.setAction("DEL");
  98. orderItemDto.setActionObj(tmpTable.trim());
  99. orderItemDto.setLogText(logText.toJSONString());
  100. orderItemDto.setServiceName(ApplicationContextFactory.getApplicationName());
  101. orderItemDto.setoId(Java110TransactionalFactory.getOId());
  102. String url = ServiceConstant.SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
  103. HttpHeaders httpHeaders = new HttpHeaders();
  104. HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
  105. if(Environment.isStartBootWay()){
  106. url = ServiceConstant.BOOT_SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
  107. }
  108. ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
  109. if (responseEntity.getStatusCode() != HttpStatus.OK) {
  110. throw new IllegalArgumentException("注册事务回滚日志失败" + responseEntity);
  111. }
  112. }
  113. /**
  114. * 处理修改 sql
  115. *
  116. * @param mappedStatement
  117. * @param parameter
  118. */
  119. private void dealUpdateSql(MappedStatement mappedStatement, Object parameter, String sql, Map<String, Object> sqlValue) {
  120. //RestTemplate restTemplate = ApplicationContextFactory.getBean("restTemplate", RestTemplate.class);
  121. String tmpTable = sql.substring(sql.indexOf("update") + 6, sql.indexOf("set")).trim();
  122. String tmpTableHasT = tmpTable;
  123. if(tmpTable.indexOf(" ") > 0){
  124. tmpTable = tmpTable.substring(0,tmpTable.indexOf(" "));
  125. }
  126. String tmpWhere = sql.substring(sql.indexOf("where"));
  127. //插入操作时之前的 没有数据 所以 preValue 为空对象
  128. JSONArray preValues = new JSONArray();
  129. JSONArray afterValues = new JSONArray();
  130. JSONObject afterVaule = null;
  131. String execSql = "select * from " + tmpTableHasT + " " + tmpWhere;
  132. queryServiceDAOImpl = ApplicationContextFactory.getBean("queryServiceDAOImpl", IQueryServiceDAO.class);
  133. List<Map<String, Object>> deleteDatas = queryServiceDAOImpl.executeSql(execSql, null);
  134. if (deleteDatas != null && deleteDatas.size() > 0) {
  135. for (Map<String, Object> map : deleteDatas) {
  136. dealReturnMap(map);
  137. preValues.add(map);
  138. afterVaule = new JSONObject();
  139. afterVaule.putAll(map);
  140. afterVaule.putAll(sqlValue);
  141. afterValues.add(afterVaule);
  142. }
  143. }
  144. JSONObject logText = new JSONObject();
  145. logText.put("preValue", preValues);
  146. logText.put("afterValue", afterValues);
  147. OrderItemDto orderItemDto = new OrderItemDto();
  148. orderItemDto.setbId("-1");
  149. orderItemDto.setAction("MOD");
  150. orderItemDto.setActionObj(tmpTable.trim());
  151. orderItemDto.setLogText(logText.toJSONString());
  152. orderItemDto.setServiceName(ApplicationContextFactory.getApplicationName());
  153. orderItemDto.setoId(Java110TransactionalFactory.getOId());
  154. String url = ServiceConstant.SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
  155. HttpHeaders httpHeaders = new HttpHeaders();
  156. HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
  157. ResponseEntity<String> responseEntity = null;
  158. if(Environment.isStartBootWay()){
  159. url = ServiceConstant.BOOT_SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
  160. }
  161. responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
  162. if (responseEntity.getStatusCode() != HttpStatus.OK) {
  163. throw new IllegalArgumentException("注册事务回滚日志失败" + responseEntity);
  164. }
  165. }
  166. private void dealReturnMap(Map<String, Object> map) {
  167. for (String key : map.keySet()) {
  168. Object value = map.get(key);
  169. if (value instanceof String) {
  170. map.put(key, "'" + map.get(key) + "'");
  171. } else if (value instanceof Date) {
  172. String tmpValue = DateUtil.getFormatTimeString((Date) value, DateUtil.DATE_FORMATE_STRING_A);
  173. map.put(key, "'" + tmpValue + "'");
  174. } else if (value instanceof Timestamp) {
  175. Date date = new Date(((Timestamp) value).getTime());
  176. String tmpValue = DateUtil.getFormatTimeString(date, DateUtil.DATE_FORMATE_STRING_A);
  177. map.put(key, "'" + tmpValue + "'");
  178. } else if (value instanceof Double) {
  179. map.put(key, "'" + map.get(key) + "'");
  180. } else {
  181. if (value != null) {
  182. map.put(key, "'" + value.toString() + "'");
  183. } else {
  184. map.put(key, "''");
  185. }
  186. }
  187. }
  188. }
  189. /**
  190. * 处理insert 语句
  191. *
  192. * @param mappedStatement
  193. * @param parameter
  194. */
  195. private void dealInsertSql(MappedStatement mappedStatement, Object parameter, String sql, Map<String, Object> sqlValue) {
  196. // RestTemplate restTemplate = ApplicationContextFactory.getBean("restTemplate", RestTemplate.class);
  197. //插入操作时之前的 没有数据 所以 preValue 为空对象
  198. JSONArray preValues = new JSONArray();
  199. JSONArray afterValues = new JSONArray();
  200. String tmpTable = sql.substring(sql.toLowerCase().indexOf("into") + 4, sql.indexOf("(")).trim();
  201. if(tmpTable.indexOf(" ") > 0){
  202. tmpTable = tmpTable.substring(0,tmpTable.indexOf(" "));
  203. }
  204. afterValues.add(sqlValue);
  205. JSONObject logText = new JSONObject();
  206. logText.put("preValue", preValues);
  207. logText.put("afterValue", afterValues);
  208. OrderItemDto orderItemDto = new OrderItemDto();
  209. orderItemDto.setbId("-1");
  210. orderItemDto.setAction("ADD");
  211. orderItemDto.setActionObj(tmpTable.trim());
  212. orderItemDto.setLogText(logText.toJSONString());
  213. orderItemDto.setServiceName(ApplicationContextFactory.getApplicationName());
  214. orderItemDto.setoId(Java110TransactionalFactory.getOId());
  215. String url = ServiceConstant.SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
  216. HttpHeaders httpHeaders = new HttpHeaders();
  217. HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
  218. if(Environment.isStartBootWay()){
  219. url = ServiceConstant.BOOT_SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
  220. }
  221. ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
  222. if (responseEntity.getStatusCode() != HttpStatus.OK) {
  223. throw new IllegalArgumentException("注册事务回滚日志失败" + responseEntity);
  224. }
  225. }
  226. @Override
  227. public Object plugin(Object target) {
  228. return Plugin.wrap(target, this);
  229. }
  230. @Override
  231. public void setProperties(Properties properties) {
  232. }
  233. public String showSql(Configuration configuration, BoundSql boundSql, Map<String, Object> sqlValue, SqlCommandType sqlCommandType) {
  234. Object parameterObject = boundSql.getParameterObject();
  235. List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
  236. String sql = boundSql.getSql().replaceAll("[\\s]+", " ").toLowerCase();
  237. String orgSql = sql;// 原始sql
  238. List<String> values = new ArrayList<>();
  239. if (parameterMappings.size() > 0 && parameterObject != null) {
  240. TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
  241. if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
  242. sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));
  243. values.add(getParameterValue(parameterObject));
  244. } else {
  245. MetaObject metaObject = configuration.newMetaObject(parameterObject);
  246. for (ParameterMapping parameterMapping : parameterMappings) {
  247. String propertyName = parameterMapping.getProperty();
  248. if (metaObject.hasGetter(propertyName)) {
  249. Object obj = metaObject.getValue(propertyName);
  250. String value = getParameterValue(obj);
  251. if(value.contains("${")){
  252. value = value.replace("${","\\${");
  253. }
  254. sql = sql.replaceFirst("\\?", value);
  255. values.add(getParameterValue(obj));
  256. } else if (boundSql.hasAdditionalParameter(propertyName)) {
  257. Object obj = boundSql.getAdditionalParameter(propertyName);
  258. sql = sql.replaceFirst("\\?", getParameterValue(obj));
  259. values.add(getParameterValue(obj));
  260. }
  261. }
  262. }
  263. }
  264. if (sqlCommandType == SqlCommandType.INSERT) {
  265. String tmpKey = orgSql.substring(orgSql.indexOf("(") + 1, orgSql.indexOf(")"));
  266. String[] tmpKeys = tmpKey.split(",");
  267. // if (values.size() < tmpKeys.length) {
  268. // throw new IllegalArgumentException("sql 错误 key 和value 个数不等" + sql);
  269. // }
  270. for (int keyIndex = 0; keyIndex < tmpKeys.length; keyIndex++) {
  271. String key = tmpKeys[keyIndex].trim();
  272. String value = "";
  273. if (values.size() - 1 < keyIndex) {
  274. continue;
  275. }
  276. value = values.get(keyIndex);
  277. if ("''".equals(value)) {
  278. continue;
  279. }
  280. sqlValue.put(key, value);
  281. }
  282. } else if (sqlCommandType == SqlCommandType.UPDATE) {
  283. String tmpKey = orgSql.substring(sql.indexOf("set") + 3, orgSql.indexOf("where"));
  284. String[] tmpKeys = tmpKey.split(",");
  285. // if (values.size() < tmpKeys.length) {
  286. // throw new IllegalArgumentException("sql 错误 key 和value 个数不等" + sql);
  287. // }
  288. for (int keyIndex = 0; keyIndex < tmpKeys.length; keyIndex++) {
  289. String tmpSetKey = tmpKeys[keyIndex];
  290. String[] keyValues = tmpSetKey.split("=");
  291. String key = "";
  292. if (keyValues.length != 2) {
  293. throw new IllegalArgumentException("update 语句可能有问题,没有 set 中出错 " + sql);
  294. }
  295. if (keyValues[0].contains(".")) {
  296. key = keyValues[0].substring(keyValues[0].indexOf(".") + 1).trim();
  297. } else {
  298. key = keyValues[0].trim();
  299. }
  300. String value = "";
  301. if (values.size() - 1 < keyIndex) {
  302. continue;
  303. }
  304. value = values.get(keyIndex);
  305. if ("''".equals(value)) {
  306. continue;
  307. }
  308. sqlValue.put(key, value);
  309. }
  310. } else if (sqlCommandType == SqlCommandType.DELETE) {
  311. }
  312. return sql;
  313. }
  314. private String getParameterValue(Object obj) {
  315. String value = null;
  316. if (obj instanceof String) {
  317. value = "'" + obj.toString() + "'";
  318. } else if (obj instanceof Date) {
  319. DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
  320. value = "'" + formatter.format(obj) + "'";
  321. // System.out.println(value);
  322. } else {
  323. if (obj != null) {
  324. value = obj.toString();
  325. } else {
  326. value = "''";
  327. }
  328. }
  329. return value;
  330. }
  331. }