Spring Boot:(6)集成代码生成工具

  • 基于第三方代码生成器 renren-generator
  • renren-generator是人人开源项目的代码生成器,基于此项目修改代码模板,
    修改代码生成程序,使生成代码直接在项目中相应位置创建,可批量生成基于数据库表的基础代码,高效。

拉取renren-generator项目源码

在项目中创建子项目 generator

在这里插入图片描述

复制源码

  • 将renren-generator项目中源码,复制进子项目generator。
    在这里插入图片描述

编辑代码生成模板

  • 路径 main\ resources\template 新建模板文件
  • 参考模板内容如下
  • M-DO.java.vm
package ${package}.${moduleName}.domain;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

#if(${hasBigDecimal})
import java.math.BigDecimal;
#end
import java.io.Serializable;
import java.util.Date;
import lombok.Data;

/**
 * ${comments}
 * 
 * @author ${author}
 * @date ${datetime}
 */
@ApiModel(value = "${comments}DO")
@Data
@TableName("${tableName}")
public class ${className}DO implements Serializable {
	private static final long serialVersionUID = 1L;

#foreach ($column in $columns)

	@ApiModelProperty(value = "$column.comments")
#if($column.columnName == $pk.columnName)
    @TableId
#end
#if($column.attrType == 'Date')
#if($column.dataType == 'date')
   	@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")
   	@DateTimeFormat(pattern="yyyy-MM-dd")
#elseif($column.dataType == 'time')
   	@JsonFormat(locale="zh", timezone="GMT+8", pattern="HH:mm:ss")
   	@DateTimeFormat(pattern="HH:mm:ss")
#else
   	@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
   	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
#end
#end
#if($column.attrname == 'updateBy' || $column.attrname == 'updateTime')
   	@TableField(fill = FieldFill.UPDATE)
#end
#if($column.attrname == 'createBy' || $column.attrname == 'createTime')
   	@TableField(fill = FieldFill.INSERT)
#end
    private $column.attrType $column.attrname;
#end

}

  • M-Dao.java.vm
package ${package}.${moduleName}.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import ${package}.${moduleName}.domain.${className}DO;

/**
 * ${comments}
 *
 * @author ${author}
 * @date ${datetime}
 */
@Mapper
public interface ${className}Dao extends BaseMapper<${className}DO> {

}
  • M-Mapper.xml.vm
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="${package}.${moduleName}.dao.${className}Dao">

	<!-- 可根据自己的需求,是否要使用 -->
    <resultMap type="${package}.${moduleName}.domain.${className}DO" id="${classname}Map">
#foreach($column in $columns)
        <result property="${column.attrname}" column="${column.columnName}"/>
#end
    </resultMap>


</mapper>
  • M-Service.java.vm
package ${package}.${moduleName}.service;

import com.baomidou.mybatisplus.extension.service.IService;
import ${package}.${moduleName}.domain.${className}DO;

/**
 * ${comments}
 *
 * @author ${author}
 * @date ${datetime}
 */
public interface ${className}Service extends IService<${className}DO> {
}

  • M-ServiceImpl.java.vm
package ${package}.${moduleName}.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${package}.${moduleName}.dao.${className}Dao;
import ${package}.${moduleName}.domain.${className}DO;
import ${package}.${moduleName}.service.${className}Service;
import org.springframework.stereotype.Service;

/**
 * ${comments}
 *
 * @author ${author}
 * @date ${datetime}
 */
@Service("${classname}Service")
public class ${className}ServiceImpl extends ServiceImpl<${className}Dao, ${className}DO> implements ${className}Service {
}

  • M-Controller.java.vm
package org.mur.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import ${mainPath}.common.core.BaseController;
import ${mainPath}.common.core.Convert;
import ${mainPath}.common.utils.Result;
import  ${package}.${moduleName}.domain.${className}DO;
import  ${package}.${moduleName}.service.${className}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;



/**
 * ${comments}
 *
 * @author ${author}
 * @date ${datetime}
 */
@Api(tags = "${comments}")
@RestController
@RequestMapping("${moduleName}/${pathName}")
public class ${className}Controller {
    @Autowired
    private ${className}Service ${classname}Service;

    @ApiOperation("列表")
    @GetMapping("/list")
    //@RequiresPermissions("${moduleName}:${pathName}:list")
    public Result<List<${className}DO>> getList(@ModelAttribute ${className}DO ${classname}DO ) {
        QueryWrapper<${className}DO> qw = new QueryWrapper<${className}DO>().setEntity(${classname}DO);
        return Result.ok(${classname}Service.list(qw));
    }

    @ApiOperation("信息")
    @GetMapping("/info/{${pk.attrname}}")
    //@RequiresPermissions("${moduleName}:${pathName}:info")
    @ApiImplicitParam(name = "${pk.attrname}", value = "主键${pk.attrname}", dataTypeClass = ${pk.attrType}.class)
    public Result<${className}DO> getInfo(@PathVariable("${pk.attrname}") ${pk.attrType} ${pk.attrname}) {
        return Result.ok(${classname}Service.getById(${pk.attrname}));
    }


