Springboot + vue前后端分离后台管理系统(十一) -- 代码生成器调整

前言

之前在集成mybatis plus的时候有稍微写了下代码生成器的用法,现在这边稍微调整和优化一下,让后面生成基本的接口代码更加的方便,减少工作量啊,偷懒果然是爽啊。

实现

模板支持

mybatis plus的代码生成器是需要模板引擎的,默认使用的是velocity模板,项目里也已经引用了。

<!-- 模板引擎 -->
<dependency>
	<groupId>org.apache.velocity</groupId>
	<artifactId>velocity-engine-core</artifactId>
	<version>2.2</version>
</dependency>

当然也支持FreemarkerBeetl模板,看个人喜好,这边使用默认的。

自定义模板内容

可以看到mubatit-plus-generatortemplates下存放着三种模板。
.vmvelocity模板, .ftl.btl分别代表FreemarkerBeetl模板

在自己的项目下建立templates文件夹,把mubatit-plus-generator下的模板文件copy过来就可以自定义模板内容了。生成代码的时候会覆盖默认的模板,这边分别对controllerserviceserviceImpl进行编写

controller.java.vm

package ${package.Controller};


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson.JSONObject;
import com.ify.sampleAdmin.root.ResResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    #if(${restControllerStyle})
    #else
    import org.springframework.stereotype.Controller;
    #end
    #if(${superControllerClassPackage})
    import ${superControllerClassPackage};
    #end
import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};


/**
 * @description $!{cfg.description}
 *
 * @author ${author}
 * @since ${date}
 */
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@RequestMapping("${cfg.moduleName}")
#if(${swagger2})
@Api(tags = "${entity}Api(${table.comment})", value = "${table.comment}")
#end
#if(${kotlin})
class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end

#else
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end

    @Autowired
    private ${table.serviceName} ${table.entityPath}Service;

    @PostMapping(value = "/${table.entityPath}s")
    @ApiOperation(value = "新增", notes = "接口描述")
    @DynamicParameters(name = "save${entity}", properties = {
        #foreach($field in ${table.fields})
            @DynamicParameter(name = "${field.propertyName}", value = "${field.comment}", example = "", required = false, dataTypeClass = ${field.propertyType}.class),
        #end
    })
    public ResResult save${entity}(@RequestBody JSONObject param){
        return this.${table.entityPath}Service.save${entity}(param.toJavaObject(${entity}.class));
    }

    @PutMapping(value = "/${table.entityPath}s")
    @ApiOperation(value = "更新", notes = "接口描述")
    @DynamicParameters(name = "update${entity}", properties = {
    #foreach($field in ${table.fields})
            @DynamicParameter(name = "${field.propertyName}", value = "${field.comment}", example = "", required = false, dataTypeClass = ${field.propertyType}.class),
    #end
    })
    public ResResult update${entity}(@RequestBody JSONObject param){
        return this.${table.entityPath}Service.update${entity}(param.toJavaObject(${entity}.class));
    }

    @DeleteMapping(value = "/${table.entityPath}s/{id}")
    @ApiOperation(value = "删除(单条)", notes = "接口描述")
    public ResResult delete${entity}ById(@PathVariable("id") String id){
        return this.${table.entityPath}Service.deleteById(id);
    }

    @PostMapping(value = "/${table.entityPath}s/batch")
    @ApiOperation(value = "删除(批量)", notes = "接口描述")
    @DynamicParameters(name = "delete${entity}ByIds", properties = {
            @DynamicParameter(name = "ids", value = "id字符串", example = "id1,id2...", required = false, dataTypeClass = String.class),
    })
    public ResResult delete${entity}ByIds(@RequestBody JSONObject param){
        return this.${table.entityPath}Service.deleteBatch(param.getString("ids"));
    }

    @GetMapping(value = "/${table.entityPath}s/{id}")
    @ApiOperation(value = "查询(单条)", notes = "接口描述")
    public ResResult get${entity}(@PathVariable("id") String id){
        return this.${table.entityPath}Service.get${entity}ById(id);
    }

    @PostMapping(value = "/${table.entityPath}s/page")
    @ApiOperation(value = "分页查询", notes = "接口描述")
    @DynamicParameters(name = "find${entity}Page", properties = {
    #foreach($field in ${table.fields})
            @DynamicParameter(name = "${field.propertyName}", value = "${field.comment}", example = "", required = false, dataTypeClass = ${field.propertyType}.class),
    #end
            @DynamicParameter(name = "page", value = "分页对象", example = "{}", required = true, dataTypeClass = Page.class),
    })
    public ResResult find${entity}Page(@RequestBody JSONObject param){
        return this.${table.entityPath}Service.findPage(param.toJavaObject(${entity}.class));
    }
}

