spring boot+tkmybatis構建後臺服務框架
阿新 • • 發佈:2019-02-16
最近一直在寫C++與C#方面的部落格,也沒有貼java方面的總結,正好有時間吧前一段時間一個springboot 後臺服務框架貼出來,幫助大家快速構建後臺,整個架構大致是採用tkmybatis做的,mapper server controller 每一層都有封裝,token校驗和傳參拷貝也有封裝,請求報文也有封裝,好了不廢話了,一下是整個專案簡介
Controller 基類
public class BaseController { protected static Map<String, Object> javaBean2Map(Object entity) { String json = JSON.toJSONString(entity); JSONObject jsonObject = JSON.parseObject(json); return jsonObject.toJavaObject(Map.class); } protected Object jsonMsg(boolean isSuccess, String code, String msg, Object data) { return ImmutableMap.of("success", isSuccess, "code", code, "msg", msg, "data", data ); } protected Object jsonMsg(boolean isSuccess, int code, String msg, Object data) { return ImmutableMap.of("success", isSuccess, "code", code, "msg", msg, "data", data == null ? Collections.emptyMap() : data ); } protected Object successResponse(@Nullable Object data) { return jsonMsg(true, ResponseCodeEnum.SUCCESS.getCode(), ResponseCodeEnum.SUCCESS.getContent(), data); } protected Object unSuccessResponse(ResponseCodeEnum response) { return jsonMsg(false, response.getCode(), response.getContent(), Collections.emptyMap()); } protected Object unSuccessResponse(String message) { return jsonMsg(false, ResponseCodeEnum.PROMPT.getCode(), message, Collections.emptyMap()); } protected Object unSuccessResponse(ResponseEntity responseEntity) { return jsonMsg(responseEntity.getError(), responseEntity.getCode(), responseEntity.getContent(), Collections.emptyMap()); } /** * 分頁設定 * * @param offset * @param limit * @return */ protected RowBounds setPage(Integer offset, Integer limit) { if (offset >= 1) { offset = (offset - 1) * limit; } return new RowBounds(offset, limit); } protected Integer getOffset(Integer pageNo,Integer size) { if (pageNo >= 1) { pageNo = (pageNo - 1) * size; } return pageNo; } }
Server 層模版類實現(介面基於tkmybatis)
public interface IBaseService<T> { List<T> select(T var1); T selectById(Long id, Class<T> clsz); List<T> selectAll(); T save(T var1); boolean delete(T var1); /** * 刪除一條資料 * * @param id */ int delete(Long id, Class<T> classz); int selectCount(T var1); int selectCount(Map<String, Object> condition, Class<T> clazz); T selectOne(T var1); List<T> selectByExample(Map<String, Object> conition); List<T> selectByExampleAndRowBounds(Object var1, RowBounds var2); List<T> selectByConditionAndRowBoundsForEntity(Map<String, Object> condition, RowBounds var2); List<T> listByCondition(Map<String, Object> condition, String orderBy, SqlOrderEnum sqlOrderEnum); List<T> listByPage(Map<String, Object> condition, int offset, int rows); List<T> listByPage(Map<String, Object> condition, int offset, int rows, String startTime, String endTime, String field); List<T> listByPage(Map<String, Object> condition, int offset, int rows, String orderBy, SqlOrderEnum sqlOrderEnum); /** * 根據任意屬性和屬性值進行物件模糊查詢 * * @param condition * @return */ public List<T> like(Map<String, Object> condition); public List<T> likeRightBlur(String property, String value); public List<T> likeLeftAndRightBlur(String property, String value); public List<T> like(Map<String, Object> condition, String orderBy, SqlOrderEnum sqlOrderEnum); List<T> listByConditionForPage(Map<String, Object> condition, String orderBy, SqlOrderEnum sqlOrderEnum, RowBounds var2); boolean updateByExample(T var1, Object var2); boolean updateByExampleSelective(T var1, Object var2); int insertSelective(T var1); List<T> selectByRowBounds(T var1, RowBounds var2); List<T> selectByConditionAndRowBounds(Map<String, Object> conition, RowBounds var2); boolean updateByConditionSelective(T entity, Map<String, Object> condition); boolean updateByListSelective(T entity, List<Long> ids); boolean updateByIdSelective(T entity, Long id); boolean updateById(T entity, Long id); int insertUseGeneratedKeys(T var1); int insertSelectiveUseGeneratedKeys(T record); }
service 實現類模版
@Transactional public abstract class AbstractBaseService<T extends BaseEntity, M extends BaseMapper<T>> implements IBaseService<T> { @Autowired protected M baseMapper; private Class<?> clazz = null; protected abstract Class<?> getEntityClass(); @Override public T selectById(Long id, Class<T> clsz) { Example example = new Example(clsz); Example.Criteria criteria = example.createCriteria(); criteria.andEqualTo("id", id); return this.baseMapper.selectByPrimaryKey(example); } @Override public List<T> select(T var1) { return baseMapper.select(var1); } @Override public T save(T entity) { Preconditions.checkNotNull(entity); enhanceNewCreateBaseEntity(entity, OperatorEnum.INSERT.getDesc()); entity.setCreateTime(new Timestamp(System.currentTimeMillis())); entity.setUpdateTime(new Timestamp(System.currentTimeMillis())); entity.setStatus(DataStatusEnum.ENABLE.getCode()); baseMapper.insertUseGeneratedKeys(entity); return baseMapper.selectByPrimaryKey(ImmutableMap.of("id", entity.getId())); } @Override public boolean delete(T entity) { return baseMapper.delete(entity) > 0; } /** * 刪除一條資料 * * @param id */ @Override public int delete(Long id, Class<T> clazz) { T entity = baseMapper.selectByPrimaryKey(id); if (entity != null) { entity.setStatus(0); return baseMapper.updateByPrimaryKeySelective(entity); } return 0; } @Override public int selectCount(T var1) { return baseMapper.selectCount(var1); } @Override public T selectOne(T var1) { return baseMapper.selectOne(var1); } @Override public boolean updateByExample(T entity, Object obj) { enhanceNewCreateBaseEntity(entity, OperatorEnum.UPDATE.getDesc()); return baseMapper.updateByExample(entity, obj) > 0; } @Override public List<T> selectAll() { return baseMapper.selectAll(); } @Override public boolean updateByExampleSelective(T entity, Object obj) { entity.setUpdateTime(new Timestamp(System.currentTimeMillis())); return baseMapper.updateByExampleSelective(entity, obj) > 0; } @Override public boolean updateByConditionSelective(T entity, Map<String, Object> condition) { enhanceNewCreateBaseEntity(entity, OperatorEnum.UPDATE.getDesc()); Example example = new Example(entity.getClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet() ) { criteria.andEqualTo(field, condition.get(field)); } entity.setUpdateTime(new Timestamp(System.currentTimeMillis())); return baseMapper.updateByExampleSelective(entity, example) > 0; } @Override public List<T> selectByExample(Map<String, Object> condition) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet() ) { if (!"orderBy".equals(field) && !"DescOrAsc".equals(field)) { criteria.andEqualTo(field, condition.get(field)); } } if (condition.containsKey("orderBy") && condition.containsKey("DescOrAsc")) {//排序查詢 if ("desc".equals((String) condition.get("DescOrAsc"))) { example.orderBy((String) condition.get("orderBy")).desc(); } else { example.orderBy((String) condition.get("orderBy")).asc(); } } return baseMapper.selectByExample(example); } @Override public boolean updateByIdSelective(T entity, Long id) { enhanceNewCreateBaseEntity(entity, OperatorEnum.UPDATE.getDesc()); Example example = new Example(entity.getClass()); Example.Criteria criteria = example.createCriteria(); criteria.andEqualTo("id", id); return baseMapper.updateByExampleSelective(entity, example) > 0; } @Override public boolean updateById(T entity, Long id) { enhanceNewCreateBaseEntity(entity, OperatorEnum.UPDATE.getDesc()); Example example = new Example(entity.getClass()); Example.Criteria criteria = example.createCriteria(); criteria.andEqualTo("id", id); entity.setUpdateTime(new Timestamp(System.currentTimeMillis())); return baseMapper.updateByExample(entity, example) > 0; } @Override public boolean updateByListSelective(T entity, List<Long> ids) { enhanceNewCreateBaseEntity(entity, OperatorEnum.UPDATE.getDesc()); Example example = new Example(entity.getClass()); Example.Criteria criteria = example.createCriteria(); criteria.andIn("id", ids); entity.setUpdateTime(new Timestamp(System.currentTimeMillis())); return baseMapper.updateByExampleSelective(entity, example) > 0; } @Override public int insertSelective(T entity) { enhanceNewCreateBaseEntity(entity, OperatorEnum.INSERT.getDesc()); return baseMapper.insertSelective(entity); } @Override public int insertSelectiveUseGeneratedKeys(T entity) { enhanceNewCreateBaseEntity(entity, OperatorEnum.INSERT.getDesc()); return baseMapper.insertSelectiveUseGeneratedKeys(entity); } @Override public List<T> selectByRowBounds(T entity, RowBounds rowBounds) { return baseMapper.selectByRowBounds(entity, rowBounds); } /** * 條件查詢分頁 * * @param condition * @param var2 * @return */ @Override public List<T> selectByConditionAndRowBounds(Map<String, Object> condition, RowBounds var2) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet() ) { if (!"orderBy".equals(field) && !"DescOrAsc".equals(field)) { criteria.andEqualTo(field, condition.get(field)); } } if (condition.containsKey("orderBy") && condition.containsKey("DescOrAsc")) {//排序查詢 if ("desc".equals((String) condition.get("DescOrAsc"))) { example.orderBy((String) condition.get("orderBy")).desc(); } else { example.orderBy((String) condition.get("orderBy")).asc(); } } return baseMapper.selectByExampleAndRowBounds(example, var2); } /** * 根據條件集合進行分頁查詢 * * @param condition 查詢條件 * @param offset 偏移 * @param rows 查詢條數 * @return 返回Pager物件 */ @Override public List<T> listByPage(Map<String, Object> condition, int offset, int rows) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet() ) { criteria.andEqualTo(field, condition.get(field)); } return baseMapper.selectByExampleAndRowBounds(example, new RowBounds(offset, rows)); } @Override public List<T> listByPage(Map<String, Object> condition, int offset, int rows,String startTime, String endTime,String field) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String f : condition.keySet() ) { criteria.andEqualTo(field, condition.get(field)); } if (StringUtils.isNotBlank(field)) { criteria.andGreaterThanOrEqualTo(field,startTime); criteria.andLessThanOrEqualTo(field,endTime); } return baseMapper.selectByExampleAndRowBounds(example, new RowBounds(offset, rows)); } @Override public List<T> listByPage(Map<String, Object> condition, int offset, int rows, String orderBy, SqlOrderEnum sqlOrderEnum) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet() ) { criteria.andEqualTo(field, condition.get(field)); } if (StringUtils.isNotBlank(orderBy) && sqlOrderEnum != null) { if (sqlOrderEnum.getName().equals("desc")) { example.orderBy(orderBy).desc(); } else { example.orderBy(orderBy).asc(); } } return baseMapper.selectByExampleAndRowBounds(example, new RowBounds(offset, rows)); } /** * 根據任意屬性和屬性值進行物件模糊查詢 * * @param condition * @return */ @Override public List<T> like(Map<String, Object> condition) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet() ) { criteria.andLike(field, (String) condition.get(field)+"%"); } return baseMapper.selectByExample(example); } @Override public List<T> like(Map<String, Object> condition, String orderBy, SqlOrderEnum sqlOrderEnum) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet() ) { criteria.andLike(field, (String) condition.get(field)); } if (StringUtils.isNotBlank(orderBy) && sqlOrderEnum != null) { if (sqlOrderEnum.getName().equals("desc")) { example.orderBy(orderBy).desc(); } else { example.orderBy(orderBy).asc(); } } return baseMapper.selectByExample(example); } @Override public List<T> likeRightBlur(String property, String value) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); criteria.andLike(property,value+"%"); criteria.andEqualTo("status",DataStatusEnum.ENABLE.getCode()); return baseMapper.selectByExample(value); } @Override public List<T> likeLeftAndRightBlur(String property, String value) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); criteria.andLike(property,"%"+value+"%"); criteria.andEqualTo("status",DataStatusEnum.ENABLE.getCode()); return baseMapper.selectByExample(example); } /** * 條件查詢分頁 * * @param condition * @param var2 * @return */ @Override public List<T> selectByConditionAndRowBoundsForEntity(Map<String, Object> condition, RowBounds var2) { Example example = new Example(getEntityClass()); Example.Criteria criteria = null; if (condition.keySet().size() != 2) { criteria = example.createCriteria(); } for (String field : condition.keySet() ) { if (!"orderBy".equals(field) && !"DescOrAsc".equals(field)) { criteria.andEqualTo(field, condition.get(field)); } } if (condition.containsKey("orderBy") && condition.containsKey("DescOrAsc")) {//排序查詢 if ("desc".equals((String) condition.get("DescOrAsc"))) { example.orderBy((String) condition.get("orderBy")).desc(); } else { example.orderBy((String) condition.get("orderBy")).asc(); } } return baseMapper.selectByExampleAndRowBounds(example, var2); } @Override public List<T> selectByExampleAndRowBounds(Object var1, RowBounds var2) { return this.baseMapper.selectByExampleAndRowBounds(var1, var2); } @Override public int insertUseGeneratedKeys(T entity) { enhanceNewCreateBaseEntity(entity, OperatorEnum.INSERT.getDesc()); return this.baseMapper.insertSelective(entity); } @Override public List<T> listByCondition(Map<String, Object> condition, String orderBy, SqlOrderEnum sqlOrderEnum) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet()) { criteria.andEqualTo(field, condition.get(field)); } if (StringUtils.isNotBlank(orderBy)) { if (sqlOrderEnum.getName().equals(SqlOrderEnum.DESC.getName())) { example.orderBy(orderBy).desc(); } else { example.orderBy(orderBy).asc(); } } return baseMapper.selectByExample(example); } @Override public List<T> listByConditionForPage(Map<String, Object> condition, String orderBy, SqlOrderEnum sqlOrderEnum, RowBounds var2) { Example example = new Example(getEntityClass()); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet()) { criteria.andEqualTo(field, condition.get(field)); } if (StringUtils.isNotBlank(orderBy)) { if (sqlOrderEnum.getName().equals(SqlOrderEnum.DESC.getName())) { example.orderBy(orderBy).desc(); } else { example.orderBy(orderBy).asc(); } } return baseMapper.selectByExampleAndRowBounds(example, var2); } @Override public int selectCount(Map<String, Object> condition, Class<T> clazz) { Example example = new Example(clazz); Example.Criteria criteria = example.createCriteria(); for (String field : condition.keySet()) { criteria.andEqualTo(field, condition.get(field)); } return this.baseMapper.selectCountByExample(example); } private final T enhanceNewCreateBaseEntity(T entity, String operatorType) { if (entity instanceof BaseEntity) { BaseEntity baseEntity = (BaseEntity) entity; //設定預設值,如果預設值和common不一樣,需要自行設定初始值 if (operatorType.equals(OperatorEnum.UPDATE.getDesc())) { if (baseEntity.getUpdateTime() == null) { baseEntity.setUpdateTime(new Timestamp(System.currentTimeMillis())); } }else { if (baseEntity.getCreateTime() == null) { baseEntity.setCreateTime(new Timestamp(System.currentTimeMillis())); } if (baseEntity.getStatus() == null) { baseEntity.setStatus(DataStatusEnum.ENABLE.getCode()); } } } return entity; } }
Mapper 層基類封裝(tkmybatis)
/**
* @author huijun
*/
public interface BaseMapper<T> extends Mapper<T>, MySqlMapper<T> {
/**
* 不插入為空的欄位,且自動生成ID
*/
@Options(useGeneratedKeys = true, keyProperty = "id")
@InsertProvider(type = WeekendInsertProvider.class, method = "dynamicSQL")
int insertSelectiveUseGeneratedKeys(T record);
}
entity 也有基類(tkmybatis 框架自身需要支援的欄位,所以封裝下)
@Data
public class BaseEntity implements Serializable {
@Id
private Long id;
/**
* 資料狀態 1:正常 0:刪除
*/
private Integer status ;
/**
* creator
*/
private Long creator;
/**
* modifier
*/
private Long modifier;
/**
* createTime
*/
@Column(name = "create_time")
private Date createTime ;
/**
* updateTime
*/
@Column(name = "update_time")
private Date updateTime ;
}
JWTs 做鑑權 (token認證)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
String value() default "";
Action action() default Action.NORMAL;
}
攔截器
/**
* @author huijun
*/
public class TokenInterceptor extends HandlerInterceptorAdapter {
Logger log = LoggerFactory.getLogger(TokenInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
Token annotation = method.getAnnotation(Token.class);
if (annotation != null) {
String token = request.getHeader("token");
if (token == null) {
response.setStatus(401);
return false;
} else {
log.debug("tokenStr:" + token);
}
Claims claims1 = TokenMangager.getClaimsFromToken(token);
if (claims1 != null) {
Long u = claims1.get(Constant.TOKEN_USER_ID, Long.class);
if (u != null) {
log.info("token檢驗成功");
CurrentLoginUserContext.setUserId(u);
return true;
} else {
response.setStatus(401);
return false;
}
} else {
response.setStatus(401);
return false;
}
}
return true;
} else {
return super.preHandle(request, response, handler);
}
}
}
``
記憶體管理token
public class TokenMangager {
private static String secret = "#$sdd2df2dsdfsdfds";
public static String generateToken(Map<String, Object> claims,Date date){
String tokenStr = Jwts.builder()
.setClaims(claims)
.setExpiration(date)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
return tokenStr;
}
public static Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
}
物件拷貝,用於跨類物件拷貝
public class InnerBeanUtils {
public static String[] getNullPropertyNames(Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for (java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) {
emptyNames.add(pd.getName());
}
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
public static void copyPropertiesIgnoreNull(Object source, Object target) {
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
}
}
`