    /**
     * 保存
     */
     @ApiOperation("保存")
    @PostMapping("/save")
    //@RequiresPermissions("${moduleName}:${pathName}:save")
    public Result save(@RequestBody ${className}DO ${classname}DO){
		boolean save = ${classname}Service.save(${classname}DO);
        return Result.status(save);
    }

    /**
     * 修改
     */
    @ApiOperation("修改")
    @PostMapping("/update")
    //@RequiresPermissions("${moduleName}:${pathName}:update")
    public Result update(@RequestBody ${className}DO ${classname}DO) {
        boolean update = ${classname}Service.updateById(${classname}DO);
        return Result.status(update);
    }

    /**
     * 删除
     */
    @ApiOperation("删除")
    @PostMapping("/delete")
    //@RequiresPermissions("${moduleName}:${pathName}:delete")
    @ApiImplicitParam(name = "ids", value = "主键ids(逗号隔开)", dataType = "string")
    public Result delete(String ids) {
        List<Long> idList = Convert.toLongList(ids);
        boolean delete = ${classname}Service.removeByIds(idList);
        return Result.status(delete);
    }
}

修改代码生成程序

  • SysGeneratorController中添加

	/** 生成代码ServiceCode */
	@ResponseBody
	@RequestMapping("/serviceCode")
	public R serviceCode(String tables, String moduleProject) throws IOException{
		byte[] data = sysGeneratorService.generatorCodeToProject(tables.split(","),1);
		return R.ok("代码已生成!");
	}

	/** 生成代码ServiceCode */
	@ResponseBody
	@RequestMapping("/controllerCode")
	public R controllerCode(String tables,String moduleProject) throws IOException{
		byte[] data = sysGeneratorService.generatorCodeToProject(tables.split(","),2);
		return R.ok("代码已生成!");
	}
  • SysGeneratorService中添加
    public byte[] generatorCodeToProject(String[] tableNames, int type) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        for (String tableName : tableNames) {
            //查询表信息
            Map<String, String> table = queryTable(tableName);
            //查询列信息
            List<Map<String, String>> columns = queryColumns(tableName);
            //生成代码
            GenUtils.generatorCodeToProject(table, columns, type);
        }
        return outputStream.toByteArray();
    }
  • GenUtils中添加

/**
 * 获取模板列表
 * @param type 1:DO, Dao, mapper,Service,ServiceImpl 2:Controller
 * @return
 */
public static List<String> getTemplates(int type) {
    List<String> templates = new ArrayList<String>();
    if(type == 1){
        // DO, Dao, mapper,Service,ServiceImpl
        templates.add("template/M-DO.java.vm");
        templates.add("template/M-Dao.java.vm");
        templates.add("template/M-Mapper.xml.vm");
        templates.add("template/M-Service.java.vm");
        templates.add("template/M-ServiceImpl.java.vm");
    }else if(type == 2){
        // Controller
        templates.add("template/M-Controller.java.vm");
}
    return templates;
}


/**
 * 生成代码
 */
public static void generatorCodeToProject(Map<String, String> table, List<Map<String, String>> columns, int type) {
    //配置信息
    Configuration config = getConfig();
    // boolean hasBigDecimal = false;
    // boolean hasList = false;
    //表信息
    TableEntity tableEntity = getTableEntity(table, columns);
    //设置velocity资源加载器
    Properties prop = new Properties();
    prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
    Velocity.init(prop);
    String mainPath = config.getString("mainPath");
    mainPath = StringUtils.isBlank(mainPath) ? "org.mur" : mainPath;
    //封装模板数据
    VelocityContext context = getVelocityContext(tableEntity);

    //获取模板列表
    List<String> templates = getTemplates(type) ;
    for (String template : templates) {
        //渲染模板
        StringWriter sw = new StringWriter();
        Template tpl = Velocity.getTemplate(template, "UTF-8");
        tpl.merge(context, sw);

        try {
            //获取当前项目的根路径
            File directory = new File("");// 参数为空
            String courseFile = directory.getCanonicalPath();
            String project = config.getString("moduleProject");
            if (StringUtils.isNotEmpty(project)) {
                int i = StringUtils.lastIndexOf(courseFile, "\\");
                courseFile += "\\" + project;
            }
            String entityFileName = getFileNameM(template, tableEntity.getClassName(), config.getString("package"), config.getString("moduleName"));
            FileUtil.writeString(sw.toString(),FileUtil.touch(courseFile+"\\src\\"+entityFileName), "UTF-8");
        } catch (IOException e){
            throw new RRException("渲染模板失败,表名:" + tableEntity.getTableName(), e);
        }
    }
}


/**
 * 获取表信息
 * @param table
 * @param columns
 * @return
 */
