1. 程式人生 > >spring boot+tkmybatis構建後臺服務框架

spring boot+tkmybatis構建後臺服務框架

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

}

`