zoukankan      html  css  js  c++  java
  • 基础框架一:“零代码”实现单表增删改查、唯一性校验、枚举类型翻译

    概述

    在日常开发中,有很多模块如基础信息都是单表的增删改查,如果每个单表都要自己编写增删改查代码,无疑增加了很多不必要的开发成本。本文通过对增删改查进行封装,通过EasyCode生成模块代码,无需编写任何代码,即可实现单表增删改查、唯一性校验、数据字典翻译。

    模块介绍

    本文主要分为以下几个模块

    1. Controller :封装对外暴露的增删改查restful接口
    2. Service ,封装具体的增删改查逻辑,包括唯一性校验、增删改操作前后的个性操作
    3. Mapper ,继承Mybatisplus的BaseMapper接口
    4. DTO ,返回给前端的实体,包含字段校验、枚举翻译等

    在介绍之前先看下一个完整的案例,熟悉下使用方式(下面案例代码均可由EasyCode生成)

    以用户模块为例:

    UserController
    注:对外暴露用户的增删改查接口

    @RestController
    @RequestMapping("user")
    public class UserController extends YaoBaseController<UserParam, UserEntity, UserDTO> {
    
        @Autowired
        private UserService userService;
        
        @Override
        public YaoBaseService<UserParam, UserEntity> getService() {
            return userService;
        }
    
        @Override
        public UserDTO getDTO() {
            return new UserDTO();
        }
    
        @Override
        public UserEntity getEntity() {
            return new UserEntity();
        }
    }
    

    UserDTO
    注:用户字段校验,枚举翻译( @Formatter)等

    /**
     * 用户DTO
     * @author YAO
     * @since 2020-06-13
     */
    public class UserDTO extends YaoBaseDTO implements Serializable {
        /**
         * 用户名
         */
        @NotNull
        private String username;
    
        /**
         * 别名即真实姓名
         */
        private String nickname;
        /**
         * 是否有效,将 1:翻译成有效,0:翻译成无效
         */
        @Formatter(dictCode = "enabled", targetField = "enabledStr")
        private Integer enabled;
    
        private String enabledStr;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getNickname() {
            return nickname;
        }
    
        public void setNickname(String nickname) {
            this.nickname = nickname;
        }
        public Integer getEnabled() {
            return enabled;
        }
    
        public void setEnabled(Integer enabled) {
            this.enabled = enabled;
        }
            public String getEnabledStr() {
            return enabledStr;
        }
    
        public void setEnabledStr(String enabledStr) {
            this.enabledStr = enabledStr;
        }
    }
    

    UserParam
    注:只要username非空,自动查询指定username对应的用户,无需编写其他代码

    /**
     * 用户请求参数
     * @author Yao
     * @since 2020-07-02
     */
    public class UserParam extends PageParam {
    
        private String username;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    }
    
    

    UserService

    /**
     * 用户service
     * @author YAO
     * @since 2020-06-13
     */
    public interface UserService extends YaoBaseService<UserParam, UserEntity> {
    }
    
    

    UserServiceImpl

    /**
     * 用户service的实现类
     *
     * @author YAO
     * @since 2020-06-13
     */
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserMapper userMapper;
        
        @Override
        public YaoBaseMapper<UserEntity> getMapper() {
            return userMapper;
        }
    }
    

    UserMapper

    /**
     * 用户数据库操作
     * @author YAO
     * @since 2020-06-13
     */
    @Mapper
    public interface UserMapper extends YaoBaseMapper<UserEntity> {
    
    }
    

    UserEntity

    /**
     * 用户实体
     * @author YAO
     * @since 2020-06-13
     */
    @TableName("user")
    public class UserEntity extends YaoBaseEntity implements Serializable {
    
        /**
         * 用户名
         */
        private String username;
        /**
         * 别名即真实姓名
         */
        private String nickname;
        
        /**
         * 是否有效
         */
        private Integer enabled;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getNickname() {
            return nickname;
        }
    
        public void setNickname(String nickname) {
            this.nickname = nickname;
        }
    
        public Integer getEnabled() {
            return enabled;
        }
    
        public void setEnabled(Integer enabled) {
            this.enabled = enabled;
        }
    }
    

    下面是各模块上层的代码封装:

    1、Controller

    自定义YaoBaseController,使用方式继承该类
    自带增删改查restful接口,其中查询会对DTO中被 @Formatter 注解的字段进行翻译,如:“0,1” 翻译成“男、女",支持 JSR-303对字段进行校验

    package com.jing.yao.component.controller;
    
    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.jing.yao.annotation.ExcelFileName;
    import com.jing.yao.annotation.Permission;
    import com.jing.yao.bean.ResponseBean;
    import com.jing.yao.component.dto.YaoBaseDTO;
    import com.jing.yao.component.entity.YaoBaseEntity;
    import com.jing.yao.component.params.page.PageParam;
    import com.jing.yao.component.service.YaoBaseService;
    import com.jing.yao.constant.ErrorCode;
    import com.jing.yao.excel.ExcelUtil;
    import com.jing.yao.exception.BusinessExceptionBuilder;
    import com.jing.yao.holder.UserContentHolder;
    import com.jing.yao.utils.YaoBeanUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeanUtils;
    import org.springframework.dao.DuplicateKeyException;
    import org.springframework.web.bind.annotation.*;
    
    import javax.servlet.http.HttpServletResponse;
    import javax.validation.Valid;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    import static com.jing.yao.bean.ResponseBean.builder;
    import static com.jing.yao.component.constants.ResponseCode.ENTITY_NOT_FOUND;
    import static com.jing.yao.component.constants.ResponseCode.FAIL_CODE;
    
    
    /**
     * 基础controller
     *
     * @author Yao
     * @since 2020-06-13
     */
    public abstract class YaoBaseController<P extends PageParam, T extends YaoBaseEntity, D extends YaoBaseDTO> {
    
        /**
         * 记录日志
         */
        protected Logger logger = LoggerFactory.getLogger(this.getClass());
    
        /**
         * 获取实际服务类
         *
         * @return
         */
        public abstract YaoBaseService<P, T> getService();
    
        /**
         * 获取当前Controller数据库实体Entity
         *
         * @return
         */
        public abstract T getEntity();
    
        /**
         * 获取当前Controller数据传输DTO
         *
         * @return
         */
        public abstract D getDTO();
    
        /**
         * 分页模板
         *
         * @param param
         * @return
         */
        @GetMapping("/pageList")
        public ResponseBean pageList(P param) {
            IPage iPage = getService().page(param);
            List<T> records = iPage.getRecords();
            List<D> list = records.stream().map(entity -> {
                D dto = getDTO();
                YaoBeanUtils.copyAndFormatter(entity, dto);
                return dto;
            }).collect(Collectors.toList());
    
            Page<D> pageDto = new Page<>();
            pageDto.setCurrent(iPage.getCurrent());
            pageDto.setRecords(list);
            pageDto.setPages(iPage.getPages());
            pageDto.setTotal(iPage.getTotal());
            pageDto.setSize(iPage.getSize());
            return successBean(pageDto);
        }
    
    
        /**
         * 根据ID查询相关记录
         *
         * @param id
         * @return
         */
        @GetMapping("/{id}")
        public ResponseBean selectById(@PathVariable("id") Long id) {
            logger.info("{}根据ID查询服务开始,id为:{}", this.getClass().getSimpleName(), id);
            T result = getService().selectOneById(id);
            if (result == null) {
                throw BusinessExceptionBuilder.build(ErrorCode.DETAIL_ID_NOT_EXIST);
            }
            ResponseBean responseBean = successBean(result);
            logger.info("{}根据ID查询结束,结果:{}", this.getClass().getSimpleName(), toJSONString(responseBean));
            return responseBean;
        }
    
        /**
         * 转换为JSON字符串
         *
         * @param object
         * @return
         */
        private String toJSONString(Object object) {
            ObjectMapper mapper = new ObjectMapper();
            String result = "";
            try {
                result = mapper.writeValueAsString(object);
            } catch (JsonProcessingException e) {
            }
            return result;
        }
    
        /**
         * 插入
         *
         * @param dto
         * @return
         * @throws Exception
         */
        @PostMapping
        @Permission(value = "add")
        public ResponseBean insert(@Valid @RequestBody D dto) {
            logger.info("{}新增服务开始,参数:{}", this.getClass().getSimpleName(), toJSONString(dto));
    
            ResponseBean responseBean = successBean();
            boolean insert;
            T entity = getEntity();
            try {
                //dto转为数据库实体
                BeanUtils.copyProperties(dto, entity);
                //新增前校验
                insert = getService().insert(entity);
            } catch (DuplicateKeyException exception) {
                exception.printStackTrace();
                return builder().code(FAIL_CODE).build();
            }
    
            //当插入记录小于1时,表示插入失败
            if (!insert) {
                responseBean = builder().code(FAIL_CODE).content(insert).build();
            }
            logger.info("{}新增服务结束,结果:{}", this.getClass().getSimpleName(), toJSONString(responseBean));
            return responseBean;
        }
    
    
        /**
         * 根据ID修改对应记录
         *
         * @param dto
         * @return
         * @throws Exception
         */
        @PutMapping
        @Permission(value = "edit")
        public ResponseBean updateById(@Valid @RequestBody D dto) {
            String username = UserContentHolder.getContext().getUsername();
            logger.info("{}更新服务开始,更新人:{},参数:{}", this.getClass().getSimpleName(), username, toJSONString(dto));
            T entity = getEntity();
            //dto转换entity
            BeanUtils.copyProperties(dto, entity);
            ResponseBean responseBean = null;
            boolean count;
    
            try {
                count = getService().update(entity);
            } catch (DuplicateKeyException exception) {
                return builder().code(FAIL_CODE).build();
            }
    
            //当更新记录小于1时,表示更新失败
            if (!count) {
                responseBean = builder().code(FAIL_CODE).content(count).build();
            }
            logger.info("{}更新服务结束,结果:{}", this.getClass().getSimpleName(), toJSONString(responseBean));
    
            return successBean(count);
        }
    
    
        /**
         * 根据ID删除指定记录,这里被删除的记录会进入删除记录表
         *
         * @param id
         * @return
         */
        @DeleteMapping("/{id}")
        @Permission(value = "del")
        public ResponseBean deleteById(@PathVariable("id") Long id) {
            logger.info("{}删除服务开始,参数ID:{}", this.getClass().getSimpleName(), id);
            boolean deleteCount = getService().removeById(id);
            ResponseBean responseBean = successBean(deleteCount);
            //当删除记录小于1时,表示更新失败
            if (!deleteCount) {
                responseBean = builder().code(FAIL_CODE).build();
            }
    
            logger.info("{}删除服务结束,结果:{}", this.getClass().getSimpleName(), toJSONString(responseBean));
            return responseBean;
        }
        
        /**
         * 构建成功响应实例
         *
         * @return
         */
        public ResponseBean successBean() {
            return builder().build();
        }
    
        /**
         * 构建成功响应实例
         *
         * @param data
         * @return
         */
        public ResponseBean successBean(Object data) {
            return builder().content(data).build();
        }
    }
    
    

    2、Service

    自定义YaoBaseService,使用方式继承该类
    主要提供以下功能
    (1)封装基础的增删改查功能
    (2)当查询有查询条件时,只需请求对应的Param对象中属性有值即可,无需写再写查询代码
    自定义的参数对象继承 YaoBaseParams,并定义自己的属性即可。当然,如果想自定义查询条件只需重写 com.anji.plus.component.service.YaoBaseService#getWrapper即可

    /**
     * 基础查询参数
     * @author Yao
     * @since 2020-06-13
     */
    public class YaoBaseParams {
    }
    

    (3)前置后置处理器 processBeforeOperationprocessAfterOperation。当InsertUpdateDelete 执行前后需要增加些逻辑时,需重写前置后置处理器。比如:删除之前想校验数据是否能删除、保存更新后想操作下缓存(Redis)等
    Demo:

      @Override
        public void processBeforeOperation(BmsApplyManagement entity, BaseOperationEnum operationEnum) throws BusinessException {
            switch (operationEnum) {
                case INSERT:
                    break;
                case UPDATE:
                    break;
                case DELETE:
                    break;
                default:
            }
        }
    
    package com.jing.yao.component.service;
    
    import com.baomidou.mybatisplus.core.conditions.Wrapper;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.core.metadata.OrderItem;
    import com.baomidou.mybatisplus.core.toolkit.Wrappers;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
    import com.jing.yao.annotation.UnionUnique;
    import com.jing.yao.annotation.Unique;
    import com.jing.yao.component.constants.BaseOperationEnum;
    import com.jing.yao.component.constants.BmsConstants;
    import com.jing.yao.component.dto.Query;
    import com.jing.yao.component.dto.QueryEnum;
    import com.jing.yao.component.entity.YaoBaseEntity;
    import com.jing.yao.component.mapper.YaoBaseMapper;
    import com.jing.yao.component.params.page.PageParam;
    import com.jing.yao.exception.BusinessException;
    import com.jing.yao.exception.BusinessExceptionBuilder;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.servlet.http.HttpServletResponse;
    import java.beans.IntrospectionException;
    import java.beans.PropertyDescriptor;
    import java.io.Serializable;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.*;
    
    import static com.jing.yao.component.constants.ResponseCode.ENTITY_NOT_FOUND;
    
    /**
     * 基础service
     * @author Yao
     * @since 2020-06-13
     */
    public interface YaoBaseService<P extends PageParam,T extends YaoBaseEntity> {
        /**
         * 获取直接操作数据库接口
         * @return
         */
        YaoBaseMapper<T> getMapper();
    
        /**
         * 根据id查询记录
         * @param id
         * @return
         */
        default T selectOneById(Long id) {
            return getMapper().selectById(id);
        }
    
        /**
         * 排序
         * @param pageParam
         * @return
         */
        default IPage<T> page(P pageParam) {
            Page<T> page = new Page<>();
            page.setCurrent(pageParam.getPageNumber());
            page.setSize(pageParam.getPageSize());
    
            //设置排序
            if(StringUtils.equals(BmsConstants.ASC,pageParam.getOrder()) && StringUtils.isNotBlank(pageParam.getOrder())){
                page.addOrder(OrderItem.asc(pageParam.getSort()));
            } else if(StringUtils.equals(BmsConstants.DESC,pageParam.getOrder()) && StringUtils.isNotBlank(pageParam.getOrder())){
                page.addOrder(OrderItem.desc(pageParam.getSort()));
            } else {
                page.addOrder(OrderItem.desc("update_time"));
            }
            TimeZone.setDefault(TimeZone.getTimeZone("GMT+8:00"));
            return getMapper().selectPage(page, getWrapper(pageParam));
        }
    
        /**
         * 抽象查询条件
         * @param param 查询条件
         * @return
         */
        default Wrapper<T> getWrapper(P param) {
            QueryWrapper<T> queryWrapper = new QueryWrapper<>();
    
            //条件的值
            Field[] fields = param.getClass().getDeclaredFields();
    
            Arrays.stream(fields).forEach(field -> {
                try {
                    boolean flag = false;
                    field.setAccessible(true);
                    if(field.get(param) instanceof String) {
                        flag = StringUtils.isNoneBlank((String)field.get(param));
                    } else {
                        flag = field.get(param) != null;
                    }
                    //判断是否是模糊查询
                    if(field.isAnnotationPresent(Query.class) && field.getAnnotation(Query.class).value() == QueryEnum.LIKE) {
                        queryWrapper.like(flag, com.baomidou.mybatisplus.core.toolkit.StringUtils.camelToUnderline(field.getName()), field.get(param));
                    } else {
                        queryWrapper.eq(flag, com.baomidou.mybatisplus.core.toolkit.StringUtils.camelToUnderline(field.getName()), field.get(param));
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
    
            return queryWrapper;
        }
    
        /**
         * 操作前处理
         * @param entity 前端传递的对象
         * @param operationEnum 操作类型
         * @throws BusinessException 阻止程序继续执行或回滚事务
         */
        default void processBeforeOperation(T entity, BaseOperationEnum operationEnum) throws BusinessException{
        }
    
        /**
         * 操作后续处理
         * @param entity
         * @param operationEnum 操作类型
         * @throws BusinessException  阻止程序继续执行或回滚事务
         */
        default void processAfterOperation(T entity, BaseOperationEnum operationEnum) throws BusinessException {
        }
    
        /**
         * 插入数据
         * @param entity
         * @throws BusinessException 业务异常
         * @return
         */
        @Transactional(rollbackFor = Exception.class)
        default boolean insert(T entity) throws BusinessException {
            //保存前处理
            processBeforeOperation(entity, BaseOperationEnum.INSERT);
            checkUniqueField(entity);
            Integer result = getMapper().insert(entity);
            processAfterOperation(entity, BaseOperationEnum.INSERT);
            return result != null && result >= 1;
        }
    
        /**
         * 校验唯一
         * @param entity
         */
        default void checkUniqueField(T entity) {
            //获取所有属性
            Field[] fields = entity.getClass().getDeclaredFields();
    
            //判断单一索引
            for (Field field : fields) {
                if (field.isAnnotationPresent(Unique.class)) {
                    Unique unique = field.getDeclaredAnnotation(Unique.class);
                    QueryWrapper<T> wrapper = Wrappers.query();
                    Integer integer = 0;
                    try {
                        Object value = getFieldValue(entity, field);
                        if (entity.getId() != null) {
                            wrapper.ne("id", entity.getId());
                        }
                        wrapper.eq(unique.column(), value);
                        integer = getMapper().selectCount(wrapper);
                    } catch (Exception e) {
                        continue;
                    }
                    if (integer >  0) {
                        throw BusinessExceptionBuilder.build(unique.code());
                    }
                }
            }
    
            //判断联合索引
            QueryWrapper<T> unionWrapper = Wrappers.query();
            if (entity.getId() != null) {
                unionWrapper.ne("id", entity.getId());
            }
            Integer integer = 0;
            boolean flag = false;
            for (Field field : fields) {
                if (field.isAnnotationPresent(UnionUnique.class)) {
                    UnionUnique unionUnique = field.getDeclaredAnnotation(UnionUnique.class);
                    try {
                        Object value = getFieldValue(entity, field);
                        unionWrapper.eq(unionUnique.column(), value);
                        flag = true;
                    } catch (Exception e) {
                        continue;
                    }
                }
            }
    
            if (flag) {
                integer = getMapper().selectCount(unionWrapper);
                if (integer >  0) {
                    throw BusinessExceptionBuilder.build(entity.getClass().getAnnotation(UnionUnique.class).code());
                }
            }
        }
    
        /**
         * 获取属性值
         * @param entity
         * @param field
         * @return
         * @throws IntrospectionException
         * @throws IllegalAccessException
         * @throws InvocationTargetException
         */
        default Object getFieldValue(T entity, Field field) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), entity.getClass());
            Method readMethod = propertyDescriptor.getReadMethod();
            return readMethod.invoke(entity);
        }
    
        /**
         * 编辑数据
         * @param entity
         * @throws BusinessException 业务异常
         * @return
         */
        @Transactional(rollbackFor = Exception.class)
        default boolean update(T entity) throws BusinessException {
            //编辑前处理
            processBeforeOperation(entity, BaseOperationEnum.UPDATE);
            Integer result = getMapper().updateById(entity);
            processAfterOperation(entity, BaseOperationEnum.UPDATE);
            return result != null && result >= 1;
        }
    
        /**
         * 根据指定字段查询对应的值
         * @param column
         * @param value
         * @return
         */
        default List<T> list(String column, String value) {
            QueryWrapper<T> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(column, value);
            return getMapper().selectList(queryWrapper);
        }
    
    
        /**
         * 根据指定条件查询对应的记录
         * @param wrapper
         * @return
         */
        default List<T> list(Wrapper<T> wrapper) {
            return getMapper().selectList(wrapper);
        }
    
        /**
         * 根据ID查询记录
         * @param id
         * @return
         */
        default T getById(Serializable id) {
            return getMapper().selectById(id);
        }
    
        /**
         * 删除
         * @param id
         * @return
         */
        @Transactional(rollbackFor = Exception.class)
        default boolean removeById(Serializable id) {
            T t = getById(id);
            if(t == null) {
                throw BusinessExceptionBuilder.build(ENTITY_NOT_FOUND);
            }
            processBeforeOperation(t,BaseOperationEnum.DELETE);
            boolean result = SqlHelper.retBool(getMapper().deleteById(id));
            processAfterOperation(t,BaseOperationEnum.DELETE);
            return result;
        }
    
        /**
         * 删除
         * @param lambdaQueryWrapper
         */
        @Transactional(rollbackFor = Exception.class)
        default void delete(LambdaQueryWrapper<T> lambdaQueryWrapper) {
            getMapper().delete(lambdaQueryWrapper);
        }
    
        /**
         * 批量删除
         * @param idList
         * @return
         */
        @Transactional(rollbackFor = Exception.class)
        default boolean removeByIds(Collection<? extends Serializable> idList) {
            return SqlHelper.retBool(getMapper().deleteBatchIds(idList));
        }
    
        /**
         * 查询所有
         * @return
         */
        default List<T> findAll() {
            return getMapper().selectList(Wrappers.emptyWrapper());
        }
    
        /**
         * @Description 导出
         * @author wangxiaoliang
         * @date 2020-07-15 14:11
         */
        default List<T> exportList(P param, HttpServletResponse response) {
            Wrapper<T> wrapper = getWrapper(param);
            List<T> managementList = getMapper().selectList(wrapper);
           return managementList;
        }
    
        /**
         * 根据指定字段更新值
         * @param id
         * @param column
         * @param value
         */
        default void updateColumn(Long id, String column, Object value) {
            Map<String,Object> params = new HashMap<>();
            params.put(column, value);
            getMapper().updateFieldsById(params, id);
        }
    
    }
    
    

    3、Mapper

    自定义YaoBaseMapper,项目中的Mapper只要实现该接口即可

    /**
     * mybatis基础接口
     * @author Yao
     * @since 2020-06-23
     */
    public interface YaoBaseMapper<T extends YaoBaseEntity> extends BaseMapper<T> {
    
        /**
         * 批量插入
         *
         * @param list
         * @return
         */
        int insertBatch(@Param("list") List<T> list);
    
    
        /**
         *  根据ID 更新指定字段
         * @param map 指定字段和值
         * @param id id
         * @return
         */
        int updateFieldsById(@Param("map") Map<String, Object> map, @Param("id") Long id);
    }
    

    数据库对应实体YaoBaseEntity,使用方式继承即可

    package com.jing.yao.component.entity;
    
    import com.baomidou.mybatisplus.annotation.*;
    
    import java.util.Date;
    
    /**
     * 基础数据库实体
     * @author Yao
     * @since 2020-06-13
     */
    public class YaoBaseEntity {
    
        @TableId(value = "id",type = IdType.AUTO)
        private Long id;
    
        /**
         * 创建人
         */
        @TableField(fill = FieldFill.INSERT)
        private String createBy;
    
        /**
         * 创建时间
         */
        @TableField(fill = FieldFill.INSERT)
        private Date createTime;
    
        /**
         * 修改人
         */
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private String updateBy;
    
        /**
         * 修改时间
         */
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Date updateTime;
    
        /**
         * 版本号
         * @Version:乐观锁,,需要添加mybatis plus插件optimisticLockerInterceptor
         */
        @TableField(fill = FieldFill.INSERT_UPDATE, update="%s+1")
        @Version
        private Integer version;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getCreateBy() {
            return createBy;
        }
    
        public void setCreateBy(String createBy) {
            this.createBy = createBy;
        }
    
        public Date getCreateTime() {
            return createTime;
        }
    
        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }
    
        public String getUpdateBy() {
            return updateBy;
        }
    
        public void setUpdateBy(String updateBy) {
            this.updateBy = updateBy;
        }
    
        public Date getUpdateTime() {
            return updateTime;
        }
    
        public void setUpdateTime(Date updateTime) {
            this.updateTime = updateTime;
        }
    
        public Integer getVersion() {
            return version;
        }
    
        public void setVersion(Integer version) {
            this.version = version;
        }
    }
    
    

    4、DTO

    自定义YaoBaseDTO,项目中所有跟前端交互的对象都需要转换为DTO(不必纠结DTO作为传输对象,返回给前端适不适合),DTO包含了字段校验、翻译等。项目中的DTO需要继承该类。该对象配合注解 @Formatter可实现字段的翻译
    YaoBaseDTO:

    package com.jing.yao.component.dto;
    import java.util.Date;
    
    /**
     * 基础传输对象
     * @author Yao
     * @since 2020-06-13
     */
    public class YaoBaseDTO {
        private Long id;
    
        /**
         * 创建人
         */
        private String createBy;
    
        /**
         * 创建时间
         */
        private Date createTime;
    
        /**
         * 修改人
         */
        private String updateBy;
    
        /**
         * 修改时间
         */
        private Date updateTime;
    
        /**
         * 版本号
         */
        private Integer version;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getCreateBy() {
            return createBy;
        }
    
        public void setCreateBy(String createBy) {
            this.createBy = createBy;
        }
    
        public Date getCreateTime() {
            return createTime;
        }
    
        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }
    
        public String getUpdateBy() {
            return updateBy;
        }
    
        public void setUpdateBy(String updateBy) {
            this.updateBy = updateBy;
        }
    
        public Date getUpdateTime() {
            return updateTime;
        }
    
        public void setUpdateTime(Date updateTime) {
            this.updateTime = updateTime;
        }
    
        public Integer getVersion() {
            return version;
        }
    
        public void setVersion(Integer version) {
            this.version = version;
        }
    }
    
    

    @Formatter

    package com.jing.yao.annotation;
    
    import java.lang.annotation.*;
    
    /**
     * 翻译
     * @author Yao
     * @since 2020-07-14
     */
    
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Formatter {
    
        /**
         * 对应的数据字典,用被注解字段的值取该字典中取值
         * @return
         */
        String dictCode() default "";
    
    
        /**
         * 字典翻译后,把翻译后的值赋值到该字段
         * @return
         */
        String targetField() default "";
    
        /**
         * 指定缓存Key,不用数据字典,直接从对应的可以取值
         * 但是对应Key在Redis的存储必须是Hash类型
         */
        String key() default "";
    }
    

    以上只是工作中使用的一部分,如果有问题或者建议欢迎各位老铁指出
    代码仓库地址链接

  • 相关阅读:
    AJAX 方式
    Qt程序设计——txt文本中获取字符串的问题
    二、Cocos2dx中Android部分的c++和java实现相互调用(高级篇)
    Android项目 手机安全卫士(代码最全,注释最详细)之五 splash动画效果
    Navigator 对象
    Dreamweaver中打开CodeSmith文件
    IOS开发:xcode5版本引发的问题
    Ubuntu 13.04 小米2S连接Eclipse真机调试
    Java面试题之四
    c++基础 之 面向对象特征一 : 继承
  • 原文地址:https://www.cnblogs.com/liruiloveparents/p/13466101.html
Copyright © 2011-2022 走看看