你还在手写crud吗,看完这篇文章,绝对赚了

开发 前端
我记得最早刚步入互联网行业的时候,当时按照 MVC 的思想和模型,每次开发新功能,会依次编写 dao、service、controller相关服务类,包括对应的 dto、entity、vo 等等实体类,如果有多张单表,也会重复的编写相似的代码,现在回想起来,感觉当时自己好像处于石器时代!

 [[352562]]

本文转载自微信公众号「Java极客技术」,作者鸭血粉丝 。转载本文请联系Java极客技术公众号。  

一、介绍

我记得最早刚步入互联网行业的时候,当时按照 MVC 的思想和模型,每次开发新功能,会依次编写 dao、service、controller相关服务类,包括对应的 dto、entity、vo 等等实体类,如果有多张单表,也会重复的编写相似的代码,现在回想起来,感觉当时自己好像处于石器时代!

实际上,当仔细的总结一下,对于任何一张单表的操作,基本都是围绕增(Create )、删(Delete )、改(Update )、查(Retrieve )四个方向进行数据操作,简称 CRUD!

他们除了表名和存储空间不一样,基本的 CRUD 思路基本都是一样的。

为了解决这些重复劳动的痛点,业界逐渐开源了一批代码生成器,目的也很简单,就是为了减少手工操作的繁琐,集中精力在业务开发上,提升开发效率。

而今天,我们所要介绍的也是代码生成器,很多初学者可能觉得代码生成器很高深。代码生成器其实是一个很简单的东西,一点都不高深。

当你看完本文的时候,你会完全掌握代码生成器的逻辑,甚至可以根据自己的项目情况,进行深度定制。

二、实现思路

下面我们就以SpringBoot项目为例,数据持久化操作采用Mybatis,数据库采用Mysql,编写一个自动生成增、删、改、查等基础功能的代码生成器,内容包括controller、service、dao、entity、dto、vo等信息。

实现思路如下:

第一步:获取表字段名称、类型、表注释等信息

第二步:基于 freemarker 模板引擎,编写相应的模板

第三步:根据对应的模板,生成相应的 java 代码

2.1、获取表结构

