自己开发独立项目的时候,像对单表的增删改查是必不可少的,每个都去写未免过于重复,下面对controller、service、dao以及entity都会有的字段,例如修改人、修改时间、删除标识等进行抽取封装,结合EasyCode代码生成工具,达到对单表的增删改查的代码自动生成的效果。此外,对像全局异常处理、操作日志管理、统一返回值等进行实现和封装,并作为一个独立的项目common,再次创建创建新项目的时候,只需要将此common引入即可。下面将封装的公共部分罗列出来。git地址:
1、公共实体类
package com.dz.web;
import com.dz.util.DateHelper;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.io.Serializable;
import java.util.Date;
import java.util.UUID;
/**
* 公共实体类
*/
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
private String id; // 主键
protected String createBy; // 创建者
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
protected Date createDate; // 创建日期
@JsonIgnore
protected String updateBy; // 更新者
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
protected Date updateDate; // 更新日期
@JsonIgnore
@Min(0)
@Max(1)
protected Integer deleted; // 删除标记(0:正常;1:删除)
public void preInsert(){
setId(UUID.randomUUID().toString());
setCreateDate(DateHelper.getCurrentDate());
setUpdateDate(DateHelper.getCurrentDate());
setDeleted(0);
}
public void preUpdate(){
setUpdateDate(DateHelper.getCurrentDate());
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public Integer getDeleted() {
return deleted;
}
public void setDeleted(Integer deleted) {
this.deleted = deleted;
}
}
2、api公共Response
package com.dz.web;
public class BaseResponse<T> {
private int code;
private String message;
private Boolean success;
private T data;
public BaseResponse() {
}
public BaseResponse(int code, String msg, Boolean success) {
this.setCode(code);
this.setMessage(msg);
this.setSuccess(success);
}
public BaseResponse(int code, String msg, Boolean success, T data) {
this.setCode(code);
this.setMessage(msg);
this.setData(data);
this.setSuccess(success);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
}
3、公共api返回参数
package com.dz.web;
/**
* 系统API返回参数
*/
public enum ApiCode {
// 通用
FAILED(false, 0, "操作失败!"),
//系统级
SUCCESS(true, 0, "成功"),
SYSTEM_EXCEPTION(false,999,"系统异常");
private BaseResponse baseResponse;
public BaseResponse getBaseResponse() {
this.baseResponse = new BaseResponse(baseResponse.getCode(), baseResponse.getMessage(), baseResponse.getSuccess());
baseResponse.setData("无返回数据项");
return baseResponse;
}
public BaseResponse getBaseResponse(Object data) {
this.baseResponse = new BaseResponse(baseResponse.getCode(), baseResponse.getMessage(), baseResponse.getSuccess());
baseResponse.setData(data);
return baseResponse;
}
/**
* 新增一个返回类用于返回修改后的提示信息
* @param data
* @param message
* @return
*/
public BaseResponse getBaseResponse(Object data, String message) {
this.baseResponse = new BaseResponse(baseResponse.getCode(), message, baseResponse.getSuccess());
baseResponse.setData(data);
return baseResponse;
}
ApiCode(boolean success, int statusCode, String message) {
this.baseResponse = null;
this.baseResponse = new BaseResponse(statusCode, message, success);
}
}
4、分页实体类
package com.dz.web;
import java.io.Serializable;
import java.util.*;
public class Page<T> implements Serializable {
private static final long serialVersionUID = 1L;
private Map<String,Object> params = new HashMap<>();
private T conditions;
private int pageNum = 1;
private int pageSize = 10;
private int size = 10;
private String orderBy;
private int startRow;
private int endRow;
private long total;
private int pages;
private List<T> list;
private int firstPage;
private int prePage;
private int nextPage;
private int lastPage;
private boolean isFirstPage;
private boolean isLastPage;
private boolean hasPreviousPage;
private boolean hasNextPage;
private int navigatePages;
private int[] navigatepageNums;
public Page() {
this.isFirstPage = false;
this.isLastPage = false;
this.hasPreviousPage = false;
this.hasNextPage = false;
}
public Page(List<T> list) {
this(list, 8);
}
public Page(List<T> list, int navigatePages) {
this.isFirstPage = false;
this.isLastPage = false;
this.hasPreviousPage = false;
this.hasNextPage = false;
if (list instanceof com.github.pagehelper.Page) {
com.github.pagehelper.Page page = (com.github.pagehelper.Page)list;
this.pageNum = page.getPageNum();
this.pageSize = page.getPageSize();
this.orderBy = page.getOrderBy();
this.pages = page.getPages();
this.list = page;
this.size = page.size();
this.total = page.getTotal();
if (this.size == 0) {
this.startRow = 0;
this.endRow = 0;
} else {
this.startRow = page.getStartRow() + 1;
this.endRow = this.startRow - 1 + this.size;
}
} else if (list instanceof Collection) {
this.pageNum = 1;
this.pageSize = list.size();
this.pages = 1;
this.list = list;
this.size = list.size();
this.total = (long)list.size();
this.startRow = 0;
this.endRow = list.size() > 0 ? list.size() - 1 : 0;
}
if (list instanceof Collection) {
this.navigatePages = navigatePages;
this.calcNavigatepageNums();
this.calcPage();
this.judgePageBoudary();
}
}
public Map<String, Object> getParams() {
return params;
}
public void setParams(Map<String, Object> params) {
this.params = params;
}
private void calcNavigatepageNums() {
int i;
if (this.pages <= this.navigatePages) {
this.navigatepageNums = new int[this.pages];
for(i = 0; i < this.pages; ++i) {
this.navigatepageNums[i] = i + 1;
}
} else {
this.navigatepageNums = new int[this.navigatePages];
i = this.pageNum - this.navigatePages / 2;
int endNum = this.pageNum + this.navigatePages / 2;
if (i < 1) {
i = 1;
for(i = 0; i < this.navigatePages; ++i) {
this.navigatepageNums[i] = i++;
}
} else if (endNum > this.pages) {
endNum = this.pages;
for(i = this.navigatePages - 1; i >= 0; --i) {
this.navigatepageNums[i] = endNum--;
}
} else {
for(i = 0; i < this.navigatePages; ++i) {
this.navigatepageNums[i] = i++;
}
}
}
}
private void calcPage() {
if (this.navigatepageNums != null && this.navigatepageNums.length > 0) {
this.firstPage = this.navigatepageNums[0];
this.lastPage = this.navigatepageNums[this.navigatepageNums.length - 1];
if (this.pageNum > 1) {
this.prePage = this.pageNum - 1;
}
if (this.pageNum < this.pages) {
this.nextPage = this.pageNum + 1;
}
}
}
private void judgePageBoudary() {
this.isFirstPage = this.pageNum == 1;
this.isLastPage = this.pageNum == this.pages;
this.hasPreviousPage = this.pageNum > 1;
this.hasNextPage = this.pageNum < this.pages;
}
public int getPageNum() {
return this.pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getPageSize() {
return this.pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getSize() {
return this.size;
}
public void setSize(int size) {
this.size = size;
}
public String getOrderBy() {
return this.orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public int getStartRow() {
return this.startRow;
}
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public int getEndRow() {
return this.endRow;
}
public void setEndRow(int endRow) {
this.endRow = endRow;
}
public long getTotal() {
return this.total;
}
public void setTotal(long total) {
this.total = total;
}
public int getPages() {
return this.pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public List<T> getList() {
return this.list;
}
public void setList(List<T> list) {
this.list = list;
}
public int getFirstPage() {
return this.firstPage;
}
public void setFirstPage(int firstPage) {
this.firstPage = firstPage;
}
public int getPrePage() {
return this.prePage;
}
public void setPrePage(int prePage) {
this.prePage = prePage;
}
public int getNextPage() {
return this.nextPage;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
public int getLastPage() {
return this.lastPage;
}
public void setLastPage(int lastPage) {
this.lastPage = lastPage;
}
public boolean isIsFirstPage() {
return this.isFirstPage;
}
public void setIsFirstPage(boolean isFirstPage) {
this.isFirstPage = isFirstPage;
}
public boolean isIsLastPage() {
return this.isLastPage;
}
public void setIsLastPage(boolean isLastPage) {
this.isLastPage = isLastPage;
}
public boolean isHasPreviousPage() {
return this.hasPreviousPage;
}
public void setHasPreviousPage(boolean hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public boolean isHasNextPage() {
return this.hasNextPage;
}
public void setHasNextPage(boolean hasNextPage) {
this.hasNextPage = hasNextPage;
}
public int getNavigatePages() {
return this.navigatePages;
}
public void setNavigatePages(int navigatePages) {
this.navigatePages = navigatePages;
}
public int[] getNavigatepageNums() {
return this.navigatepageNums;
}
public void setNavigatepageNums(int[] navigatepageNums) {
this.navigatepageNums = navigatepageNums;
}
public String toString() {
StringBuffer sb = new StringBuffer("PageInfo{");
sb.append("pageNum=").append(this.pageNum);
sb.append(", pageSize=").append(this.pageSize);
sb.append(", size=").append(this.size);
sb.append(", startRow=").append(this.startRow);
sb.append(", endRow=").append(this.endRow);
sb.append(", total=").append(this.total);
sb.append(", pages=").append(this.pages);
sb.append(", list=").append(this.list);
sb.append(", firstPage=").append(this.firstPage);
sb.append(", prePage=").append(this.prePage);
sb.append(", nextPage=").append(this.nextPage);
sb.append(", lastPage=").append(this.lastPage);
sb.append(", isFirstPage=").append(this.isFirstPage);
sb.append(", isLastPage=").append(this.isLastPage);
sb.append(", hasPreviousPage=").append(this.hasPreviousPage);
sb.append(", hasNextPage=").append(this.hasNextPage);
sb.append(", navigatePages=").append(this.navigatePages);
sb.append(", navigatepageNums=");
if (this.navigatepageNums == null) {
sb.append("null");
} else {
sb.append('[');
for(int i = 0; i < this.navigatepageNums.length; ++i) {
sb.append(i == 0 ? "" : ", ").append(this.navigatepageNums[i]);
}
sb.append(']');
}
sb.append('}');
return sb.toString();
}
}
5、公共Dao
package com.dz.web;
import java.util.List;
import java.util.Map;
/**
* DAO支持类实现
* @param <PK> 主键数据类型
* @param <T> 实体类
*/
public interface IBaseDao<PK, T> {
/**
* 根据id获取对象
*
* @param id
* @return
*/
T get(PK id);
/**
* 保存
*
* @param entity
*/
Integer save(T entity);
/**
* 更新
*
* @param entity
*/
Integer update(T entity);
/**
* 删除
*
* @param id
*/
Integer delete(PK id);
/**
* 分页查询
*
* @param params 条件
* @return
*/
List<T> queryPage(Map<String,Object> params);
}
6、公共Service
package com.dz.web;
public interface IBaseService<T> {
Integer update(T entity);
Integer delete(String id);
Integer save(T entity);
T get(String id);
Page<T> queryPage(Page<T> page);
}
7、公共service实现
package com.dz.web;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.util.List;
/**
* @param <T>
*/
@Service
public class BaseService<T extends BaseEntity> implements IBaseService<T> {
private static Logger log = LoggerFactory.getLogger(BaseService.class);
protected IBaseDao<String, T> iBaseDao;
@Override
@Transactional(readOnly = false)
public Integer update(T entity) {
Assert.notNull(entity, "CsDcProject entity must not be null!");
entity.preUpdate();
log.info("update:{}", entity);
return iBaseDao.update(entity);
}
@Override
@Transactional(readOnly = false)
public Integer delete(String id) {
log.info("delete:{}", id);
return iBaseDao.delete(id);
}
@Override
@Transactional(readOnly = false)
public Integer save(T entity) {
Assert.notNull(entity, entity.getClass().getSimpleName() + " entity must not be null!");
entity.preInsert();
log.info("save:{}", entity);
return iBaseDao.save(entity);
}
@Override
public T get(String id) {
log.info("get:{}", id);
return iBaseDao.get(id);
}
@Override
@Transactional(readOnly = false)
public Page<T> queryPage(Page<T> page) {
log.info("queryPage:{}", page);
PageHelper.startPage(page.getPageNum(),page.getPageSize());
List<T> list = iBaseDao.queryPage(page.getParams());
PageInfo pageInfo = new PageInfo(list);
page.setPageNum(pageInfo.getPageNum());
page.setPageSize(pageInfo.getPageSize());
page.setSize(pageInfo.getSize());
page.setOrderBy(pageInfo.getOrderBy());
page.setStartRow(pageInfo.getStartRow());
page.setEndRow(pageInfo.getEndRow());
page.setTotal(pageInfo.getTotal());
page.setPages(pageInfo.getPages());
page.setList(pageInfo.getList());
page.setFirstPage(pageInfo.getFirstPage());
page.setPrePage(pageInfo.getPrePage());
page.setNextPage(pageInfo.getNextPage());
page.setLastPage(pageInfo.getLastPage());
page.setIsFirstPage(pageInfo.isIsFirstPage());
page.setIsLastPage(pageInfo.isIsLastPage());
page.setHasPreviousPage(pageInfo.isHasPreviousPage());
page.setHasNextPage(pageInfo.isHasNextPage());
page.setNavigatePages(pageInfo.getNavigatePages());
page.setNavigatepageNums(pageInfo.getNavigatepageNums());
return page;
}
}
8、公共controller
package com.dz.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 公共controller
*/
@Controller
public class BaseController {
/**
* ThreadLocal确保高并发下每个请求的request,response都是独立的
*/
private static ThreadLocal<HttpServletRequest> currentRequest = new ThreadLocal<>();
private static ThreadLocal<HttpServletResponse> currentResponse = new ThreadLocal<>();
private static ThreadLocal<HttpSession> currentSession = new ThreadLocal<>();
/**
* 线程安全初始化reque,respose对象
*
* @param request
* @param response
*/
@ModelAttribute
public void initReqAndRep(HttpServletRequest request, HttpServletResponse response) {
currentRequest.set(request);
currentResponse.set(response);
currentSession.set(request.getSession());
}
// /**
// * 从请求头获取accessToken
// *
// * @return
// */
// public String getAuthorization() {
// String access_token = currentRequest.get().getHeader("accessToken");
// return access_token;
// }
//
// /**
// * 得到用户id
// *
// * @return
// */
// public String getUserId() {
// String id = getUsers().getId();
// return id;
// }
//
// /**
// * 从请求头获取用户名称
// *
// * @return
// */
// public String getUserName() {
// String username = getUsers().getName();
// return username;
// }
//
// /**
// * 从请求头获取用户
// *
// * @return
// */
// public SysUser getUsers() {
// HttpServletRequest request = currentRequest.get();
// Assert.notNull(request, "无法获取请求信息");
// String userDetails = request.getHeader("userDetails");
// try {
// if (StringUtils.isNotEmpty(userDetails)) {
// userDetails = URLDecoder.decode(userDetails, "UTF-8");
// } else {
// Assert.notNull(userDetails, "未获取用户信息");
// }
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
// userDetails = userDetails.replace("\\", "").replace("\"{", "{").replace("}\"", "}");
// JSONObject jsonObject = JSONObject.parseObject(userDetails);
// System.out.println("access_token为:[" + getAuthorization() + "]");
// System.out.println("当前请求头对象为[" + jsonObject + "]");
// SysUser user = jsonObject.toJavaObject(SysUser.class);
// return user;
// }
//
// /**
// * 从请求头获取用户
// *
// * @return
// */
// public SysUser getUsers(HttpServletRequest request) {
// JSONObject jsonobject = JSON.parseObject(currentRequest.get().getHeader("userDetails"));
// System.out.println("access_token为:[" + getAuthorization() + "]");
// System.out.println("当前请求头对象为[" + jsonobject + "]");
// SysUser user = jsonobject.toJavaObject(SysUser.class);
// return user;
// }
}
9、公共Restful风格controller
package com.dz.web;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
/**
* @param <T>
*/
public interface RestServiceController<T> {
/**
* 根据id查询资源
* @param id 资源的唯一标识
* @return
*/
@GetMapping("{id}")
Object getOne(@PathVariable("id") String id);
/**
* 列表分页
* @param page 分页对象
* @return
*/
@GetMapping
Object getList(@RequestBody Page<T> page);
/**
* 提交一个资源
* @param entity 资源实体
* @return
*/
@PostMapping
Object postOne(@RequestBody T entity);
/**
* 提交一个资源,并给出标识
* @param id 标识
* @param entity 资源实体
* @return
*/
@PutMapping("{id}")
Object putOne(@PathVariable("id") String id, @RequestBody T entity, HttpServletResponse response);
/**
* 提交一个资源的一部分,不处理null值
* @param id 标识
* @param entity 资源实体
* @return
*/
@PatchMapping("{id}")
Object patchOne(@PathVariable("id") String id, @RequestBody T entity);
/**
* 根据id删除一个资源
* @param id 标识
* @return
*/
@DeleteMapping("{id}")
Object deleteOne(@PathVariable("id") String id);
/**
* 批量删除资源
* @param ids 标识
* @return
*/
@DeleteMapping("deletes")
Object deleteMore(String[] ids);
}
10、公共Restful风格controller实现
package com.dz.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
/**
* @param <T>
*/
@RestController
public abstract class RestServiceControllerImpl<T extends BaseEntity> extends BaseController implements RestServiceController<T> {
@Autowired
protected IBaseService<T> baseService;
@Override
@GetMapping("{id}")
public BaseResponse<T> getOne(@PathVariable("id") String id) {
BaseResponse baseResponse = ApiCode.SUCCESS.getBaseResponse(baseService.get(id));
return baseResponse;
}
@Override
@GetMapping
public BaseResponse<Page<T>> getList(@RequestBody Page<T> page) {
BaseResponse baseResponse = ApiCode.SUCCESS.getBaseResponse(baseService.queryPage(page));
return baseResponse;
}
@Override
@PostMapping
public BaseResponse postOne(@RequestBody T entity) {
baseService.save(entity);
BaseResponse<Page<T>> baseResponse = ApiCode.SUCCESS.getBaseResponse(entity);
return baseResponse;
}
@Override
@PutMapping("{id}")
public BaseResponse putOne(@PathVariable("id") String id, @RequestBody T entity, HttpServletResponse response) {
baseService.update(entity);
BaseResponse<Page<T>> baseResponse = ApiCode.SUCCESS.getBaseResponse(entity);
return baseResponse;
}
@Override
@PatchMapping("{id}")
public BaseResponse patchOne(@PathVariable("id") String id, @RequestBody T entity) {
baseService.update(entity);
BaseResponse<Page<T>> baseResponse = ApiCode.SUCCESS.getBaseResponse(entity);
return baseResponse;
}
@Override
@DeleteMapping("{id}")
public BaseResponse deleteOne(@PathVariable("id") String id) {
baseService.delete(id);
BaseResponse<Page<T>> baseResponse = ApiCode.SUCCESS.getBaseResponse();
return baseResponse;
}
@Override
@DeleteMapping("/rest/deletes")
public BaseResponse deleteMore(@RequestParam("ids") String[] ids) {
for (String id : ids) {
baseService.delete(id);
}
BaseResponse<Page<T>> baseResponse = ApiCode.SUCCESS.getBaseResponse();
return baseResponse;
}
}