#end

这个文件主要生成controller代码,在基础接口上面增加swagger的注释文档,开发的时候看清空删减。

service.java.vm

package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ify.sampleAdmin.root.ResResult;

/**
 *
 * $!{table.comment} 服务类
 *
 *
 * @author ${author}
 * @since ${date}
 */
#if(${kotlin})
interface ${table.serviceName} : ${superServiceClass}<${entity}>
#else
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

    ResResult save${entity}(${entity} ${table.entityPath});

    ResResult update${entity}(${entity} ${table.entityPath});

    ResResult deleteById(String id);

    ResResult deleteBatch(String ids);

    ResResult get${entity}ById(String id);

    ResResult findPage(${entity} ${table.entityPath});
}
#end

serviceImpl.java.vm

package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.transaction.annotation.Transactional;
import com.ify.sampleAdmin.root.ResResult;

/**
 *
 * @description $!{table.comment} 服务实现类
 * @author ${author}
 * @since ${date}
 */
@Service
@Transactional(rollbackFor = Exception.class)
#if(${kotlin})
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {

    }
#else
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}>implements ${table.serviceName} {


    @Override
    public ResResult save${entity}(${entity} ${table.entityPath}){
        return null;
    }


    @Override
    public ResResult update${entity}(${entity} ${table.entityPath}){
        return null;
    }

    @Override
    public ResResult deleteById(String id){
        return null;
    }

    @Override
    public ResResult deleteBatch(String ids){
        return null;
    }


    @Override
    public ResResult get${entity}ById(String id){
        return null;
    }


    @Override
    public ResResult findPage(${entity} ${table.entityPath}){
        return null;
    }
}
#end

代码生成器配置逻辑

@RestController
@RequestMapping("/sys")
@Api(tags = "GenApi(代码生成表)", value = "代码生成表")
public class GenController extends BaseController {

    @Autowired
    private GenService genService;

    @PostMapping(value = "/gen/code")
    @ApiOperation(value = "代码生成", notes = "接口描述")
    @DynamicParameters(name = "generatorCode", properties = {
            @DynamicParameter(name = "tableName", value = "表名", example = "", required = true, dataTypeClass = String.class),
            @DynamicParameter(name = "tablePrefix", value = "表名前缀 填写前缀,生成实体不包含前缀", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "module", value = "模块名称 模块名称用来分类", example = "", required = true, dataTypeClass = String.class),
            @DynamicParameter(name = "description", value = "功能描述", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "author", value = "作者", example = "", required = false, dataTypeClass = String.class),
    })
    public ResResult generatorCode(@RequestBody JSONObject param) {
        this.genService.codeGenerator(param.toJavaObject(Gen.class));
        return ResResult.success();
    }



}

public interface GenService extends IService<Gen> {


    /**
     * 生成代码
     * @param gen
     */
    void codeGenerator(Gen gen);

}

/**
 * <p>
 * 代码生成表  服务实现类
 * </p>
 *
 * @author ify
 * @since 2021-01-28
 */
@Service
public class GenServiceImpl extends ServiceImpl<GenDao, Gen> implements GenService {

    @Value("${spring.datasource.druid.driver-class-name}")
    private String dbDriverName;
    @Value("${spring.datasource.druid.url}")
    private String dbUrl;
    @Value("${spring.datasource.druid.username}")
    private String dbUsername;
    @Value("${spring.datasource.druid.password}")
    private String dbPassword;