首先我们创建一张test_db表,脚本如下:

  1. CREATE TABLE test_db ( 
  2.   id bigint(20) unsigned NOT NULL COMMENT '主键ID'
  3.   name varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名称'
  4.   is_delete tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除 1:已删除;0:未删除'
  5.   create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
  6.   update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
  7.   PRIMARY KEY (id), 
  8.   KEY idx_create_time (create_time) USING BTREE 
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试表'

表创建完成之后,基于test_db表,我们查询对应的表结果字段名称、类型、备注信息,这些关键信息将用于后续进行代码生成器所使用!

  1. # 获取对应表结构 
  2. SELECT column_name, data_type, column_comment FROM information_schema.columns WHERE table_schema = 'yjgj_base' AND table_name = 'test_db' 

 

同时,获取对应表注释,用于生成备注信息!

  1. # 获取对应表注释 
  2. SELECT TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'yjgj_base' AND table_name = 'test_db' 

 

2.2、编写模板

编写mapper.ftl模板,涵盖新增、修改、删除、查询等信息

  1. <?xml version="1.0" encoding="UTF-8" ?> 
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > 
  3. <mapper namespace="${daoPackageName}.${daoName}"
  4.  
  5.  <!--BaseResultMap--> 
  6.  <resultMap id="BaseResultMap" type="${entityPackageName}.${entityName}"
  7.         <#list columns as pro> 
  8.             <#if pro.proName == primaryId> 
  9.     <id column="${primaryId}" property="${primaryId}" jdbcType="${pro.fieldType}"/> 
  10.             <#else
  11.     <result column="${pro.fieldName}" property="${pro.proName}" jdbcType="${pro.fieldType}"/> 
  12.             </#if> 
  13.         </#list> 
  14.  </resultMap> 
  15.  
  16.  <!--Base_Column_List--> 
  17.  <sql id="Base_Column_List"
  18.         <#list columns as pro> 
  19.             <#if pro_index == 0>${pro.fieldName}<#else>,${pro.fieldName}</#if> 
  20.         </#list> 
  21.  </sql> 
  22.  
  23.  <!--批量插入--> 
  24.  <insert id="insertList" parameterType="java.util.List"
  25.   insert into ${tableName} ( 
  26.         <#list columns as pro> 
  27.             <#if pro_index == 0>${pro.fieldName},<#elseif pro_index == 1>${pro.fieldName}<#else>,${pro.fieldName}</#if> 
  28.         </#list> 
  29.   ) 
  30.   values 
  31.   <foreach collection ="list" item="obj" separator =","
  32.    <trim prefix=" (" suffix=")" suffixOverrides=","
  33.                 <#list columns as pro> 
  34.                     ${r"#{obj." + pro.proName + r"}"}, 
  35.                 </#list> 
  36.    </trim> 
  37.   </foreach > 
  38.  </insert
  39.  
  40.  <!--按需新增--> 
  41.  <insert id="insertPrimaryKeySelective" parameterType="${entityPackageName}.${entityName}"
  42.   insert into ${tableName} 
  43.   <trim prefix="(" suffix=")" suffixOverrides=","
  44.             <#list columns as pro> 
  45.     <if test="${pro.proName} != null"
  46.                     ${pro.fieldName}, 
  47.     </if> 
  48.             </#list> 
  49.   </trim> 
  50.   <trim prefix="values (" suffix=")" suffixOverrides=","
  51.             <#list columns as pro> 
  52.     <if test="${pro.proName} != null"
  53.                     ${r"#{" + pro.proName + r",jdbcType=" + pro.fieldType +r"}"}, 
  54.     </if> 
  55.             </#list> 
  56.   </trim> 
  57.  </insert
  58.  
  59.  <!-- 按需修改--> 
  60.  <update id="updatePrimaryKeySelective" parameterType="${entityPackageName}.${entityName}"
  61.   update ${tableName} 
  62.   <set
  63.             <#list columns as pro> 
  64.                 <#if pro.fieldName != primaryId && pro.fieldName != primaryId> 
  65.      <if test="${pro.proName} != null"
  66.                         ${pro.fieldName} = ${r"#{" + pro.proName + r",jdbcType=" + pro.fieldType +r"}"}, 
  67.      </if> 
  68.                 </#if> 
  69.             </#list> 
  70.   </set
  71.   where ${primaryId} = ${r"#{" + "${primaryId}" + r",jdbcType=BIGINT}"
  72.  </update
  73.  
  74.  <!-- 按需批量修改--> 
  75.  <update id="updateBatchByIds" parameterType="java.util.List"
  76.   update ${tableName} 
  77.   <trim prefix="set" suffixOverrides=","
  78.             <#list columns as pro> 
  79.                 <#if pro.fieldName != primaryId && pro.fieldName != primaryId> 
  80.      <trim prefix="${pro.fieldName}=case" suffix="end,"
  81.       <foreach collection="list" item="obj" index="index"
  82.        <if test="obj.${pro.proName} != null"
  83.         when id = ${r"#{" + "obj.id" + r"}"
  84.         then  ${r"#{obj." + pro.proName + r",jdbcType=" + pro.fieldType +r"}"
  85.        </if> 
  86.       </foreach> 
  87.      </trim> 
  88.                 </#if> 
  89.             </#list> 
  90.   </trim> 
  91.   where 
  92.   <foreach collection="list" separator="or" item="obj" index="index" > 
  93.    id = ${r"#{" + "obj.id" + r"}"
  94.   </foreach> 
  95.  </update
  96.  
  97.  <!-- 删除--> 
  98.  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long"
  99.   delete from ${tableName} 
  100.   where ${primaryId} = ${r"#{" + "${primaryId}" + r",jdbcType=BIGINT}"
  101.  </delete
  102.  
  103.  <!-- 查询详情 --> 
  104.  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long"
  105.   select 
  106.   <include refid="Base_Column_List"/> 
  107.   from ${tableName} 
  108.   where ${primaryId} = ${r"#{" + "${primaryId}" + r",jdbcType=BIGINT}"
  109.  </select
  110.  
  111.  <!-- 按需查询 --> 
  112.  <select id="selectByPrimaryKeySelective" resultMap="BaseResultMap" parameterType="${entityPackageName}.${entityName}"
  113.   select 
  114.   <include refid="Base_Column_List"/> 
  115.   from ${tableName} 
  116.  </select
  117.  
  118.  <!-- 批量查询--> 
  119.  <select id="selectByIds" resultMap="BaseResultMap" parameterType="java.util.List"
  120.   select 
  121.   <include refid="Base_Column_List"/> 
  122.   from ${tableName} 
  123.   <where
  124.    <if test="ids != null"
  125.     and ${primaryId} in 
  126.     <foreach item="item" index="index" collection="ids" open="(" separator="," close=")"
  127.                     ${r"#{" + "item" + r"}"
  128.     </foreach> 
  129.    </if> 
  130.   </where
  131.  </select
  132.  
  133.  <!-- 根据条件查询 --> 
  134.  <select id="selectByMap" resultMap="BaseResultMap" parameterType="java.util.Map"
  135.   select 
  136.   <include refid="Base_Column_List"/> 
  137.   from ${tableName} 
  138.  </select
  139.  
  140.  <!-- 查询${entityName}总和 --> 
  141.  <select id="countPage" resultType="int" parameterType="${dtoPackageName}.${dtoName}"
  142.   select count(${primaryId}) 
  143.   from ${tableName} 
  144.  </select
  145.  
  146.  <!-- 查询${entityName}列表 --> 
  147.  <select id="selectPage" resultMap="BaseResultMap" parameterType="${dtoPackageName}.${dtoName}"
  148.   select 
  149.   <include refid="Base_Column_List"/> 
  150.   from ${tableName} 
  151.   limit ${r"#{" + "start,jdbcType=INTEGER" + r"}"},${r"#{" + "end,jdbcType=INTEGER" + r"}"
  152.  </select
  153.  
  154. </mapper> 

编写dao.ftl数据访问模板

  1. package ${daoPackageName}; 
  2.  
  3. import com.example.generator.core.BaseMapper; 
  4. import java.util.List; 
  5. import ${entityPackageName}.${entityName}; 
  6. import ${dtoPackageName}.${dtoName}; 
  7.  
  8. /** 
  9. * @ClassName: ${daoName} 
  10. * @Description: 数据访问接口 
  11. * @author ${authorName} 
  12. * @date ${currentTime} 
  13. */ 
  14. public interface ${daoName} extends BaseMapper<${entityName}>{ 
  15.  
  16.  int countPage(${dtoName} ${dtoName?uncap_first}); 
  17.  
  18.  List<${entityName}> selectPage(${dtoName} ${dtoName?uncap_first}); 

编写service.ftl服务接口模板

  1. package ${servicePackageName}; 
  2.  
  3. import com.example.generator.core.BaseService; 
  4. import com.example.generator.common.Pager; 
  5. import ${voPackageName}.${voName}; 
  6. import ${dtoPackageName}.${dtoName}; 
  7. import ${entityPackageName}.${entityName}; 
  8.  
  9. /** 
  10.  * 
  11.  * @ClassName: ${serviceName} 
  12.  * @Description: ${entityName}业务访问接口 
  13.  * @author ${authorName} 
  14.  * @date ${currentTime} 
  15.  * 
  16.  */ 
  17. public interface ${serviceName} extends BaseService<${entityName}> { 
  18.  
  19.  /** 
  20.   * 分页列表查询 
  21.   * @param request 
  22.   */ 
  23.  Pager<${voName}> getPage(${dtoName} request); 

编写serviceImpl.ftl服务实现类模板

  1. package ${serviceImplPackageName}; 
  2.  
  3. import com.example.generator.common.Pager; 
  4. import com.example.generator.core.BaseServiceImpl; 
  5. import com.example.generator.test.service.TestEntityService; 
  6. import org.springframework.beans.BeanUtils; 
  7. import org.springframework.stereotype.Service; 
  8. import org.springframework.util.CollectionUtils; 
  9. import org.slf4j.Logger; 
  10. import org.slf4j.LoggerFactory; 
  11.  
  12. import java.util.ArrayList; 
  13. import java.util.List; 
  14.  
  15.  
  16. import ${daoPackageName}.${daoName}; 
  17. import ${entityPackageName}.${entityName}; 
  18. import ${dtoPackageName}.${dtoName}; 
  19. import ${voPackageName}.${voName}; 
  20.  
  21.  
  22. @Service 
  23. public class ${serviceImplName} extends BaseServiceImpl<${daoName}, ${entityName}> implements ${serviceName} { 
  24.  
  25.  private static final Logger log = LoggerFactory.getLogger(${serviceImplName}.class); 
  26.  
  27.  /** 
  28.   * 分页列表查询 
  29.   * @param request 
  30.   */ 
  31.  public Pager<${voName}> getPage(${dtoName} request) { 
  32.   List<${voName}> resultList = new ArrayList(); 
  33.   int count = super.baseMapper.countPage(request); 
  34.   List<${entityName}> dbList = count > 0 ? super.baseMapper.selectPage(request) : new ArrayList<>(); 
  35.   if(!CollectionUtils.isEmpty(dbList)){ 
  36.    dbList.forEach(source->{ 
  37.     ${voName} target = new ${voName}(); 
  38.     BeanUtils.copyProperties(source, target); 
  39.     resultList.add(target); 
  40.    }); 
  41.   } 
  42.   return new Pager(request.getCurrPage(), request.getPageSize(), count, resultList); 
  43.  } 

编写controller.ftl控制层模板

  1. package ${controllerPackageName}; 
  2.  
  3. import com.example.generator.common.IdRequest; 
  4. import com.example.generator.common.Pager; 
  5. import org.springframework.beans.BeanUtils; 
  6. import org.springframework.beans.factory.annotation.Autowired; 
  7. import org.springframework.web.bind.annotation.PostMapping; 
  8. import org.springframework.web.bind.annotation.RequestBody; 
  9. import org.springframework.web.bind.annotation.RequestMapping; 
  10. import org.springframework.web.bind.annotation.RestController; 
  11. import java.util.Objects; 
  12.  
  13. import ${servicePackageName}.${serviceName}; 
  14. import ${entityPackageName}.${entityName}; 
  15. import ${dtoPackageName}.${dtoName}; 
  16. import ${voPackageName}.${voName}; 
  17.  
  18. /** 
  19.  * 
  20.  * @ClassName: ${controllerName} 
  21.  * @Description: 外部访问接口 
  22.  * @author ${authorName} 
  23.  * @date ${currentTime} 
  24.  * 
  25.  */ 
  26. @RestController 
  27. @RequestMapping("/${entityName?uncap_first}"
  28. public class ${controllerName} { 
  29.  
  30.  @Autowired 
  31.  private ${serviceName} ${serviceName?uncap_first}; 
  32.  
  33.  /** 
  34.   * 分页列表查询 
  35.   * @param request 
  36.   */ 
  37.  @PostMapping(value = "/getPage"
  38.  public Pager<${voName}> getPage(@RequestBody ${dtoName} request){ 
  39.   return ${serviceName?uncap_first}.getPage(request); 
  40.  } 
  41.  
  42.  /** 
  43.   * 查询详情 
  44.   * @param request 
  45.   */ 
  46.  @PostMapping(value = "/getDetail"
  47.  public ${voName} getDetail(@RequestBody IdRequest request){ 
  48.   ${entityName} source = ${serviceName?uncap_first}.selectById(request.getId()); 
  49.   if(Objects.nonNull(source)){ 
  50.    ${voName} result = new ${voName}(); 
  51.    BeanUtils.copyProperties(source, result); 
  52.    return result; 
  53.   } 
  54.   return null
  55.  } 
  56.  
  57.  /** 
  58.   * 新增操作 
  59.   * @param request 
  60.   */ 
  61.  @PostMapping(value = "/save"
  62.  public void save(${dtoName} request){ 
  63.   ${entityName} entity = new ${entityName}(); 
  64.   BeanUtils.copyProperties(request, entity); 
  65.   ${serviceName?uncap_first}.insert(entity); 
  66.  } 
  67.  
  68.  /** 
  69.   * 编辑操作 
  70.   * @param request 
  71.   */ 
  72.  @PostMapping(value = "/edit"
  73.  public void edit(${dtoName} request){ 
  74.   ${entityName} entity = new ${entityName}(); 
  75.   BeanUtils.copyProperties(request, entity); 
  76.   ${serviceName?uncap_first}.updateById(entity); 
  77.  } 
  78.  
  79.  /** 
  80.   * 删除操作 
  81.   * @param request 
  82.   */ 
  83.  @PostMapping(value = "/delete"
  84.  public void delete(IdRequest request){ 
  85.   ${serviceName?uncap_first}.deleteById(request.getId()); 
  86.  } 

编写entity.ftl实体类模板

  1. package ${entityPackageName}; 
  2.  
  3. import java.io.Serializable
  4. import java.math.BigDecimal; 
  5. import java.util.Date
  6.  
  7. /** 
  8.  * 
  9.  * @ClassName: ${entityName} 
  10.  * @Description: ${tableDes!}实体类 
  11.  * @author ${authorName} 
  12.  * @date ${currentTime} 
  13.  * 
  14.  */ 
  15. public class ${entityName} implements Serializable { 
  16.  
  17.  private static final long serialVersionUID = 1L; 
  18.   
  19.  <#--属性遍历--> 
  20.  <#list columns as pro> 
  21.  <#--<#if pro.proName != primaryId 
  22.  && pro.proName != 'remarks' 
  23.  && pro.proName != 'createBy' 
  24.  && pro.proName != 'createDate' 
  25.  && pro.proName != 'updateBy' 
  26.  && pro.proName != 'updateDate' 
  27.  && pro.proName != 'delFlag' 
  28.  && pro.proName != 'currentUser' 
  29.  && pro.proName != 'page' 
  30.  && pro.proName != 'sqlMap' 
  31.  && pro.proName != 'isNewRecord' 
  32.  ></#if>--> 
  33.  /** 
  34.   * ${pro.proDes!} 
  35.   */ 
  36.  private ${pro.proType} ${pro.proName}; 
  37.  </#list> 
  38.  
  39.  <#--属性get||set方法--> 
  40.  <#list columns as pro> 
  41.  public ${pro.proType} get${pro.proName?cap_first}() { 
  42.   return this.${pro.proName}; 
  43.  } 
  44.  
  45.  public ${entityName} set${pro.proName?cap_first}(${pro.proType} ${pro.proName}) { 
  46.   this.${pro.proName} = ${pro.proName}; 
  47.   return this; 
  48.  } 
  49.  </#list> 

编写dto.ftl实体类模板

  1. package ${dtoPackageName}; 
  2.  
  3. import com.example.generator.core.BaseDTO; 
  4. import java.io.Serializable
  5.  
  6. /** 
  7.  * @ClassName: ${dtoName} 
  8.  * @Description: 请求实体类 
  9.  * @author ${authorName} 
  10.  * @date ${currentTime} 
  11.  * 
  12.  */ 
  13. public class ${dtoName} extends BaseDTO { 
  14.  

编写vo.ftl视图实体类模板

  1. package ${voPackageName}; 
  2.  
  3. import java.io.Serializable
  4.  
  5. /** 
  6.  * @ClassName: ${voName} 
  7.  * @Description: 返回视图实体类 
  8.  * @author ${authorName} 
  9.  * @date ${currentTime} 
  10.  * 
  11.  */ 
  12. public class ${voName} implements Serializable { 
  13.  
  14.  private static final long serialVersionUID = 1L; 

可能细心的网友已经看到了,在模板中我们用到了BaseMapper、BaseService、BaseServiceImpl等等服务类。

之所以有这三个类,是因为在模板中,我们有大量的相同的方法名包括逻辑也相似,除了所在实体类不一样以外,其他都一样,因此我们可以借助泛型类来将这些服务抽成公共的部分。

BaseMapper,主要负责将dao层的公共方法抽出来

  1. package com.example.generator.core; 
  2.  
  3. import org.apache.ibatis.annotations.Param; 
  4.  
  5. import java.io.Serializable
  6. import java.util.List; 
  7. import java.util.Map; 
  8.  
  9. /** 
  10.  * @author pzblog 
  11.  * @Description 
  12.  * @since 2020-11-11 
  13.  */ 
  14. public interface BaseMapper<T> { 
  15.  
  16.     /** 
  17.      * 批量插入 
  18.      * @param list 
  19.      * @return 
  20.      */ 
  21.     int insertList(@Param("list") List<T> list); 
  22.  
  23.     /** 
  24.      * 按需插入一条记录 
  25.      * @param entity 
  26.      * @return 
  27.      */ 
  28.     int insertPrimaryKeySelective(T entity); 
  29.  
  30.     /** 
  31.      * 按需修改一条记录(通过主键ID) 
  32.      * @return 
  33.      */ 
  34.     int updatePrimaryKeySelective(T entity); 
  35.  
  36.     /** 
  37.      * 批量按需修改记录(通过主键ID) 
  38.      * @param list 
  39.      * @return 
  40.      */ 
  41.     int updateBatchByIds(@Param("list") List<T> list); 
  42.  
  43.     /** 
  44.      * 根据ID删除 
  45.      * @param id 主键ID 
  46.      * @return 
  47.      */ 
  48.     int deleteByPrimaryKey(Serializable id); 
  49.  
  50.     /** 
  51.      * 根据ID查询 
  52.      * @param id 主键ID 
  53.      * @return 
  54.      */ 
  55.     T selectByPrimaryKey(Serializable id); 
  56.  
  57.     /** 
  58.      * 按需查询 
  59.      * @param entity 
  60.      * @return 
  61.      */ 
  62.     List<T> selectByPrimaryKeySelective(T entity); 
  63.  
  64.     /** 
  65.      * 批量查询 
  66.      * @param ids 主键ID集合 
  67.      * @return 
  68.      */ 
  69.     List<T> selectByIds(@Param("ids") List<? extends Serializable> ids); 
  70.  
  71.     /** 
  72.      * 查询(根据 columnMap 条件) 
  73.      * @param columnMap 表字段 map 对象 
  74.      * @return 
  75.      */ 
  76.     List<T> selectByMap(Map<String, Object> columnMap); 

BaseService,主要负责将service层的公共方法抽出来

  1. package com.example.generator.core; 
  2.  
  3. import java.io.Serializable
  4. import java.util.List; 
  5. import java.util.Map; 
  6.  
  7. /** 
  8.  * @author pzblog 
  9.  * @Description 服务类 
  10.  * @since 2020-11-11 
  11.  */ 
  12. public interface BaseService<T> { 
  13.  
  14.     /** 
  15.      * 新增 
  16.      * @param entity 
  17.      * @return boolean 
  18.      */ 
  19.     boolean insert(T entity); 
  20.  
  21.     /** 
  22.      * 批量新增 
  23.      * @param list 
  24.      * @return boolean 
  25.      */ 
  26.     boolean insertList(List<T> list); 
  27.  
  28.     /** 
  29.      * 通过ID修改记录(如果想全部更新,只需保证字段都不为NULL) 
  30.      * @param entity 
  31.      * @return boolean 
  32.      */ 
  33.     boolean updateById(T entity); 
  34.  
  35.     /** 
  36.      * 通过ID批量修改记录(如果想全部更新,只需保证字段都不为NULL) 
  37.      * @param list 
  38.      * @return boolean 
  39.      */ 
  40.     boolean updateBatchByIds(List<T> list); 
  41.  
  42.     /** 
  43.      * 根据ID删除 
  44.      * @param id 主键ID 
  45.      * @return boolean 
  46.      */ 
  47.     boolean deleteById(Serializable id); 
  48.  
  49.     /** 
  50.      * 根据ID查询 
  51.      * @param id 主键ID 
  52.      * @return 
  53.      */ 
  54.     T selectById(Serializable id); 
  55.  
  56.     /** 
  57.      * 按需查询 
  58.      * @param entity 
  59.      * @return 
  60.      */ 
  61.     List<T> selectByPrimaryKeySelective(T entity); 
  62.  
  63.     /** 
  64.      * 批量查询 
  65.      * @param ids 
  66.      * @return 
  67.      */ 
  68.     List<T> selectByIds(List<? extends Serializable> ids); 
  69.  
  70.     /** 
  71.      * 根据条件查询 
  72.      * @param columnMap 
  73.      * @return 
  74.      */ 
  75.     List<T> selectByMap(Map<String, Object> columnMap); 
  76.  

BaseServiceImpl,service层的公共方法具体实现类

  1. package com.example.generator.core; 
  2.  
  3. import org.springframework.beans.factory.annotation.Autowired; 
  4. import org.springframework.transaction.annotation.Transactional; 
  5.  
  6. import java.io.Serializable
  7. import java.util.List; 
  8. import java.util.Map; 
  9.  
  10. /** 
  11.  * @author pzblog 
  12.  * @Description 实现类( 泛型说明:M 是 mapper 对象,T 是实体) 
  13.  * @since 2020-11-11 
  14.  */ 
  15. public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements BaseService<T>{ 
  16.  
  17.     @Autowired 
  18.     protected M baseMapper; 
  19.  
  20.     /** 
  21.      * 新增 
  22.      * @param entity 
  23.      * @return boolean 
  24.      */ 
  25.     @Override 
  26.     @Transactional(rollbackFor = {Exception.class}) 
  27.     public boolean insert(T entity){ 
  28.         return returnBool(baseMapper.insertPrimaryKeySelective(entity)); 
  29.     } 
  30.  
  31.     /** 
  32.      * 批量新增 
  33.      * @param list 
  34.      * @return boolean 
  35.      */ 
  36.     @Override 
  37.     @Transactional(rollbackFor = {Exception.class}) 
  38.     public boolean insertList(List<T> list){ 
  39.         return returnBool(baseMapper.insertList(list)); 
  40.     } 
  41.  
  42.     /** 
  43.      * 通过ID修改记录(如果想全部更新,只需保证字段都不为NULL) 
  44.      * @param entity 
  45.      * @return boolean 
  46.      */ 
  47.     @Override 
  48.     @Transactional(rollbackFor = {Exception.class}) 
  49.     public boolean updateById(T entity){ 
  50.         return returnBool(baseMapper.updatePrimaryKeySelective(entity)); 
  51.     } 
  52.  
  53.     /** 
  54.      * 通过ID批量修改记录(如果想全部更新,只需保证字段都不为NULL) 
  55.      * @param list 
  56.      * @return boolean 
  57.      */ 
  58.     @Override 
  59.     @Transactional(rollbackFor = {Exception.class}) 
  60.     public boolean updateBatchByIds(List<T> list){ 
  61.         return returnBool(baseMapper.updateBatchByIds(list)); 
  62.     } 
  63.  
  64.     /** 
  65.      * 根据ID删除 
  66.      * @param id 主键ID 
  67.      * @return boolean 
  68.      */ 
  69.     @Override 
  70.     @Transactional(rollbackFor = {Exception.class}) 
  71.     public boolean deleteById(Serializable id){ 
  72.         return returnBool(baseMapper.deleteByPrimaryKey(id)); 
  73.     } 
  74.  
  75.     /** 
  76.      * 根据ID查询 
  77.      * @param id 主键ID 
  78.      * @return 
  79.      */ 
  80.     @Override 
  81.     public T selectById(Serializable id){ 
  82.         return baseMapper.selectByPrimaryKey(id); 
  83.     } 
  84.  
  85.     /** 
  86.      * 按需查询 
  87.      * @param entity 
  88.      * @return 
  89.      */ 
  90.     @Override 
  91.     public List<T> selectByPrimaryKeySelective(T entity){ 
  92.         return baseMapper.selectByPrimaryKeySelective(entity); 
  93.     } 
  94.  
  95.     /** 
  96.      * 批量查询 
  97.      * @param ids 
  98.      * @return 
  99.      */ 
  100.     @Override 
  101.     public List<T> selectByIds(List<? extends Serializable> ids){ 
  102.         return baseMapper.selectByIds(ids); 
  103.     } 
  104.  
  105.     /** 
  106.      * 根据条件查询 
  107.      * @param columnMap 
  108.      * @return 
  109.      */ 
  110.     @Override 
  111.     public List<T> selectByMap(Map<String, Object> columnMap){ 
  112.         return baseMapper.selectByMap(columnMap); 
  113.     } 
  114.  
  115.     /** 
  116.      * 判断数据库操作是否成功 
  117.      * @param result 数据库操作返回影响条数 
  118.      * @return boolean 
  119.      */ 
  120.     protected boolean returnBool(Integer result) { 
  121.         return null != result && result >= 1; 
  122.     } 
  123.  

在此,还封装来其他的类,例如 dto 公共类BaseDTO,分页类Pager,还有 id 请求类IdRequest。

BaseDTO公共类

  1. public class BaseDTO implements Serializable { 
  2.  
  3.     /** 
  4.      * 请求token 
  5.      */ 
  6.     private String token; 
  7.  
  8.     /** 
  9.      * 当前页数 
  10.      */ 
  11.     private Integer currPage = 1; 
  12.  
  13.     /** 
  14.      * 每页记录数 
  15.      */ 
  16.     private Integer pageSize = 20; 
  17.  
  18.     /** 
  19.      * 分页参数(第几行) 
  20.      */ 
  21.     private Integer start; 
  22.  
  23.     /** 
  24.      * 分页参数(行数) 
  25.      */ 
  26.     private Integer end
  27.  
  28.     /** 
  29.      * 登录人ID 
  30.      */ 
  31.     private String loginUserId; 
  32.  
  33.     /** 
  34.      * 登录人名称 
  35.      */ 
  36.     private String loginUserName; 
  37.  
  38.     public String getToken() { 
  39.         return token; 
  40.     } 
  41.  
  42.     public BaseDTO setToken(String token) { 
  43.         this.token = token; 
  44.         return this; 
  45.     } 
  46.  
  47.     public Integer getCurrPage() { 
  48.         return currPage; 
  49.     } 
  50.  
  51.     public BaseDTO setCurrPage(Integer currPage) { 
  52.         this.currPage = currPage; 
  53.         return this; 
  54.     } 
  55.  
  56.     public Integer getPageSize() { 
  57.         return pageSize; 
  58.     } 
  59.  
  60.     public BaseDTO setPageSize(Integer pageSize) { 
  61.         this.pageSize = pageSize; 
  62.         return this; 
  63.     } 
  64.  
  65.     public Integer getStart() { 
  66.         if (this.currPage != null && this.currPage > 0) { 
  67.             start = (currPage - 1) * getPageSize(); 
  68.             return start; 
  69.         } 
  70.         return start == null ? 0 : start; 
  71.     } 
  72.  
  73.     public BaseDTO setStart(Integer start) { 
  74.         this.start = start; 
  75.         return this; 
  76.     } 
  77.  
  78.     public Integer getEnd() { 
  79.         return getPageSize(); 
  80.     } 
  81.  
  82.     public BaseDTO setEnd(Integer end) { 
  83.         this.end = end
  84.         return this; 
  85.     } 
  86.  
  87.     public String getLoginUserId() { 
  88.         return loginUserId; 
  89.     } 
  90.  
  91.     public BaseDTO setLoginUserId(String loginUserId) { 
  92.         this.loginUserId = loginUserId; 
  93.         return this; 
  94.     } 
  95.  
  96.     public String getLoginUserName() { 
  97.         return loginUserName; 
  98.     } 
  99.  
  100.     public BaseDTO setLoginUserName(String loginUserName) { 
  101.         this.loginUserName = loginUserName; 
  102.         return this; 
  103.     } 
  104.  

Pager分页类

  1. public class Pager<T extends Serializable> implements Serializable { 
  2.  
  3.     private static final long serialVersionUID = -6557244954523041805L; 
  4.  
  5.     /** 
  6.      * 当前页数 
  7.      */ 
  8.     private int currPage; 
  9.  
  10.     /** 
  11.      * 每页记录数 
  12.      */ 
  13.     private int pageSize; 
  14.  
  15.     /** 
  16.      * 总页数 
  17.      */ 
  18.     private int totalPage; 
  19.  
  20.     /** 
  21.      * 总记录数 
  22.      */ 
  23.     private int totalCount; 
  24.  
  25.     /** 
  26.      * 列表数据 
  27.      */ 
  28.     private List<T> list; 
  29.  
  30.     public Pager(int currPage, int pageSize) { 
  31.         this.currPage = currPage; 
  32.         this.pageSize = pageSize; 
  33.     } 
  34.  
  35.     public Pager(int currPage, int pageSize, int totalCount, List<T> list) { 
  36.         this.currPage = currPage; 
  37.         this.pageSize = pageSize; 
  38.         this.totalPage = (int) Math.ceil((double) totalCount / pageSize);; 
  39.         this.totalCount = totalCount; 
  40.         this.list = list; 
  41.     } 
  42.  
  43.     public int getCurrPage() { 
  44.         return currPage; 
  45.     } 
  46.  
  47.     public Pager setCurrPage(int currPage) { 
  48.         this.currPage = currPage; 
  49.         return this; 
  50.     } 
  51.  
  52.     public int getPageSize() { 
  53.         return pageSize; 
  54.     } 
  55.  
  56.     public Pager setPageSize(int pageSize) { 
  57.         this.pageSize = pageSize; 
  58.         return this; 
  59.     } 
  60.  
  61.     public int getTotalPage() { 
  62.         return totalPage; 
  63.     } 
  64.  
  65.     public Pager setTotalPage(int totalPage) { 
  66.         this.totalPage = totalPage; 
  67.         return this; 
  68.     } 
  69.  
  70.     public int getTotalCount() { 
  71.         return totalCount; 
  72.     } 
  73.  
  74.     public Pager setTotalCount(int totalCount) { 
  75.         this.totalCount = totalCount; 
  76.         return this; 
  77.     } 
  78.  
  79.     public List<T> getList() { 
  80.         return list; 
  81.     } 
  82.  
  83.     public Pager setList(List<T> list) { 
  84.         this.list = list; 
  85.         return this; 
  86.     } 

IdRequest公共请求类

  1. public class IdRequest extends BaseDTO { 
  2.  
  3.     private Long id; 
  4.  
  5.     public Long getId() { 
  6.         return id; 
  7.     } 
  8.  
  9.     public IdRequest setId(Long id) { 
  10.         this.id = id; 
  11.         return this; 
  12.     } 

2.3、编写代码生成器

前两部分主要介绍的是如何获取对应的表结构,以及代码器运行之前的准备工作。

其实代码生成器,很简单,其实就是一个main方法,没有想象中的那么复杂。

处理思路也很简单,过程如下:

1、定义基本变量,例如包名路径、模块名、表名、转换后的实体类、以及数据库连接配置,我们可以将其写入配置文件

2、读取配置文件,封装对应的模板中定义的变量

3、根据对应的模板文件和变量,生成对应的java文件

2.3.1、创建配置文件,定义变量

小编我用的是application.properties配置文件来定义变量,这个没啥规定,你也可以自定义文件名,内容如下:

  1. #包前缀 
  2. packageNamePre=com.example.generator 
  3. #模块名称 
  4. moduleName=test 
  5. #表 
  6. tableName=test_db 
  7. #实体类名称 
  8. entityName=TestEntity 
  9. #主键ID 
  10. primaryId=id 
  11. #作者 
  12. authorName=pzblog 
  13. #数据库名称 
  14. databaseName=yjgj_base 
  15.  
  16. #数据库服务器IP地址 
  17. ipName=127.0.0.1 
  18. #数据库服务器端口 
  19. portName=3306 
  20. #用户名 
  21. userName=root 
  22. #密码 
  23. passWord=123456 
  24.  
  25. #文件输出路径,支持自定义输出路径,如果为空,默认取当前工程的src/main/java路径 
  26. outUrl= 

2.3.2、根据模板生成对应的java代码

首先,读取配置文件变量

  1. public class SystemConstant { 
  2.  
  3.     private static Properties properties = new Properties(); 
  4.  
  5.     static { 
  6.         try { 
  7.             // 加载上传文件设置参数:配置文件 
  8.             properties.load(SystemConstant.class.getClassLoader().getResourceAsStream("application.properties")); 
  9.         } catch (IOException e) { 
  10.             e.printStackTrace(); 
  11.         } 
  12.     } 
  13.  
  14.     public static final String tableName = properties.getProperty("tableName"); 
  15.     public static final String entityName = properties.getProperty("entityName"); 
  16.     public static final String packageNamePre = properties.getProperty("packageNamePre"); 
  17.     public static final String outUrl = properties.getProperty("outUrl"); 
  18.     public static final String databaseName = properties.getProperty("databaseName"); 
  19.     public static final String ipName = properties.getProperty("ipName"); 
  20.     public static final String portName = properties.getProperty("portName"); 
  21.     public static final String userName = properties.getProperty("userName"); 
  22.     public static final String passWord = properties.getProperty("passWord"); 
  23.     public static final String authorName = properties.getProperty("authorName"); 
  24.  
  25.     public static final String primaryId = properties.getProperty("primaryId"); 
  26.  
  27.     public static final String moduleName = properties.getProperty("moduleName"); 

然后,封装对应的模板中定义的变量

  1. public class CodeService { 
  2.  
  3.     public void generate(Map<String, Object> templateData) { 
  4.         //包前缀 
  5.         String packagePreAndModuleName = getPackagePreAndModuleName(templateData); 
  6.  
  7.         //支持对应实体插入在前面,需要带上%s 
  8.         templateData.put("entityPackageName", String.format(packagePreAndModuleName + ".entity"
  9.                 templateData.get("entityName").toString().toLowerCase())); 
  10.  
  11.         templateData.put("dtoPackageName", String.format(packagePreAndModuleName + ".dto"
  12.                 templateData.get("entityName").toString().toLowerCase())); 
  13.  
  14.         templateData.put("voPackageName", String.format(packagePreAndModuleName + ".vo"
  15.                 templateData.get("entityName").toString().toLowerCase())); 
  16.  
  17.         templateData.put("daoPackageName", String.format(packagePreAndModuleName + ".dao"
  18.                 templateData.get("entityName").toString().toLowerCase())); 
  19.  
  20.         templateData.put("mapperPackageName", packagePreAndModuleName + ".mapper"); 
  21.  
  22.  
  23.         templateData.put("servicePackageName", String.format(packagePreAndModuleName + ".service"
  24.                 templateData.get("entityName").toString().toLowerCase())); 
  25.  
  26.         templateData.put("serviceImplPackageName", String.format(packagePreAndModuleName + ".service.impl"
  27.                 templateData.get("entityName").toString().toLowerCase())); 
  28.  
  29.         templateData.put("controllerPackageName", String.format(packagePreAndModuleName + ".web"
  30.                 templateData.get("entityName").toString().toLowerCase())); 
  31.  
  32.         templateData.put("apiTestPackageName", String.format(packagePreAndModuleName + ".junit"
  33.                 templateData.get("entityName").toString().toLowerCase())); 
  34.  
  35.  
  36.         templateData.put("currentTime", new SimpleDateFormat("yyyy-MM-dd").format(new Date())); 
  37.  
  38.         //======================生成文件配置====================== 
  39.         try { 
  40.             // 生成Entity 
  41.             String entityName = String.format("%s", templateData.get("entityName").toString()); 
  42.             generateFile("entity.ftl", templateData, templateData.get("entityPackageName").toString(), entityName+".java"); 
  43.  
  44.             // 生成dto 
  45.             String dtoName = String.format("%sDTO", templateData.get("entityName").toString()); 
  46.             templateData.put("dtoName", dtoName); 
  47.             generateFile("dto.ftl", templateData, templateData.get("dtoPackageName").toString(), 
  48.                     dtoName + ".java"); 
  49.  
  50.             // 生成VO 
  51.             String voName = String.format("%sVO", templateData.get("entityName").toString()); 
  52.             templateData.put("voName", voName); 
  53.             generateFile("vo.ftl", templateData, templateData.get("voPackageName").toString(), 
  54.                     voName + ".java"); 
  55.  
  56.             // 生成DAO 
  57.             String daoName = String.format("%sDao", templateData.get("entityName").toString()); 
  58.             templateData.put("daoName", daoName); 
  59.             generateFile("dao.ftl", templateData, templateData.get("daoPackageName").toString(), 
  60.                     daoName + ".java"); 
  61.  
  62.             // 生成Mapper 
  63.             String mapperName = String.format("%sMapper", templateData.get("entityName").toString()); 
  64.             generateFile("mapper.ftl", templateData, templateData.get("mapperPackageName").toString(), 
  65.                     mapperName+".xml"); 
  66.  
  67.  
  68.             // 生成Service 
  69.             String serviceName = String.format("%sService", templateData.get("entityName").toString()); 
  70.             templateData.put("serviceName", serviceName); 
  71.             generateFile("service.ftl", templateData, templateData.get("servicePackageName").toString(), 
  72.                     serviceName + ".java"); 
  73.  
  74.             // 生成ServiceImpl 
  75.    String serviceImplName = String.format("%sServiceImpl", templateData.get("entityName").toString()); 
  76.    templateData.put("serviceImplName", serviceImplName); 
  77.    generateFile("serviceImpl.ftl", templateData, templateData.get("serviceImplPackageName").toString(), 
  78.                     serviceImplName + ".java"); 
  79.  
  80.             // 生成Controller 
  81.    String controllerName = String.format("%sController", templateData.get("entityName").toString()); 
  82.    templateData.put("controllerName", controllerName); 
  83.    generateFile("controller.ftl", templateData, templateData.get("controllerPackageName").toString(), 
  84.                     controllerName + ".java"); 
  85.  
  86. //   // 生成junit测试类 
  87. //            String apiTestName = String.format("%sApiTest", templateData.get("entityName").toString()); 
  88. //            templateData.put("apiTestName", apiTestName); 
  89. //            generateFile("test.ftl", templateData, templateData.get("apiTestPackageName").toString(), 
  90. //                    apiTestName + ".java"); 
  91.  
  92.         } catch (Exception e) { 
  93.             e.printStackTrace(); 
  94.         } 
  95.     } 
  96.  
  97.     /** 
  98.      * 生成文件 
  99.      * @param templateName 模板名称 
  100.      * @param templateData 参数名 
  101.      * @param packageName 包名 
  102.      * @param fileName 文件名 
  103.      */ 
  104.     public void generateFile(String templateName, Map<String, Object> templateData, String packageName, String fileName) { 
  105.         templateData.put("fileName", fileName); 
  106.  
  107.         DaseService dbService = new DaseService(templateData); 
  108.  
  109.         // 获取数据库参数 
  110.         if("entity.ftl".equals(templateName) || "mapper.ftl".equals(templateName)){ 
  111.             dbService.getAllColumns(templateData); 
  112.         } 
  113.         try { 
  114.             // 默认生成文件的路径 
  115.             FreeMakerUtil freeMakerUtil = new FreeMakerUtil(); 
  116.             freeMakerUtil.generateFile(templateName, templateData, packageName, fileName); 
  117.         } catch (Exception e) { 
  118.             e.printStackTrace(); 
  119.         } 
  120.     } 
  121.  
  122.     /** 
  123.      * 封装包名前缀 
  124.      * @return 
  125.      */ 
  126.     private String getPackagePreAndModuleName(Map<String, Object> templateData){ 
  127.         String packageNamePre = templateData.get("packageNamePre").toString(); 
  128.         String moduleName = templateData.get("moduleName").toString(); 
  129.         if(StringUtils.isNotBlank(moduleName)){ 
  130.             return packageNamePre + "." + moduleName; 
  131.         } 
  132.         return packageNamePre; 
  133.     } 
  134.  

接着,获取模板文件,并生成相应的模板文件

  1. public class FreeMakerUtil { 
  2.  
  3.  
  4.     /** 
  5.      * 根据Freemark模板,生成文件 
  6.      * @param templateName:模板名 
  7.      * @param root:数据原型 
  8.      * @throws Exception 
  9.      */ 
  10.     public void generateFile(String templateName, Map<String, Object> root, String packageName, String fileName) throws Exception { 
  11.         FileOutputStream fos=null
  12.         Writer out =null
  13.         try { 
  14.             // 通过一个文件输出流,就可以写到相应的文件中,此处用的是绝对路径 
  15.             String entityName = (String) root.get("entityName"); 
  16.             String fileFullName = String.format(fileName, entityName); 
  17.             packageName = String.format(packageName, entityName.toLowerCase()); 
  18.  
  19.             String fileStylePackageName = packageName.replaceAll("\\.""/"); 
  20.             File file = new File(root.get("outUrl").toString() + "/" + fileStylePackageName + "/" + fileFullName); 
  21.             if (!file.getParentFile().exists()) { 
  22.                 file.getParentFile().mkdirs(); 
  23.             } 
  24.             file.createNewFile(); 
  25.  
  26.             Template template = getTemplate(templateName); 
  27.             fos = new FileOutputStream(file); 
  28.             out = new OutputStreamWriter(fos); 
  29.             template.process(root, out); 
  30.             out.flush(); 
  31.         } catch (Exception e) { 
  32.             e.printStackTrace(); 
  33.         } finally { 
  34.             try { 
  35.                 if (fos != null){ 
  36.                     fos.close(); 
  37.                 } 
  38.                 if(out != null){ 
  39.                     out.close(); 
  40.                 } 
  41.             } catch (IOException e) { 
  42.                 e.printStackTrace(); 
  43.             } 
  44.         } 
  45.     } 
  46.  
  47.     /** 
  48.      * 
  49.      * 获取模板文件 
  50.      * 
  51.      * @param name 
  52.      * @return 
  53.      */ 
  54.     public Template getTemplate(String name) { 
  55.         try { 
  56.             Configuration cfg = new Configuration(Configuration.VERSION_2_3_23); 
  57.             cfg.setClassForTemplateLoading(this.getClass(), "/ftl"); 
  58.             Template template = cfg.getTemplate(name); 
  59.             return template; 
  60.         } catch (IOException e) { 
  61.             e.printStackTrace(); 
  62.         } 
  63.         return null
  64.     } 

最后,我们编写一个main方法,看看运行之后的效果

  1. public class GeneratorMain { 
  2.  
  3.     public static void main(String[] args) { 
  4.         System.out.println("生成代码start......"); 
  5.  
  6.         //获取页面或者配置文件的参数 
  7.         Map<String, Object> templateData = new HashMap<String, Object>(); 
  8.         templateData.put("tableName", SystemConstant.tableName); 
  9.         System.out.println("表名=="+ SystemConstant.tableName); 
  10.  
  11.         templateData.put("entityName", SystemConstant.entityName); 
  12.         System.out.println("实体类名称=="+ SystemConstant.entityName); 
  13.  
  14.         templateData.put("packageNamePre", SystemConstant.packageNamePre); 
  15.         System.out.println("包名前缀=="+ SystemConstant.packageNamePre); 
  16.  
  17.         //支持自定义输出路径 
  18.         if(StringUtils.isNotBlank(SystemConstant.outUrl)){ 
  19.             templateData.put("outUrl", SystemConstant.outUrl); 
  20.         } else { 
  21.             String path = GeneratorMain.class.getClassLoader().getResource("").getPath() + "../../src/main/java"
  22.             templateData.put("outUrl", path); 
  23.         } 
  24.         System.out.println("生成文件路径为=="+ templateData.get("outUrl")); 
  25.  
  26.         templateData.put("authorName", SystemConstant.authorName); 
  27.         System.out.println("以后代码出问题找=="+ SystemConstant.authorName); 
  28.  
  29.  
  30.         templateData.put("databaseName", SystemConstant.databaseName); 
  31.         templateData.put("ipName", SystemConstant.ipName); 
  32.         templateData.put("portName", SystemConstant.portName); 
  33.         templateData.put("userName", SystemConstant.userName); 
  34.         templateData.put("passWord", SystemConstant.passWord); 
  35.  
  36.         //主键ID 
  37.         templateData.put("primaryId", SystemConstant.primaryId); 
  38.  
  39.         //模块名称 
  40.         templateData.put("moduleName", SystemConstant.moduleName); 
  41.         CodeService dataService = new CodeService(); 
  42.  
  43.         try { 
  44.             //生成代码文件 
  45.             dataService.generate(templateData); 
  46.         } catch (Exception e) { 
  47.             e.printStackTrace(); 
  48.         } 
  49.  
  50.         System.out.println("生成代码end......"); 
  51.     } 

结果如下:

 

生成的 Controller 层代码如下

  1. /** 
  2.  * 
  3.  * @ClassName: TestEntityController 
  4.  * @Description: 外部访问接口 
  5.  * @author pzblog 
  6.  * @date 2020-11-16 
  7.  * 
  8.  */ 
  9. @RestController 
  10. @RequestMapping("/testEntity"
  11. public class TestEntityController { 
  12.  
  13.  @Autowired 
  14.  private TestEntityService testEntityService; 
  15.  
  16.  /** 
  17.   * 分页列表查询 
  18.   * @param request 
  19.   */ 
  20.  @PostMapping(value = "/getPage"
  21.  public Pager<TestEntityVO> getPage(@RequestBody TestEntityDTO request){ 
  22.   return testEntityService.getPage(request); 
  23.  } 
  24.  
  25.  /** 
  26.   * 查询详情 
  27.   * @param request 
  28.   */ 
  29.  @PostMapping(value = "/getDetail"
  30.  public TestEntityVO getDetail(@RequestBody IdRequest request){ 
  31.   TestEntity source = testEntityService.selectById(request.getId()); 
  32.   if(Objects.nonNull(source)){ 
  33.    TestEntityVO result = new TestEntityVO(); 
  34.    BeanUtils.copyProperties(source, result); 
  35.    return result; 
  36.   } 
  37.   return null
  38.  } 
  39.  
  40.  /** 
  41.   * 新增操作 
  42.   * @param request 
  43.   */ 
  44.  @PostMapping(value = "/save"
  45.  public void save(TestEntityDTO request){ 
  46.   TestEntity entity = new TestEntity(); 
  47.   BeanUtils.copyProperties(request, entity); 
  48.   testEntityService.insert(entity); 
  49.  } 
  50.  
  51.  /** 
  52.   * 编辑操作 
  53.   * @param request 
  54.   */ 
  55.  @PostMapping(value = "/edit"
  56.  public void edit(TestEntityDTO request){ 
  57.   TestEntity entity = new TestEntity(); 
  58.   BeanUtils.copyProperties(request, entity); 
  59.   testEntityService.updateById(entity); 
  60.  } 
  61.  
  62.  /** 
  63.   * 删除操作 
  64.   * @param request 
  65.   */ 
  66.  @PostMapping(value = "/delete"
  67.  public void delete(IdRequest request){ 
  68.   testEntityService.deleteById(request.getId()); 
  69.  } 

至此,一张单表的90%的基础工作量全部开发完毕!

三、总结

代码生成器,在实际的项目开发中应用非常的广,本文主要以freemaker模板引擎为基础,开发的一套全自动代码生成器,一张单表的CRUD,只需要5秒钟就可以完成!

最后多说一句,如果你是项目负责人,那么代码生成器会是一个比较好的提升项目开发效率的工具,希望能帮到各位!

 

责任编辑:武晓燕 来源: Java极客技术
相关推荐

2019-01-30 13:44:34

JVM内存服务器

2023-10-08 19:06:41

2019-07-10 15:15:23

JVM虚拟机Java

2021-04-27 07:59:11

内联汇编 C 语言 asm 关键字

2018-07-31 14:03:09

JVM内存数据

2017-03-10 21:04:04

Android适配

2017-03-07 15:35:26

Android适配 界面

2021-10-14 06:36:38

存储云存储本地存储

2022-02-18 06:56:18

Wi-Fi路由器局域网

2019-08-01 11:04:10

Linux磁盘I

2019-05-30 09:32:49

2019-11-28 18:36:00

华为MateBook

2017-06-01 18:55:44

2015-12-02 18:11:06

百度地图/地图软件

2023-09-22 07:52:16

HDMI 2.14K HDR游戏

2021-11-24 07:47:06

安全

2021-02-24 07:38:50

Redis

2017-08-09 15:07:08

大数据数据分析户画像

2021-04-16 16:37:23

SpringMVC源码配置

2020-07-09 10:21:03

网络排错TCPIP
点赞
收藏

51CTO技术栈公众号