最近一直在写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));
}
}
`