QueryWrapperUtil.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. package mybatisex.core.mapper;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Modifier;
  5. import java.util.ArrayList;
  6. import java.util.Arrays;
  7. import java.util.List;
  8. import org.apache.ibatis.ognl.OgnlRuntime;
  9. import org.springframework.core.annotation.AnnotationUtils;
  10. import org.springframework.util.ObjectUtils;
  11. import com.baomidou.mybatisplus.annotation.TableField;
  12. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  13. import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
  14. import com.baomidou.mybatisplus.core.toolkit.StringUtils;
  15. /**
  16. * @Description 拼接查询条件工具类
  17. */
  18. public class QueryWrapperUtil {
  19. /**
  20. * 得到父类的对象
  21. *
  22. * @param <T> 查询的泛型
  23. * @param clazz
  24. * @return
  25. */
  26. public static <T> List<Field> reflectForField(Class<T> clazz) {
  27. Class<?> tmpClazz = clazz;
  28. List<Field> fieldList = new ArrayList<>();
  29. while (tmpClazz != null) {
  30. // 处理去掉静态属性
  31. for (Field f : tmpClazz.getDeclaredFields()) {
  32. if (!Modifier.isStatic(f.getModifiers())) {
  33. fieldList.add(f);
  34. }
  35. }
  36. tmpClazz = tmpClazz.getSuperclass();
  37. }
  38. return fieldList;
  39. }
  40. /**
  41. * 拼接查询条件
  42. *
  43. * @param obj 数据实体
  44. * @return void 返回参数说明
  45. * @exception/throws
  46. */
  47. public static <T> QueryWrapper<T> convertQuery(Object obj, QueryMap... map) {
  48. QueryMap param = new QueryMap();
  49. if (ArrayUtils.isNotEmpty(map)) {
  50. param = map[0];
  51. }
  52. QueryWrapper<T> queryWrapper = new QueryWrapper<>();
  53. Class<?> clazz = obj.getClass();
  54. try {
  55. // TODO 这里应该通过共有方法来进行反射
  56. for (Field field : reflectForField(clazz)) {
  57. // 抑制Java对修饰符的检查
  58. // field.setAccessible(true);
  59. // 获取属性值
  60. // Object fieldValue = field.get(obj);
  61. // String fieldValue = getFieldValue(obj ,field.getName()).toString();
  62. TableField tableField = AnnotationUtils.getAnnotation(field, TableField.class);
  63. // 字段没有TableField这个注解和有这个主机上false的
  64. // 这里有可能没有注解,是使用了骆驼ming'm
  65. if (tableField != null && !tableField.exist()) {
  66. continue;
  67. }
  68. // String methodName = "set" + filedName.substring(0, 1).toUpperCase() +
  69. // filedName.substring(1);
  70. // 获取属性名
  71. String name = field.getName();
  72. // 声明属性描述对象
  73. // PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, clazz);
  74. // Method method = clazz.getDeclaredMethod(propertyName);
  75. // 获取getter方法
  76. // Method method = propertyDescriptor.getReadMethod();
  77. // String getMethod = getMethod(name);
  78. Method method = getMethod(clazz, name);
  79. if (method == null) {
  80. continue;
  81. }
  82. Object fieldValue = method.invoke(obj);
  83. String fieldName;
  84. if (tableField == null) {
  85. fieldName = StringUtils.camelToUnderline(name);
  86. } else {
  87. fieldName = tableField.value();
  88. }
  89. // 默认是相等
  90. QueryWapper queryWapperAnnotation = AnnotationUtils.getAnnotation(field, QueryWapper.class);
  91. if (ObjectUtils.isEmpty(queryWapperAnnotation)) {
  92. queryWrapper.eq(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  93. } else {
  94. // 获取枚举
  95. QueryKeyword[] queryWapperEnums = queryWapperAnnotation.value();
  96. for (QueryKeyword queryWapperEnum : queryWapperEnums) {
  97. // 拼接查询条件
  98. switch (queryWapperEnum) {
  99. case NE:
  100. queryWrapper.ne(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  101. break;
  102. // 这里需要,修改为集合
  103. case IN:
  104. if (fieldValue != null)
  105. if (fieldValue.toString().contains(",")) {
  106. List<String> result = Arrays.asList(fieldValue.toString().split(","));
  107. queryWrapper.in(!ObjectUtils.isEmpty(fieldValue), fieldName, result);
  108. } else {
  109. queryWrapper.in(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  110. }
  111. break;
  112. case GT:
  113. queryWrapper.gt(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  114. break;
  115. case EQ:
  116. queryWrapper.eq(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  117. break;
  118. case GE:
  119. queryWrapper.ge(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  120. break;
  121. case LT:
  122. queryWrapper.lt(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  123. break;
  124. case LE:
  125. queryWrapper.le(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  126. break;
  127. case LIKE:
  128. queryWrapper.like(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  129. break;
  130. case NOT_LIKE:
  131. queryWrapper.notLike(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  132. break;
  133. case LIKE_LEFT:
  134. queryWrapper.likeLeft(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  135. break;
  136. case LIKE_RIGHT:
  137. queryWrapper.likeRight(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue);
  138. break;
  139. case DESC:
  140. queryWrapper.orderByDesc(fieldName);
  141. break;
  142. case AND:
  143. // 通过attribute指定多个字段做AND连接(格式:{"field1", "field2"})
  144. String[] andFields = queryWapperAnnotation.attribute();
  145. if (ArrayUtils.isNotEmpty(andFields)) {
  146. for (String andField : andFields) {
  147. Method andMethod = getMethod(clazz, andField);
  148. if (andMethod == null) {
  149. continue;
  150. }
  151. Object andValue = andMethod.invoke(obj);
  152. if (!ObjectUtils.isEmpty(andValue)) {
  153. String dbAndField = getDbFieldName(clazz, andField);
  154. queryWrapper.eq(true, dbAndField, andValue);
  155. }
  156. }
  157. }
  158. break;
  159. case BETWEEN:
  160. // attribute指定开始/结束字段(格式:{"startField", "endField"})
  161. String[] betweenFields = queryWapperAnnotation.attribute();
  162. if (betweenFields.length == 2) {
  163. Method startMethod = getMethod(clazz, betweenFields[0]);
  164. Object startVal = startMethod != null ? startMethod.invoke(obj) : null;
  165. Method endMethod = getMethod(clazz, betweenFields[1]);
  166. Object endVal = endMethod != null ? endMethod.invoke(obj) : null;
  167. boolean betweenCondition = !ObjectUtils.isEmpty(startVal)
  168. && !ObjectUtils.isEmpty(endVal);
  169. queryWrapper.between(betweenCondition, fieldName, startVal, endVal);
  170. }
  171. break;
  172. case EXISTS:
  173. // attribute[0]传入EXISTS子查询SQL
  174. String[] existsSql = queryWapperAnnotation.attribute();
  175. if (ArrayUtils.isNotEmpty(existsSql) && !StringUtils.isBlank(existsSql[0])) {
  176. queryWrapper.exists(existsSql[0]);
  177. }
  178. break;
  179. case GROUP_BY:
  180. // attribute指定分组字段(格式:{"field1", "field2"})
  181. String[] groupFields = queryWapperAnnotation.attribute();
  182. if (ArrayUtils.isNotEmpty(groupFields)) {
  183. for (String groupField : groupFields) {
  184. if (StringUtils.isBlank(groupField)) {
  185. continue;
  186. }
  187. String dbGroupField = getDbFieldName(clazz, groupField);
  188. queryWrapper.groupBy(dbGroupField);
  189. }
  190. }
  191. break;
  192. case HAVING:
  193. // attribute[0]直接写having条件SQL
  194. String[] havingConditions = queryWapperAnnotation.attribute();
  195. if (ArrayUtils.isNotEmpty(havingConditions) && !StringUtils.isBlank(havingConditions[0])) {
  196. queryWrapper.having(havingConditions[0]);
  197. }
  198. break;
  199. case IS_NOT_NULL:
  200. queryWrapper.isNotNull(fieldName);
  201. break;
  202. case IS_NULL:
  203. queryWrapper.isNull(fieldName);
  204. break;
  205. case NOT:
  206. // attribute[0]指定要取反的字段
  207. String[] notFields = queryWapperAnnotation.attribute();
  208. if (ArrayUtils.isNotEmpty(notFields)) {
  209. String notField = notFields[0];
  210. Method notMethod = getMethod(clazz, notField);
  211. if (notMethod != null) {
  212. Object notValue = notMethod.invoke(obj);
  213. if (!ObjectUtils.isEmpty(notValue)) {
  214. String dbNotField = getDbFieldName(clazz, notField);
  215. queryWrapper.not(true, i -> i.eq(dbNotField, notValue));
  216. }
  217. }
  218. }
  219. break;
  220. case NOT_BETWEEN:
  221. String[] notBetweenFields = queryWapperAnnotation.attribute();
  222. if (notBetweenFields.length == 2) {
  223. Method notStartMethod = getMethod(clazz, notBetweenFields[0]);
  224. Object notStartVal = notStartMethod != null ? notStartMethod.invoke(obj) : null;
  225. Method notEndMethod = getMethod(clazz, notBetweenFields[1]);
  226. Object notEndVal = notEndMethod != null ? notEndMethod.invoke(obj) : null;
  227. boolean notBetweenCondition = !ObjectUtils.isEmpty(notStartVal)
  228. && !ObjectUtils.isEmpty(notEndVal);
  229. queryWrapper.notBetween(notBetweenCondition, fieldName, notStartVal, notEndVal);
  230. }
  231. break;
  232. case NOT_EXISTS:
  233. String[] notExistsSql = queryWapperAnnotation.attribute();
  234. if (ArrayUtils.isNotEmpty(notExistsSql) && !StringUtils.isBlank(notExistsSql[0])) {
  235. queryWrapper.notExists(notExistsSql[0]);
  236. }
  237. break;
  238. case NOT_IN:
  239. if (fieldValue != null && fieldValue.toString().contains(",")) {
  240. List<String> notInList = Arrays.asList(fieldValue.toString().split(","));
  241. if (!ObjectUtils.isEmpty(notInList)) {
  242. queryWrapper.notIn(true, fieldName, notInList);
  243. }
  244. }
  245. break;
  246. case OR:
  247. queryWrapper.or();
  248. break;
  249. case ORDER_BY:
  250. // 支持多字段排序(格式:{"field1,asc", "field2,desc"})
  251. String[] orderRules = queryWapperAnnotation.attribute();
  252. if (ArrayUtils.isNotEmpty(orderRules)) {
  253. for (String rule : orderRules) {
  254. if (StringUtils.isBlank(rule)) {
  255. continue;
  256. }
  257. String[] parts = rule.split(",", 2);
  258. String orderField = parts[0].trim();
  259. if (StringUtils.isBlank(orderField)) {
  260. continue;
  261. }
  262. String direction = parts.length > 1 ? parts[1].trim().toUpperCase() : "ASC";
  263. String dbOrderField = getDbFieldName(clazz, orderField);
  264. if ("DESC".equals(direction)) {
  265. queryWrapper.orderByDesc(dbOrderField);
  266. } else {
  267. queryWrapper.orderByAsc(dbOrderField);
  268. }
  269. }
  270. }
  271. break;
  272. case ASC:
  273. queryWrapper.orderByAsc(fieldName);
  274. break;
  275. case RANGE:
  276. // 设置开始的值和结束的值
  277. String[] attribute = queryWapperAnnotation.attribute();
  278. String startRange = attribute[0];
  279. // 声明属性描述对象
  280. // getMethod = getMethod(startRange);
  281. // method = ReflectionUtils.findMethod(clazz, getMethod);
  282. method = getMethod(clazz, startRange);
  283. if (method != null) {
  284. Object val = method.invoke(obj);
  285. if (!ObjectUtils.isEmpty(val)) {
  286. queryWrapper.ge(fieldName, val);
  287. }
  288. }
  289. // 得到开始的属性值,通过反射设置属性值
  290. // Field startRange = clazz.getDeclaredField(attribute[0]);
  291. // startRange.setAccessible(true);
  292. // Object val = startRange.get(obj);
  293. // 结束的属性值,通过反射设置属性值
  294. String endRange = attribute[1];
  295. // getMethod = getMethod(endRange);
  296. // 获取getter方法
  297. // method = ReflectionUtils.findMethod(clazz, getMethod);
  298. method = getMethod(clazz, endRange);
  299. if (method != null) {
  300. Object val = method.invoke(obj);
  301. if (!ObjectUtils.isEmpty(val)) {
  302. queryWrapper.le(fieldName, val);
  303. }
  304. }
  305. // ---属性值查询结束的值----
  306. // 通过传入的参数查询值
  307. // 然后通过参数查询
  308. Object val = param.get(attribute[0]);
  309. if (!ObjectUtils.isEmpty(val)) {
  310. queryWrapper.ge(fieldName, val);
  311. }
  312. // 然后通过参数查询
  313. val = param.get(attribute[1]);
  314. if (!ObjectUtils.isEmpty(val)) {
  315. queryWrapper.le(fieldName, val);
  316. }
  317. break;
  318. default:
  319. break;
  320. }
  321. }
  322. }
  323. }
  324. } catch (Exception e) {
  325. e.printStackTrace();
  326. }
  327. return queryWrapper;
  328. }
  329. /**
  330. * 获取数据库字段名(优先TableField.value,其次驼峰转下划线)
  331. */
  332. private static <T> String getDbFieldName(Class<T> clazz, String fieldName) {
  333. if (StringUtils.isBlank(fieldName)) {
  334. return fieldName;
  335. }
  336. for (Field f : reflectForField(clazz)) {
  337. if (!f.getName().equals(fieldName)) {
  338. continue;
  339. }
  340. TableField attrTableField = AnnotationUtils.getAnnotation(f, TableField.class);
  341. if (attrTableField != null && attrTableField.exist() && !StringUtils.isBlank(attrTableField.value())) {
  342. return attrTableField.value();
  343. }
  344. break;
  345. }
  346. return StringUtils.camelToUnderline(fieldName);
  347. }
  348. // 获取get方法
  349. public static Method getMethod(Class<?> clazz, String filedName) throws Exception {
  350. // String alpha = filedName.substring(0, 1).toUpperCase();
  351. // String methodName = "get" + alpha + filedName.substring(1);
  352. // PropertyDescriptor p = new PropertyDescriptor(filedName, beanClass);
  353. // Method readMethod = p.getReadMethod();
  354. return OgnlRuntime.getReadMethod(clazz, filedName);
  355. }
  356. }