DbUtil.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. package com.kym;
  2. import com.kym.jdbc.annotations.DBF;
  3. import com.kym.jdbc.annotations.Entity;
  4. import com.kym.jdbc.annotations.Many;
  5. import com.kym.jdbc.annotations.One;
  6. import com.kym.jdbc.annotations.QE;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import java.lang.reflect.Array;
  10. import java.lang.reflect.Field;
  11. import java.lang.reflect.Modifier;
  12. import java.lang.reflect.Type;
  13. import java.math.BigDecimal;
  14. import java.sql.PreparedStatement;
  15. import java.sql.SQLException;
  16. import java.sql.Timestamp;
  17. import java.util.Arrays;
  18. import java.util.Collection;
  19. import java.util.Date;
  20. import java.util.HashSet;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Set;
  24. /**
  25. * 描述:基础工具类 refelct、empty check
  26. * create at 2020/5/7 23:01
  27. *
  28. * @author yaop
  29. */
  30. public class DbUtil {
  31. private static final Logger logger = LoggerFactory.getLogger(DbUtil.class);
  32. private DbUtil() {
  33. }
  34. public static void asserts(boolean express, String errorMsg) {
  35. if (!express) {
  36. throw new RuntimeException(errorMsg);
  37. }
  38. }
  39. public static int null2Int(Object val) {
  40. if (null == val) {
  41. return 0;
  42. }
  43. try {
  44. return Integer.parseInt(val.toString());
  45. } catch (Exception e) {
  46. // do nothings
  47. }
  48. return 0;
  49. }
  50. public static boolean isGenericType(Type type) {
  51. Class<?> t = (Class) type;
  52. return t.isAssignableFrom(String.class)
  53. ||t.isAssignableFrom(byte.class)
  54. ||t.isAssignableFrom(Byte.class)
  55. ||t.isAssignableFrom(boolean.class)
  56. ||t.isAssignableFrom(Boolean.class)
  57. ||t.isAssignableFrom(int.class)
  58. ||t.isAssignableFrom(Integer.class)
  59. ||t.isAssignableFrom(short.class)
  60. ||t.isAssignableFrom(Short.class)
  61. ||t.isAssignableFrom(long.class)
  62. ||t.isAssignableFrom(Long.class)
  63. ||t.isAssignableFrom(float.class)
  64. ||t.isAssignableFrom(Float.class)
  65. ||t.isAssignableFrom(double.class)
  66. ||t.isAssignableFrom(Double.class)
  67. ||t.isAssignableFrom(char.class)
  68. ||t.isAssignableFrom(Character.class);
  69. // return type == String.class || type == Integer.TYPE || type == Long.TYPE || type == Short.TYPE || type == Byte.TYPE
  70. // || type == Boolean.TYPE || type == Character.TYPE || type == Float.TYPE || type == Double.TYPE;
  71. }
  72. public static boolean isGenericType(Object obj) {
  73. if (obj instanceof Integer) {
  74. return true;
  75. } else if (obj instanceof Short) {
  76. return true;
  77. } else if (obj instanceof Float) {
  78. return true;
  79. } else if (obj instanceof Double) {
  80. return true;
  81. } else if (obj instanceof Byte) {
  82. return true;
  83. } else if (obj instanceof Boolean) {
  84. return true;
  85. } else if (obj instanceof Long) {
  86. return true;
  87. } else if (obj instanceof String) {
  88. return true;
  89. } else {
  90. return obj instanceof Character;
  91. }
  92. }
  93. /**
  94. * 数据库持久化的字段
  95. */
  96. public static boolean isUsageField(Field f) {
  97. if (f.isAnnotationPresent(DBF.class)) {
  98. return true;
  99. }
  100. if (f.isAnnotationPresent(One.class) && !f.getAnnotation(One.class).noQuery()) {
  101. return true;
  102. }
  103. return f.isAnnotationPresent(Many.class) && !f.getAnnotation(Many.class).noQuery();
  104. }
  105. public static boolean isStaticFinalField(Field f) {
  106. int modifiers = f.getModifiers();
  107. return Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers);
  108. }
  109. public static String firstToLowerCase(String str) {
  110. return str.substring(0, 1).toLowerCase() + str.substring(1);
  111. }
  112. public static String getColumnName(String field) {
  113. StringBuilder sbr = new StringBuilder();
  114. char[] chars = field.toCharArray();
  115. for (char ch : chars) {
  116. if (Character.isUpperCase(ch)) {
  117. sbr.append("_").append(Character.toLowerCase(ch));
  118. } else {
  119. sbr.append(ch);
  120. }
  121. }
  122. return sbr.toString();
  123. }
  124. public static Object getFieldValue(Object o, Field field) {
  125. field.setAccessible(true);
  126. Object val = null;
  127. try {
  128. val = field.get(o);
  129. } catch (IllegalAccessException e) {
  130. logger.error("SQLHelper ERR# Object getFieldValue,fileName:{}", field.getName());
  131. }
  132. field.setAccessible(false);
  133. return val;
  134. }
  135. public static Object getFieldValue(Object bean, String fieldName) {
  136. Object defValu = "";
  137. try {
  138. fieldName = getCamelName(fieldName);
  139. Field field = null;
  140. try {
  141. field = bean.getClass().getDeclaredField(fieldName);
  142. } catch (Exception e) {
  143. try {
  144. field = bean.getClass().getField(fieldName);
  145. } catch (Exception e1) {
  146. try {
  147. field = bean.getClass().getSuperclass().getDeclaredField(fieldName);
  148. } catch (Exception e2) {
  149. field = bean.getClass().getSuperclass().getField(fieldName);
  150. }
  151. }
  152. }
  153. field.setAccessible(true);
  154. defValu = field.get(bean);
  155. if (null == defValu) {
  156. Class<?> type = field.getType();
  157. if (type == String.class) {
  158. defValu = "";
  159. } else if (type == int.class || type == Integer.class) {
  160. defValu = 0;
  161. } else if (type == double.class || type == Double.class) {
  162. defValu = 0d;
  163. } else if (type == long.class || type == Long.class) {
  164. defValu = 0L;
  165. } else if (type == float.class || type == Float.class) {
  166. defValu = 0F;
  167. } else if (type == short.class || type == Short.class) {
  168. defValu = 0;
  169. } else if (type == byte.class || type == Byte.class) {
  170. defValu = 0;
  171. } else if (type == boolean.class || type == Boolean.class) {
  172. defValu = 0;
  173. } else if (type == char.class || type == Character.class) {
  174. defValu = '0';
  175. } else if (field.getType().isArray()) {
  176. defValu = new Object[]{};
  177. }
  178. }
  179. field.setAccessible(false);
  180. } catch (Exception e) {
  181. logger.warn("SQLHandler ERR# getFieldValue ,field:{}, bean:{} ,msg:{}", fieldName, bean.getClass().getSimpleName(), e.getMessage());
  182. }
  183. return defValu;
  184. }
  185. public static String getCamelName(String fieldName) {
  186. StringBuilder sbr = new StringBuilder();
  187. char[] chars = fieldName.toCharArray();
  188. boolean preUpper = false;
  189. for (char ch : chars) {
  190. if ('_' == ch) {
  191. preUpper = true;
  192. } else {
  193. if (preUpper) {
  194. sbr.append(Character.toUpperCase(ch));
  195. preUpper = false;
  196. } else {
  197. sbr.append(ch);
  198. }
  199. }
  200. }
  201. return sbr.toString();
  202. }
  203. public static void setFieldValue(Object o, Field field, Object val) {
  204. try {
  205. field.setAccessible(true);
  206. field.set(o, val);
  207. field.setAccessible(false);
  208. } catch (IllegalAccessException e) {
  209. logger.error("SQLHelper ERR# Object setFieldValue ,fileName:{}", field.getName());
  210. }
  211. }
  212. /**
  213. * 判断集合是否为空
  214. */
  215. public static boolean isEmptyOrNull(Collection<?> collection) {
  216. return null == collection || collection.isEmpty();
  217. }
  218. /**
  219. * 判断数组是否为空
  220. */
  221. public static boolean isEmptyOrNull(Object[] array) {
  222. return null == array || array.length == 0 || null == array[0];
  223. }
  224. /**
  225. * 判断字符串是否为空
  226. */
  227. public static boolean isEmptyOrNull(String value) {
  228. return null == value || value.isEmpty();
  229. }
  230. public static boolean isEmptyOrNull(Object value) {
  231. if (null == value) {
  232. return true;
  233. }
  234. if (value.getClass().isArray()) {
  235. return Array.getLength(value) == 0;
  236. } else if (value instanceof Collection) {
  237. return ((Collection<?>) value).isEmpty();
  238. } else if (value instanceof Map) {
  239. return ((Map<?, ?>) value).isEmpty();
  240. } else {
  241. return isEmptyOrNull(value.toString());
  242. }
  243. }
  244. public final static String regex = "(create\\s+(database|table|index)|truncate|drop\\s+(table|index|database)|alter\\s+(table|database)|update[\\s\\S]*set|insert[\\s\\S]*into|delete\\s+from|net user|xp_cmdshell|#)+\\s+";
  245. /*
  246. public final static String regex = "'|and|exec|execute|insert|select|delete|update|count|drop|\\*|%|chr|mid|master|truncate|" +
  247. "char|declare|sitename|net user|xp_cmdshell|;|or|-|\\+|,|like'|and|exec|execute|insert|create|drop|" +
  248. "table|from|grant|use|group_concat|column_name|" +
  249. "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|\\*|" +
  250. "chr|mid|master|truncate|char|declare|or|;|-|--|\\+|,|like|//|/|%|#";
  251. */
  252. /**
  253. * 把SQL关键字追加$字符串
  254. */
  255. public static String injectDefend(String param) {
  256. if (param == null) {
  257. return null;
  258. }
  259. // (?i)不区分大小写替换
  260. return param.replaceAll("(?i)" + regex, "$0.");
  261. }
  262. /**
  263. * 返回经过防注入处理的字符串
  264. */
  265. public static String fitlerSql(String sql) {
  266. return injectDefend(sql);
  267. }
  268. /**
  269. * 设置参数
  270. *
  271. * @param ps
  272. * @param parameters
  273. */
  274. public static void setParameter(PreparedStatement ps, Object... parameters) throws SQLException {
  275. if (parameters == null || parameters.length == 0) {
  276. return;
  277. }
  278. int i = 1;
  279. for (Object o : parameters) {
  280. if (o == null) {
  281. ps.setString(i++, null);
  282. continue;
  283. }
  284. if (o instanceof String) {
  285. ps.setString(i++, ((String) o));
  286. continue;
  287. }
  288. if (o instanceof Date date) {
  289. ps.setTimestamp(i++, new Timestamp(date.getTime()));
  290. continue;
  291. }
  292. // Integer
  293. if (o instanceof Integer) {
  294. ps.setInt(i++, ((Integer) o));
  295. continue;
  296. }
  297. if (o instanceof Double) {
  298. ps.setDouble(i++, ((Double) o));
  299. continue;
  300. }
  301. if (o instanceof Float) {
  302. ps.setFloat(i++, ((Float) o));
  303. continue;
  304. }
  305. if (o instanceof BigDecimal) {
  306. ps.setBigDecimal(i++, ((BigDecimal) o));
  307. continue;
  308. }
  309. if (o instanceof Long) {
  310. ps.setLong(i++, ((Long) o));
  311. continue;
  312. }
  313. if (o instanceof Short) {
  314. ps.setShort(i++, ((Short) o));
  315. continue;
  316. }
  317. if (o instanceof Byte) {
  318. ps.setByte(i++, ((Byte) o));
  319. continue;
  320. }
  321. if (o instanceof byte[]) {
  322. ps.setBytes(i++, ((byte[]) o));
  323. continue;
  324. }
  325. if (o instanceof Boolean) {
  326. ps.setBoolean(i++, ((Boolean) o));
  327. continue;
  328. }
  329. if (o.getClass().isArray()) {
  330. ps.setString(i++, JacksonUtil.toJSONString(o));
  331. continue;
  332. }
  333. if (List.class.isAssignableFrom(o.getClass())) {
  334. ps.setString(i++, JacksonUtil.toJSONString(o));
  335. continue;
  336. }
  337. if (Set.class.isAssignableFrom(o.getClass())) {
  338. ps.setString(i++, JacksonUtil.toJSONString(o));
  339. continue;
  340. }
  341. if (Map.class.isAssignableFrom(o.getClass())) {
  342. ps.setString(i++, JacksonUtil.toJSONString(o));
  343. continue;
  344. }
  345. if (isGenericType(o.getClass())) {
  346. ps.setString(i++, JacksonUtil.toJSONString(o));
  347. continue;
  348. }
  349. logger.info("SetParameter PreparedStatement SQL type:{},value:{}", o.getClass().getName(), JacksonUtil.toJSONString(o));
  350. // throw new IllegalArgumentException("unsupported type:" + o.getClass());
  351. ps.setString(i++,JacksonUtil.toJSONString(o));
  352. }
  353. }
  354. private static void recursiveFields(Class<?> clz, Set<Field> fieldSet) {
  355. if(null==clz){
  356. return;
  357. }
  358. Field[] fields = clz.getDeclaredFields();
  359. if (!isEmptyOrNull(fields)) {
  360. for (Field f : fields) {
  361. if (isUsageField(f)) {
  362. fieldSet.add(f);
  363. }
  364. }
  365. }
  366. Entity annotation = clz.getDeclaredAnnotation(Entity.class);
  367. if (null == annotation) {
  368. recursiveFields(clz.getSuperclass(), fieldSet);
  369. }
  370. }
  371. public static Field getField(Object bean, String fieldName) throws NoSuchFieldException {
  372. Field field = null;
  373. int loop = 0;
  374. Class<?> clz = bean.getClass();
  375. while (loop < 10) {
  376. try {
  377. loop++;
  378. return clz.getDeclaredField(fieldName);
  379. } catch (Exception e) {
  380. clz = clz.getSuperclass();
  381. }
  382. if(null==clz){
  383. throw new NoSuchFieldException(fieldName);
  384. }
  385. }
  386. throw new NoSuchFieldException(fieldName);
  387. }
  388. public static Set<Field> getEntityFields(Class<?> clz) {
  389. Set<Field> fields = new HashSet<>();
  390. recursiveFields(clz, fields);
  391. return fields;
  392. }
  393. public static Set<Field> getQueryFields(Class<?> clz) {
  394. Set<Field> fields = new HashSet<>();
  395. if (clz.getName().equals("BasicQuery")) {
  396. return new HashSet<>(Arrays.asList(clz.getFields()));
  397. }
  398. QE annotation = clz.getDeclaredAnnotation(QE.class);
  399. if (null != annotation) {
  400. Field[] fields1 = clz.getFields();
  401. if (!isEmptyOrNull(fields1)) {
  402. for (Field f : fields1) {
  403. if (!isStaticFinalField(f)) {
  404. fields.add(f);
  405. }
  406. }
  407. }
  408. Field[] fields2 = clz.getDeclaredFields();
  409. if (!isEmptyOrNull(fields2)) {
  410. for (Field f : fields2) {
  411. if (!isStaticFinalField(f)) {
  412. fields.add(f);
  413. }
  414. }
  415. }
  416. }
  417. return fields;
  418. }
  419. public static void main(String[] args) {
  420. System.out.println(fitlerSql("droptable t_state"));
  421. System.out.println(fitlerSql("update t_state set "));
  422. System.out.println(fitlerSql("drop table t_state"));
  423. System.out.println(fitlerSql("DROP table t_state"));
  424. System.out.println(fitlerSql("Drop Table t_state"));
  425. System.out.println(fitlerSql("alter table t_state"));
  426. System.out.println(fitlerSql("delete from table t_state"));
  427. System.out.println(fitlerSql(".lete from -- table t_state"));
  428. System.out.println(fitlerSql("truncate table t_state -- '' delete from t"));
  429. }
  430. }