    @Override
    public void codeGenerator(Gen gen) {
        String projectPath = System.getProperty("user.dir");
        // 1、声明代码生成器
        AutoGenerator generator = new AutoGenerator();
        // 2、全局信息配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig
                // 输出目录
                .setOutputDir(projectPath + "/src/main/java")
                // 是否覆盖原有文件 默认false
                .setFileOverride(true)
                // 是否打开输出目录 默认true
                .setOpen(false)
                // 作者
                .setAuthor(StrUtil.isEmpty(gen.getAuthor()) ? " " : gen.getAuthor())
                // 设置实体类名称
                .setEntityName("%s")
                // 设置mapper 命名方式
                .setMapperName("%sDao")
                // Mapper xml 命名方式
                .setXmlName("%sDao")
                //service 命名方式
                .setServiceName("%sService")
                //service impl 命名方式
                .setServiceImplName("%sServiceImpl")
                //controller 命名方式
                .setControllerName("%sController")
                // Mapper xml 生成基础 查询列 可以不设置
                .setBaseColumnList(true)
                //Mapper xml  生成基础返回map 可以不设置
                .setBaseResultMap(true)
                // 实体属性 Swagger2 注解 默认false
                .setSwagger2(true);

        // 3、数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        // 设置数据库类型和数据源
        dataSourceConfig.setDbType(DbType.MYSQL)
                .setDriverName(dbDriverName)
                .setUrl(dbUrl)
                .setUsername(dbUsername)
                .setPassword(dbPassword);

        // 4、策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig
                // 数据库表映射实体 下划线转大写,驼峰命名方式
                .setNaming(NamingStrategy.underline_to_camel)
                // 数据库字段映射实体属性 下划线转大写,驼峰命名方式
                .setColumnNaming(NamingStrategy.underline_to_camel)
                // 生成 @RestController 控制器
                .setRestControllerStyle(true)
                // 设置controller继承的父类
                .setSuperControllerClass(BaseController.class)
                // entity继承的父类
                .setSuperEntityClass(BaseEntity.class)
                // entity继承类的字段
                .setSuperEntityColumns("id", "create_by", "create_time", "update_by", "update_time")
                // 是否生成lombok模式
                .setEntityLombokModel(true)
                //要生成的表名
                .setInclude(gen.getTableName());
        // 设置表前缀,生成的实体名称不包含前缀
        if (StrUtil.isNotEmpty(gen.getTablePrefix())) {
            strategyConfig.setTablePrefix(gen.getTablePrefix());
        }

        // 5、生成代码包信息配置
        PackageConfig packageConfig = new PackageConfig();

        packageConfig
                // 设置生成的包名的父类名称
                .setParent("com.ify.sampleAdmin.web")
                .setController("controller" + "." + gen.getModule())
                .setEntity("entity" + "." + gen.getModule())
                .setMapper("dao" + "." + gen.getModule())
                .setService("service" + "." + gen.getModule())
                .setServiceImpl("service.impl" + "." + gen.getModule());
        //xml 自定义输出到java 文件夹下,所以下面自定义输出路径
        //                .setXml(mapper");


        // 自定义要注入到模板的属性,在模板里用cfg.xxx引用
        InjectionConfig injectionConfig = new InjectionConfig() {
            // 必须实现的方法, 内容可以放空
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>(4);
                map.put("moduleName", gen.getModule());
                map.put("description", gen.getDescription());
                this.setMap(map);
            }
        };

        List<FileOutConfig> fileOutConfigList = new ArrayList<>();
        FileOutConfig fileOutConfig = new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath + "/src/main/resources/mapper/" + gen.getModule() + "/" + tableInfo.getEntityName() + "Dao" + StringPool.DOT_XML;
            }
        };
        fileOutConfigList.add(fileOutConfig);
        injectionConfig.setFileOutConfigList(fileOutConfigList);

        // 7 自定义模板
        TemplateConfig templateConfig = new TemplateConfig();
        // xml自定义输出路径,所以设置为null
        templateConfig.setXml(null);


        // 8、整合配置
        generator.setGlobalConfig(globalConfig)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig)
                .setTemplate(templateConfig)
                .setCfg(injectionConfig);

        //9、执行
        generator.execute();
    }
}

把基础的表重新生成一遍。

看一下生成的基本代码是什么样子

@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user")
@ApiModel(value="User对象", description="")
public class User extends BaseEntity {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "用户名")
    private String username;

    @ApiModelProperty(value = "密码")
    private String password;

    @ApiModelProperty(value = "性别 0 女| 1 男")
    private String sex;

    @ApiModelProperty(value = "是否锁住 0 否 | 1 是")
    private String locked;


}
public interface UserService extends IService<User> {