public static TableEntity getTableEntity(Map<String, String> table, List<Map<String, String>> columns){
    //配置信息
    Configuration config = getConfig();
    boolean hasBigDecimal = false;
    boolean hasList = false;
    //表信息
    TableEntity tableEntity = new TableEntity();
    tableEntity.setTableName(table.get("tableName"));
    tableEntity.setComments(table.get("tableComment"));
    //表名转换成Java类名
    String className = tableToJava(tableEntity.getTableName(), config.getStringArray("tablePrefix"));
    tableEntity.setClassName(className);
    tableEntity.setClassname(StringUtils.uncapitalize(className));

    //列信息
    List<ColumnEntity> columsList = new ArrayList<>();
    for (Map<String, String> column : columns) {
        ColumnEntity columnEntity = new ColumnEntity();
        columnEntity.setColumnName(column.get("columnName"));
        columnEntity.setDataType(column.get("dataType"));
        columnEntity.setComments(column.get("columnComment"));
        columnEntity.setExtra(column.get("extra"));

        //列名转换成Java属性名
        String attrName = columnToJava(columnEntity.getColumnName());
        columnEntity.setAttrName(attrName);
        columnEntity.setAttrname(StringUtils.uncapitalize(attrName));

        //列的数据类型,转换成Java类型
        String attrType = config.getString(columnEntity.getDataType(), columnToJava(columnEntity.getDataType()));
        columnEntity.setAttrType(attrType);


        if (!hasBigDecimal && attrType.equals("BigDecimal")) {
            hasBigDecimal = true;
        }
        if (!hasList && "array".equals(columnEntity.getExtra())) {
            hasList = true;
        }
        //是否主键
        if ("PRI".equalsIgnoreCase(column.get("columnKey")) && tableEntity.getPk() == null) {
            tableEntity.setPk(columnEntity);
        }

        columsList.add(columnEntity);
    }
    tableEntity.setColumns(columsList);

    //没主键,则第一个字段为主键
    if (tableEntity.getPk() == null) {
        tableEntity.setPk(tableEntity.getColumns().get(0));
    }
    return tableEntity;
}

public static VelocityContext getVelocityContext(TableEntity tableEntity){
    //配置信息
    Configuration config = getConfig();
    boolean hasBigDecimal = false;
    boolean hasList = false;

    String mainPath = config.getString("mainPath");
    //封装模板数据
    Map<String, Object> map = new HashMap<>();
    map.put("tableName", tableEntity.getTableName());
    map.put("comments", tableEntity.getComments());
    map.put("pk", tableEntity.getPk());
    map.put("className", tableEntity.getClassName());
    map.put("classname", tableEntity.getClassname());
    map.put("pathName", tableEntity.getClassname().toLowerCase());
    map.put("columns", tableEntity.getColumns());
    map.put("hasBigDecimal", hasBigDecimal);
    map.put("hasList", hasList);
    map.put("mainPath", mainPath);
    map.put("package", config.getString("package"));
    map.put("moduleName", config.getString("moduleName"));
    map.put("author", config.getString("author"));
    map.put("email", config.getString("email"));
    map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
    VelocityContext context = new VelocityContext(map);
    return context;
}

/**
 * 获取文件名
 */
public static String getFileNameM(String template, String className, String packageName, String moduleName) {
    String packagePath = "main" + File.separator + "java" + File.separator;
    if (StringUtils.isNotBlank(packageName)) {
        packagePath += packageName.replace(".", File.separator) + File.separator + moduleName + File.separator;
    }

    if (template.contains("M-DO.java.vm")) {
        return packagePath + "domain" + File.separator + className + "DO.java";
    }

    if (template.contains("M-Dao.java.vm")) {
        return packagePath + "dao" + File.separator + className + "Dao.java";
    }

    if (template.contains("M-Service.java.vm")) {
        return packagePath + "service" + File.separator + className + "Service.java";
    }

    if (template.contains("M-ServiceImpl.java.vm")) {
        return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java";
    }

    if (template.contains("M-Controller.java.vm")) {
        return packagePath + "controller" + File.separator + className + "Controller.java";
    }

    if (template.contains("M-Mapper.xml.vm")) {
        return "main" + File.separator + "resources" + File.separator + "mapper" + File.separator + moduleName + File.separator + className + "Mapper.xml";
    }

    return null;
}

修改配置信息

  • 修改generator.properties中配置信息
#\u4EE3\u7801\u751F\u6210\u5668\uFF0C\u914D\u7F6E\u4FE1\u606F
#主路径
mainPath=org.mur
#\u5305\u540D
#包名
package=org.mur
#模块名
moduleName=system
#子项目名
moduleProject = admin
#\u4F5C\u8005
author=Mur
#Email
#email=sunlightcs@gmail.com
#\u8868\u524D\u7F00(\u7C7B\u540D\u4E0D\u4F1A\u5305\u542B\u8868\u524D\u7F00)
tablePrefix=

修改连接数据库信息

  • 修改application.yml文件
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: username
password: password

生成代码

  • 启动项目,访问页面 http://localhost:80
    在这里插入图片描述

  • 勾选需要生成代码的数据表,点击代码生成按钮
    在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值