BaseController.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. package com.shawn.web.controller.base;
  2. import java.io.Serializable;
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Method;
  6. import java.text.ParseException;
  7. import java.util.ArrayList;
  8. import java.util.Date;
  9. import java.util.List;
  10. import org.springframework.http.HttpStatus;
  11. import org.springframework.http.ResponseEntity;
  12. import org.springframework.web.bind.annotation.DeleteMapping;
  13. import org.springframework.web.bind.annotation.GetMapping;
  14. import org.springframework.web.bind.annotation.PathVariable;
  15. import org.springframework.web.bind.annotation.PostMapping;
  16. import org.springframework.web.bind.annotation.PutMapping;
  17. import org.springframework.web.bind.annotation.RequestBody;
  18. import org.springframework.web.bind.annotation.RequestParam;
  19. import com.fasterxml.jackson.annotation.JsonIgnore;
  20. import com.shawn.constant.PageConstant;
  21. import com.shawn.model.bean.PageBean;
  22. import com.shawn.model.dto.PaginatedResult;
  23. import com.shawn.model.dto.ResultMessage;
  24. import com.shawn.service.base.BaseServiceInterface;
  25. import com.shawn.util.FgObjectUtil;
  26. import com.shawn.util.PageUtil;
  27. import com.shawn.web.exception.MyException;
  28. import com.shawn.web.exception.ResourceNotFoundException;
  29. import lombok.extern.apachecommons.CommonsLog;
  30. import lombok.extern.slf4j.Slf4j;
  31. /*
  32. * 一:@RequestParam 与 @RequestBody
  33. * 1、@RequestParam 用来处理 content-type 为 application/x-www-form-urlencoded 编码的内容
  34. * 2、@RequestBody 用来处理除content-type 为 application/x-www-form-urlencoded 编码的内容
  35. * 如 application/json,application/xml
  36. *
  37. * 二:在不给定注解的情况下,参数默认是怎么绑定的?
  38. * 1、若为简单类型:调用@RequestParam
  39. * 2、若为复杂类型,如对象,调用@ModelAttribute
  40. */
  41. @Slf4j
  42. public abstract class BaseController<ENTITY, ENTITYExample,ENTITYParam, ID extends Serializable> {
  43. protected BaseServiceInterface<ENTITY,ENTITYExample,ENTITYParam, ID> baseService;
  44. public BaseController(BaseServiceInterface<ENTITY,ENTITYExample,ENTITYParam, ID> service){
  45. this.baseService = service;
  46. }
  47. /**
  48. * 自定义获取各model的id
  49. * @param entity
  50. * @return
  51. * @throws InvocationTargetException
  52. * @throws IllegalArgumentException
  53. * @throws IllegalAccessException
  54. * @throws SecurityException
  55. * @throws NoSuchMethodException
  56. */
  57. protected ID getEntityId(ENTITY entity) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
  58. Class entityClass = entity.getClass();
  59. Method m = entityClass.getDeclaredMethod("getPrimaryKey");
  60. m.setAccessible(true);//因为写成private 所以这里必须设置
  61. return (ID)m.invoke(entity);
  62. }
  63. /**
  64. * 自定义设置各model的id
  65. * @param entity
  66. * @return
  67. * @throws InvocationTargetException
  68. * @throws IllegalArgumentException
  69. * @throws IllegalAccessException
  70. * @throws SecurityException
  71. * @throws NoSuchMethodException
  72. */
  73. protected void setEntityId(ENTITY entity,ID id) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
  74. Class entityClass = entity.getClass();
  75. Method m = entityClass.getDeclaredMethod("hasPrimaryKey");
  76. m.setAccessible(true);//因为写成private 所以这里必须设置
  77. boolean flag = (boolean)m.invoke(entity);
  78. if(flag) {
  79. Object property = getEntityId(entity);// 调用getter方法获取属性值
  80. Method m2 = entityClass.getDeclaredMethod("setPrimaryKey",FgObjectUtil.getPropertyType(property));
  81. m2.setAccessible(true);//因为写成private 所以这里必须设置
  82. m2.invoke(entity,id);
  83. }
  84. /*if(id instanceof String) {
  85. Method m = entityClass.getDeclaredMethod("setPrimaryKey",String.class);
  86. m.setAccessible(true);//因为写成private 所以这里必须设置
  87. m.invoke(entity,id);
  88. }else if(id instanceof Long){
  89. Method m = entityClass.getDeclaredMethod("setPrimaryKey",Long.class);
  90. m.setAccessible(true);//因为写成private 所以这里必须设置
  91. m.invoke(entity,id);
  92. }else if(id instanceof Integer) {
  93. Method m = entityClass.getDeclaredMethod("setPrimaryKey",Integer.class);
  94. m.setAccessible(true);//因为写成private 所以这里必须设置
  95. m.invoke(entity,id);
  96. }*/
  97. }
  98. /**
  99. * 自定义new 一个实体对应的ENTITYExample
  100. * @return
  101. */
  102. protected abstract ENTITYExample createNewExample();
  103. /**
  104. * 自定义获取model 表的名称
  105. */
  106. protected String getResourceName() {
  107. return baseService.getResourceName();
  108. }
  109. /**
  110. * 根据id获取一条实体表记录
  111. * @param id
  112. * @return
  113. */
  114. @GetMapping("/{id}")
  115. public ResponseEntity<?> getEntityById(@PathVariable ID id) {
  116. ENTITY entity = baseService.selectEntityById(id);
  117. if(entity==null){
  118. throw new ResourceNotFoundException()
  119. .setResourceName(getResourceName())
  120. .setId(id.toString());
  121. }
  122. return ResponseEntity
  123. .status(HttpStatus.OK)
  124. .body(new ResultMessage()
  125. .setCode(true)
  126. .setData(entity)
  127. .setMessage("SUCCESS"));
  128. }
  129. /**
  130. * 新增实体表数据
  131. * @param entity
  132. * @return
  133. * @throws SecurityException
  134. * @throws NoSuchMethodException
  135. * @throws InstantiationException
  136. * @throws InvocationTargetException
  137. * @throws IllegalArgumentException
  138. * @throws IllegalAccessException
  139. */
  140. @PostMapping("/postEntity")
  141. public ResponseEntity<?> postEntity(@RequestBody ENTITY entity) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
  142. Class entityClass = entity.getClass();
  143. setEntityId(entity, (ID)baseService.generateUniqueID());
  144. Integer i = baseService.insert(entity);
  145. return ResponseEntity
  146. .status(HttpStatus.OK)
  147. .body(new ResultMessage()
  148. .setCode(true)
  149. .setData(i)
  150. .setMessage("SUCCESS"));
  151. }
  152. /**
  153. * 根据id 更新实体表
  154. * @param id
  155. * @param entity
  156. * @return
  157. * @throws SecurityException
  158. * @throws NoSuchMethodException
  159. * @throws InvocationTargetException
  160. * @throws IllegalArgumentException
  161. * @throws IllegalAccessException
  162. */
  163. @PutMapping("/{id}")
  164. public ResponseEntity<?> putEntity(@PathVariable ID id, @RequestBody ENTITY entity) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
  165. log.debug("id:"+id);
  166. assertEntityExist(id);
  167. setEntityId(entity,id);
  168. baseService.updateById(entity);
  169. return ResponseEntity
  170. .status(HttpStatus.OK)
  171. .body(new ResultMessage()
  172. .setCode(true)
  173. .setData(entity)
  174. .setMessage("SUCCESS"));
  175. }
  176. /**
  177. * 根据id删除实体表数据
  178. * @param id
  179. * @return
  180. */
  181. @DeleteMapping("/{id}")
  182. public ResponseEntity<?> deleteEntity(@PathVariable ID id) {
  183. assertEntityExist(id);
  184. baseService.deleteById(id);
  185. return ResponseEntity
  186. .status(HttpStatus.OK)
  187. .body(new ResultMessage()
  188. .setCode(true)
  189. .setMessage("SUCCESS"));
  190. }
  191. @GetMapping("/selectAllByPage")
  192. public ResponseEntity<?> selectAllByPage(@RequestParam(value = "offset", required = false)String offsetString,
  193. @RequestParam(value = "limit", required = false) String limitString,
  194. @RequestParam(value = "order", required = false) String order )
  195. throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
  196. // Parse request parameters
  197. int offset = PageUtil.parseOffset(offsetString, PageConstant.OFFSET);
  198. int limit = PageUtil.parsePerPage(limitString, PageConstant.LIMIT);
  199. ENTITYExample example = createNewExample();
  200. Class exampleClass = example.getClass();
  201. Method m = exampleClass.getDeclaredMethod("setLimit", Integer.class);
  202. m.setAccessible(true);//因为写成private 所以这里必须设置
  203. m.invoke(exampleClass.newInstance(), limit);
  204. Method m2 = exampleClass.getDeclaredMethod("setOffset", Integer.class);
  205. m2.setAccessible(true);//因为写成private 所以这里必须设置
  206. m2.invoke(exampleClass.newInstance(), offset);
  207. return ResponseEntity
  208. .ok(new PaginatedResult()
  209. .setCode(true)
  210. .setData(baseService.selectByOption(example))
  211. .setTotal(baseService.selectCount(null).intValue()));
  212. }
  213. /**
  214. * 获取实体表所有数据
  215. * @return
  216. */
  217. @GetMapping("/selectAll")
  218. public ResponseEntity<?> selectAll() {
  219. List<ENTITY> entityList = baseService.selectByOption(null);
  220. return ResponseEntity
  221. .status(HttpStatus.OK)
  222. .body(new ResultMessage()
  223. .setCode(true)
  224. .setData(entityList)
  225. .setMessage("SUCCESS"));
  226. }
  227. /**
  228. * 获取实体表总记录数
  229. * @return
  230. */
  231. @GetMapping("/selectCount")
  232. public ResponseEntity<?> getCount() {
  233. Long result = baseService.selectCount(null);
  234. return ResponseEntity
  235. .status(HttpStatus.OK)
  236. .body(new ResultMessage()
  237. .setCode(true)
  238. .setData(result)
  239. .setMessage("SUCCESS"));
  240. }
  241. /**
  242. * 根据表字段条件查询单表数据
  243. * 只作用于单表,并且所有条件都为EqualTo
  244. * 字段加后缀_like,则做模糊查询
  245. * 字段加后缀_start,则做>=查询
  246. * 字段加后缀_end,则做<=查询
  247. *
  248. */
  249. @GetMapping("/selectEntityByEqualToOption")
  250. public ResponseEntity<?> selectEntityByEqualToOption(ENTITYParam param) {
  251. ENTITYExample example = (ENTITYExample) entity2example(param,createNewExample());
  252. List<ENTITY> entityList = baseService.selectByOption(example);
  253. return ResponseEntity
  254. .status(HttpStatus.OK)
  255. .body(new ResultMessage()
  256. .setCode(true)
  257. .setData(entityList)
  258. .setMessage("SUCCESS"));
  259. }
  260. /**
  261. * 根据表字段条件查询单表数据
  262. * 只作用于单表,并且所有条件都为EqualTo
  263. * 字段加后缀_like,则做模糊查询
  264. * 字段加后缀_start,则做>=查询
  265. * 字段加后缀_end,则做<=查询
  266. *
  267. */
  268. @GetMapping("/selectEntityByEqualToOptionByPage")
  269. public ResponseEntity<?> selectEntityByEqualToOptionByPage(ENTITYParam param)
  270. throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
  271. ENTITYExample example = (ENTITYExample) entity2example(param,createNewExample());
  272. List<ENTITY> entityList = baseService.selectByOption(example);
  273. return ResponseEntity
  274. .ok(new PaginatedResult()
  275. .setCode(true)
  276. .setData(entityList)
  277. .setTotal(baseService.selectCount(example).intValue()));
  278. }
  279. /**
  280. * 批量更新
  281. */
  282. @PutMapping("/updateBatchByIdList")
  283. public ResponseEntity<?> updateBatchByIdList(@RequestBody ENTITYParam param) {
  284. int i= baseService.updateBatchByIdList(param);
  285. return ResponseEntity
  286. .status(HttpStatus.OK)
  287. .body(new ResultMessage()
  288. .setCode(true)
  289. .setData(i)
  290. .setMessage("批量更新"+i+"条数据"));
  291. }
  292. /**
  293. * 批量删除
  294. * @throws InvocationTargetException
  295. * @throws IllegalArgumentException
  296. * @throws IllegalAccessException
  297. * @throws SecurityException
  298. * @throws NoSuchMethodException
  299. */
  300. @DeleteMapping("/deleteBatchByIdList")
  301. public ResponseEntity<?> deleteBatchByIdList(@RequestBody ENTITYParam param) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
  302. Method method = (Method) param.getClass().getMethod("getPrimaryKeyList");
  303. List primaryKeyList = (List)method.invoke(param);//获取主键list
  304. int i= baseService.deleteBatchByIdList(primaryKeyList);
  305. return ResponseEntity
  306. .status(HttpStatus.OK)
  307. .body(new ResultMessage()
  308. .setCode(true)
  309. .setData(i)
  310. .setMessage("批量删除"+i+"条数据"));
  311. }
  312. /**
  313. * 批量新增
  314. * @throws ParseException
  315. * @throws SecurityException
  316. * @throws NoSuchMethodException
  317. * @throws InvocationTargetException
  318. * @throws IllegalArgumentException
  319. * @throws IllegalAccessException
  320. */
  321. @PostMapping("/batchInsert")
  322. public ResponseEntity<?> batchInsert(@RequestBody ENTITYParam param) throws ParseException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  323. Method method = (Method) param.getClass().getMethod("getEntityList");
  324. List<ENTITY> entityList = (List<ENTITY>)method.invoke(param);//获取实体list
  325. for (ENTITY entity : entityList) {
  326. setEntityId(entity, (ID)baseService.generateUniqueID());
  327. }
  328. int i= baseService.insertBatch(entityList);
  329. return ResponseEntity
  330. .status(HttpStatus.OK)
  331. .body(new ResultMessage()
  332. .setCode(true)
  333. .setData(i)
  334. .setMessage("批量新增"+i+"条数据"));
  335. }
  336. /********************************** HELPER METHOD ***********************************/
  337. protected ENTITY assertEntityExist(ID id) {
  338. return baseService
  339. .selectById(id)
  340. .orElseThrow(() -> new ResourceNotFoundException()
  341. .setResourceName(getResourceName())
  342. .setId(id.toString()));
  343. }
  344. /**
  345. * 将实体的字段自动转为example的EqualTo
  346. * @param entity
  347. * @param example
  348. * @return
  349. */
  350. @SuppressWarnings({ "unchecked", "rawtypes" })
  351. protected Object entity2example(Object entity,Object example){
  352. try {
  353. Class exampleClass = example.getClass();
  354. Method createCriteriaMethod = (Method) exampleClass.getMethod("createCriteria");
  355. Object criteria = createCriteriaMethod.invoke(example);//生成criteria
  356. Class criteriaClass = criteria.getClass();
  357. //实体
  358. Class entityClass = entity.getClass();
  359. Field[] fields = entityClass.getDeclaredFields();
  360. ArrayList<Field> fieldList= new ArrayList<Field>();
  361. for (Field field : fields) {
  362. fieldList.add(field);
  363. }
  364. //获取实体类所有父类的属性
  365. fieldList = FgObjectUtil.getAllFields(entityClass,fieldList);
  366. for (Field field : fieldList) {
  367. String nameKey = field.getName();
  368. if("serialVersionUID".equals(nameKey)){
  369. continue;
  370. }
  371. if("distinct".equals(nameKey)) {
  372. Method entityMethod = (Method) entityClass.getMethod("is" + FgObjectUtil.getMethodName(nameKey));
  373. Object property = entityMethod.invoke(entity);// 调用getter方法获取属性值
  374. if(null ==property || "".equals(property)){
  375. continue;
  376. }
  377. Method m = exampleClass.getMethod("set"+ FgObjectUtil.getMethodName(nameKey), boolean.class);
  378. m.invoke(example, property);
  379. continue;
  380. }
  381. Method entityMethod = (Method) entityClass.getMethod("get" + FgObjectUtil.getMethodName(nameKey));
  382. Object property = entityMethod.invoke(entity);// 调用getter方法获取属性值
  383. if(null ==property || "".equals(property)){
  384. continue;
  385. }
  386. if("orderByClause".equals(nameKey)||"limit".equals(nameKey)||"offset".equals(nameKey)) {
  387. Method m = exampleClass.getMethod("set"+ FgObjectUtil.getMethodName(nameKey), FgObjectUtil.getPropertyType(property));
  388. m.invoke(example, property);
  389. }else if(nameKey.endsWith("_start")||nameKey.endsWith("_end")) {
  390. String nameKey2 =nameKey.replace("_start", "").replace("_end", "");
  391. if(nameKey.endsWith("_start")) {
  392. Method criteriaMethod = (Method) criteriaClass.getMethod("and" + FgObjectUtil.getMethodName(nameKey2)+"GreaterThanOrEqualTo",FgObjectUtil.getPropertyType(property));
  393. criteriaMethod.invoke(criteria,property);
  394. }else {
  395. Method criteriaMethod = (Method) criteriaClass.getMethod("and" + FgObjectUtil.getMethodName(nameKey2)+"LessThanOrEqualTo",FgObjectUtil.getPropertyType(property));
  396. criteriaMethod.invoke(criteria,property);
  397. }
  398. }else if(nameKey.endsWith("_like")){
  399. String nameKey2 =nameKey.replace("_like", "");
  400. //like 参数必须为string
  401. Method criteriaMethod = (Method) criteriaClass.getMethod("and" + FgObjectUtil.getMethodName(nameKey2)+"Like",String.class);
  402. criteriaMethod.invoke(criteria,"%"+property.toString()+"%");
  403. }else {
  404. Method criteriaMethod = (Method) criteriaClass.getMethod("and" + FgObjectUtil.getMethodName(nameKey)+"EqualTo",FgObjectUtil.getPropertyType(property));
  405. criteriaMethod.invoke(criteria,property);
  406. }
  407. }
  408. return example;
  409. } catch (Exception e) {
  410. log.error(e.getMessage());
  411. return null;
  412. }
  413. }
  414. }