    ResResult saveUser(User user);

    ResResult updateUser(User user);

    ResResult deleteById(String id);

    ResResult deleteBatch(String ids);

    ResResult getUserById(String id);

    ResResult findPage(User user);
}

@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserDao, User>implements UserService {


    @Override
    public ResResult saveUser(User user){
        return null;
    }


    @Override
    public ResResult updateUser(User user){
        return null;
    }

    @Override
    public ResResult deleteById(String id){
        return null;
    }

    @Override
    public ResResult deleteBatch(String ids){
        return null;
    }


    @Override
    public ResResult getUserById(String id){
        return null;
    }


    @Override
    public ResResult findPage(User user){
        return null;
    }
}
@RestController
@RequestMapping("sys")
@Api(tags = "UserApi(用户表)", value = "")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @PostMapping(value = "/users")
    @ApiOperation(value = "新增", notes = "接口描述")
    @DynamicParameters(name = "saveUser", properties = {
            @DynamicParameter(name = "username", value = "用户名", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "password", value = "密码", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "sex", value = "性别 0 女| 1 男", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "locked", value = "是否锁住 0 否 | 1 是", example = "", required = false, dataTypeClass = String.class),
    })
    public ResResult saveUser(@RequestBody JSONObject param){
        return this.userService.saveUser(param.toJavaObject(User.class));
    }

    @PutMapping(value = "/users")
    @ApiOperation(value = "更新", notes = "接口描述")
    @DynamicParameters(name = "updateUser", properties = {
            @DynamicParameter(name = "username", value = "用户名", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "password", value = "密码", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "sex", value = "性别 0 女| 1 男", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "locked", value = "是否锁住 0 否 | 1 是", example = "", required = false, dataTypeClass = String.class),
    })
    public ResResult updateUser(@RequestBody JSONObject param){
        return this.userService.updateUser(param.toJavaObject(User.class));
    }

    @DeleteMapping(value = "/users/{id}")
    @ApiOperation(value = "删除(单条)", notes = "接口描述")
    public ResResult deleteUserById(@PathVariable("id") String id){
        return this.userService.deleteById(id);
    }

    @PostMapping(value = "/users/batch")
    @ApiOperation(value = "删除(批量)", notes = "接口描述")
    @DynamicParameters(name = "deleteUserByIds", properties = {
            @DynamicParameter(name = "ids", value = "id字符串", example = "id1,id2...", required = false, dataTypeClass = String.class),
    })
    public ResResult deleteUserByIds(@RequestBody JSONObject param){
        return this.userService.deleteBatch(param.getString("ids"));
    }

    @GetMapping(value = "/users/{id}")
    @ApiOperation(value = "查询(单条)", notes = "接口描述")
    public ResResult getUser(@PathVariable("id") String id){
        return this.userService.getUserById(id);
    }

    @PostMapping(value = "/users/page")
    @ApiOperation(value = "分页查询", notes = "接口描述")
    @DynamicParameters(name = "findUserPage", properties = {
            @DynamicParameter(name = "username", value = "用户名", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "password", value = "密码", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "sex", value = "性别 0 女| 1 男", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "locked", value = "是否锁住 0 否 | 1 是", example = "", required = false, dataTypeClass = String.class),
            @DynamicParameter(name = "page", value = "分页对象", example = "{}", required = true, dataTypeClass = Page.class),
    })
    public ResResult findUserPage(@RequestBody JSONObject param){
        return this.userService.findPage(param.toJavaObject(User.class));
    }
}

swagger文档的效果

轻松加愉快!

补充

BaseEntity封装了分页对象

@Data
public class BaseEntity {

    /**
     * id 生成策略为UUID
     */
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;

    /**
     * 创建者 填充策略为插入自动填充
     */
    @TableField(fill = FieldFill.INSERT)
    private String createBy;

    /**
     * 创建时间 填充策略为插入自动填充
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    /**
     * 更新者 填充策略为更新自动填充
     */
    @TableField(fill = FieldFill.UPDATE)
    private String updateBy;

    /**
     * 更新时间 填充策略为更新自动填充
     */
    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;

    /**
     * 分页对象,分页查询传参用
     */
    @TableField(exist = false)
    private Page page;
}

结尾

偷懒工作就这些了,后面开发生成代码可以节省点基础crud代码的编写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值