SaaS系统从0到1搭建,06代码生成(模板篇)

·  阅读 271
SaaS系统从0到1搭建,06代码生成(模板篇)

前言

车队管理类似的SaaS平台,从0到1,继续..

上一篇咱撸到租户入驻,已经是实际业务场景了,然后在设计下入驻的租户主要信息,已经租户的状态历史表。本篇本来是编写下关于SaaS计费规则的,但这块还是得按需求来设计,就先不要了。 那就从代码生成器,做个分享吧。

(我是后半夜Java,在掘金这分享下经验,那些靠copy的搬运作者,未经允许,不要copy文章了)

代码生成

程序猿子都知道,平白无期的copy代码是浪费时间的,一直CtrlC CtrlV 浪费头发,主要的精力应该用在业务逻辑上,架构完善上面,那么有一套代码生成的工具,就灰常的适合,或者已经就是程序猿的必备工具了。

场景

比如新增个业务表,那么表已经有了,如果咱用的是Mybatis 那么那些基础的SQL、表对应的Bean对象,CRUD的基础方法这些基本都是一样的,所以这类代码就是需要咱自动生成代码的工具来完成了。

做法

估计网上可以搜索出一片的代码生成工具,但从原理上或者思路上,去理解下,对每个程序猿都会有些成长值。

思路

表->获取字段,生成基本TableNameMapping.xml ,及对应的Bean对象,然后生成service、control那些

准备

先了解下Velocity,也就是*.vm 后缀的文件,Velocity是一个基于java的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(templatelanguage)来引用由java代码定义的对象。

TableNameMapping.xml.vm

mapping文件

<?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}.entity.${className}Entity" id="${classname}Map">
#foreach($column in $columns)
        <result property="${column.attrname}" column="${column.columnName}"/>
#end
    </resultMap>
</mapper>
复制代码

TableNameDao.java.vm

Dao内容

package ${package}.${moduleName}.dao;

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

/**
 * ${comments}
 * @author ${author}
 * @date ${datetime}
 */
@Mapper
public interface ${className}Dao extends BaseMapper<${className}Entity> {
   
}
复制代码

TableNameEntity.java.vm

Entity表对象,也有叫model的,反正一个意思,就是表对应的bean对象

package ${package}.${moduleName}.entity;

import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
#if(${hasBigDecimal})
import java.math.BigDecimal;
#end
import java.io.Serializable;
import java.util.Date;

/**
 * 对象说明:${comments}
 * @author ${author}
 * @date ${datetime}
 */
@TableName("${tableName}")
@Data
public class ${className}Entity implements Serializable {
   private static final long serialVersionUID = 1L;
#foreach ($column in $columns)
   /**
    * $column.comments
    */
   #if($column.columnName == $pk.columnName)
   @TableId
   #end
   private $column.attrType $column.attrname;
#end
}
复制代码

TableNameService.java.vm

表对应的接口类

package ${package}.${moduleName}.service;

import com.baomidou.mybatisplus.extension.service.IService;
import ${mainPath}.common.utils.PageUtils;
import ${package}.${moduleName}.entity.${className}Entity;
import java.util.Map;

/**
 * 接口描述:${comments}
 * @author ${author}
 * @date ${datetime}
 */
public interface ${className}Service extends IService<${className}Entity> {
    /**
    * 分页查询
    * @param params
    * @return 
    */
    PageUtils queryPage(Map<String, Object> params);
}
复制代码

TableNameServiceImpl.java.vm

接口实现类

package ${package}.${moduleName}.service.impl;

import org.springframework.stereotype.Service;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${mainPath}.common.utils.PageUtils;
import ${mainPath}.common.utils.Query;
import ${package}.${moduleName}.dao.${className}Dao;
import ${package}.${moduleName}.entity.${className}Entity;
import ${package}.${moduleName}.service.${className}Service;
/**
 * 描述:${comments}
 * @author ${author}
 * @date ${datetime}
 */
public class ${className}ServiceImpl extends ServiceImpl<${className}Dao, ${className}Entity> implements ${className}Service {
    /**
    * 分页查询
    * @param params
    * @return 
    */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<${className}Entity> page = this.page(
                new Query<${className}Entity>().getPage(params),
                new QueryWrapper<${className}Entity>()
        );
        return new PageUtils(page);
    }

}
复制代码

TableNameController.java.vm

最后就是control层,一般的增删改查的入口:

package ${package}.${moduleName}.controller;

import java.util.Arrays;
import java.util.Map;
import io.renren.common.validator.ValidatorUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ${package}.${moduleName}.entity.${className}Entity;
import ${package}.${moduleName}.service.${className}Service;
import ${mainPath}.common.utils.PageUtils;
import ${mainPath}.common.utils.R;

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

    /**
     * 分页查询列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("${moduleName}:${pathName}:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = ${classname}Service.queryPage(params);
        return R.ok().put("page", page);
    }

    /**
     * 获取单个对象信息
     */
    @RequestMapping("/info/{${pk.attrname}}")
    @RequiresPermissions("${moduleName}:${pathName}:info")
    public R info(@PathVariable("${pk.attrname}") ${pk.attrType} ${pk.attrname}){
        ${className}Entity ${classname} = ${classname}Service.getById(${pk.attrname});
        return R.ok().put("${classname}", ${classname});
    }

    /**
     * 新增
     */
    @RequestMapping("/save")
    @RequiresPermissions("${moduleName}:${pathName}:save")
    public R save(@RequestBody ${className}Entity ${classname}){
        ${classname}Service.save(${classname});
        return R.ok();
    }

    /**
     * 编辑修改
     */
    @RequestMapping("/update")
    @RequiresPermissions("${moduleName}:${pathName}:update")
    public R update(@RequestBody ${className}Entity ${classname}){
        ValidatorUtils.validateEntity(${classname});
        ${classname}Service.updateById(${classname});
        return R.ok();
    }

    /**
     * 删除(物理删除)
     */
    @RequestMapping("/delete")
    @RequiresPermissions("${moduleName}:${pathName}:delete")
    public R delete(@RequestBody ${pk.attrType}[] ${pk.attrname}s){
        ${classname}Service.removeByIds(Arrays.asList(${pk.attrname}s));
        return R.ok();
    }

}
复制代码

总结

代码生成,有很多案例,这种可以自己修改模板的开源也有一些,这种模板的做法,是相对比较好的实现方式。模板分享,下篇我们继续生成代码逻辑。

SaaS系统从0到1搭建,下篇继续....

分类:
后端
标签: