基于SpringBoot的CodeGenerator


title: 基于SpringBoot的CodeGenerator tags:

  • SpringBoot
  • Mybatis
  • 生成器
  • PageHelper categories: springboot date: 2017-11-21 15:13:33

背景

目前组织上对于一个基础的crud的框架需求较多 因此选择了SpringBoot作为基础选型。

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

目前的结构基于 SpringBoot [base]+ mybatis[orm] + dubbo[soa] + shiro[rbac] + kisso[sso] + orika[mapping] +swagger[doc] +easypoi [word]

代码

在介绍生成器之前先简单介绍如下几个抽象接口或者超类

实体对象

    package com.f6car.base.common;public class Po implements java.io.Serializable {private static final long serialVersionUID = 5350639685728778721L;}
复制代码

页面展示对象

    package com.f6car.base.common;public class Vo implements java.io.Serializable {private static final long serialVersionUID = -3138610557784823876L;}
复制代码

页面搜索对象

    /*** @author qixiaobo*///非线程安全public class So implements java.io.Serializable, Pagable, Sortable {private static final long serialVersionUID = -828171499994153332L;private int currentPage;private int pageSize = PAGESIZE.s.pageSize;private boolean enableCount;private List<Sort> sorts;@Overridepublic int getCurrentPage() {return currentPage;}@Overridepublic void setCurrentPage(int currentPage) {this.currentPage = currentPage;}@Overridepublic int getPageSize() {return pageSize;}@Overridepublic void setPageSize(int pageSize) {this.pageSize = pageSize;}@Overridepublic boolean isEnableCount() {return enableCount;}@Overridepublic void setEnableCount(boolean enableCount) {this.enableCount = enableCount;}@Overridepublic List<Sort> getSorts() {return sorts;}public void setSorts(List<Sort> sorts) {this.sorts = sorts;}@Overridepublic void addSort(Sort sort) {if (sorts != null) {sorts = new ArrayList<>();}sorts.add(sort);}public static enum PAGESIZE {xs(5), s(10), m(20), l(30), xl(50), xxl(100), xxxl(1000);private int pageSize;PAGESIZE(int pageSize) {this.pageSize = pageSize;}public int getPageSize() {return pageSize;}}}
复制代码
    /*** Created by qixiaobo on 2016/11/24.*/public interface Pagable {public int getCurrentPage();public void setCurrentPage(int currentPage);public int getPageSize();public void setPageSize(int pagesize);public boolean isEnableCount();public void setEnableCount(boolean enable);}
复制代码
    /*** Created by qixiaobo on 2016/11/24.*/public interface Sortable {List<Sort> getSorts();void addSort(Sort sort);}
复制代码
    /*** Created by qixiaobo on 2016/11/24.*/public class Sort implements Serializable {private static final long serialVersionUID = 7739709965769082011L;private static final String DEFAULT_PREFIX = "p";private static final String SQL_DOT = ".";private String orderField;private OrderType orderType = OrderType.ASC;private boolean enablePrefix = true;private Sort() {}private Sort(String orderField, OrderType orderType, boolean enablePrefix) {assert orderField != null;this.orderField = orderField;this.orderType = orderType;this.enablePrefix = enablePrefix;}private Sort(String orderField) {this(orderField, OrderType.ASC, true);}public static Sort valueOf(String sortString) {return new Sort(sortString);}public static Sort valueOf(String sortKey, OrderType orderType) {return new Sort(sortKey, orderType, true);}public static Sort valueOf(String sortKey, OrderType orderType, boolean enablePrefix) {return new Sort(sortKey, orderType, enablePrefix);}public String getOrderField() {if (orderField.contains(SQL_DOT) || !enablePrefix) {return orderField;} else {return DEFAULT_PREFIX + SQL_DOT + orderField;}}public void setOrderField(String orderField) {this.orderField = orderField;}public OrderType getOrderType() {return orderType;}public void setOrderType(OrderType orderType) {this.orderType = orderType;}public boolean isEnablePrefix() {return enablePrefix;}public void setEnablePrefix(boolean enablePrefix) {this.enablePrefix = enablePrefix;}@Overridepublic String toString() {return getOrderField() + " " + orderType;}}
复制代码

统一回复格式

    public class Result {private int code;private String message;private Object data;public Result setCode(ResultCode resultCode) {this.code = resultCode.code;return this;}public int getCode() {return code;}public Result setCode(int code) {this.code = code;return this;}public String getMessage() {return message;}public Result setMessage(String message) {this.message = message;return this;}public Object getData() {return data;}public Result setData(Object data) {this.data = data;return this;}@Overridepublic String toString() {final StringBuilder sb = new StringBuilder("Result{");sb.append("code=").append(code);sb.append(", message='").append(message).append('\'');sb.append(", data=").append(data);sb.append('}');return sb.toString();}}public enum ResultCode {SUCCESS(200),//成功FAIL(400),//失败UNAUTHORIZED(401),//未认证(签名错误)NOT_FOUND(404),//接口不存在INTERNAL_SERVER_ERROR(500);//服务器内部错误public int code;ResultCode(int code) {this.code = code;}}
复制代码
    public class ResultGenerator {private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";public static Result genSuccessResult() {return new Result().setCode(ResultCode.SUCCESS).setMessage(DEFAULT_SUCCESS_MESSAGE);}public static Result genSuccessResult(Object data) {return new Result().setCode(ResultCode.SUCCESS).setMessage(DEFAULT_SUCCESS_MESSAGE).setData(data);}public static Result genFailResult(String message) {return new Result().setCode(ResultCode.FAIL).setMessage(message);}}
复制代码

抽象Mapper

    package com.f6car.base.core;import com.f6car.base.common.Po;import tk.mybatis.mapper.common.BaseMapper;import tk.mybatis.mapper.common.ConditionMapper;import tk.mybatis.mapper.common.IdsMapper;import tk.mybatis.mapper.common.special.InsertListMapper;public interface Mapper<T extends Po>extendsBaseMapper<T>,ConditionMapper<T>,IdsMapper<T>,InsertListMapper<T> {}
复制代码

抽象Service

    public abstract class AbstractService<T extends Po, V extends Vo, S extends So> implements Service<V, S> {@Autowiredprotected Mapper<T> mapper;@Resourceprotected OrikaMapper orikaMapper;protected Class<V> voClazz;protected Class<T> poClazz;public AbstractService() {TypeToken<T> poType = new TypeToken<T>(getClass()) {};TypeToken<V> voType = new TypeToken<V>(getClass()) {};poClazz = (Class<T>) poType.getRawType();voClazz = (Class<V>) voType.getRawType();}@Overridepublic int save(V model) {Preconditions.checkArgument(model != null);T po = orikaMapper.convert(model, poClazz);return mapper.insertSelective(po);}@Overridepublic int save(List<V> models) {Preconditions.checkArgument(models != null && !models.isEmpty());List<T> ts = orikaMapper.convertList(models, poClazz);return mapper.insertList(ts);}@Overridepublic int deleteById(Serializable id) {Preconditions.checkArgument(id != null);return mapper.deleteByPrimaryKey(id);}@Overridepublic int deleteByIds(String ids) {Preconditions.checkArgument(!Strings.isNullOrEmpty(ids));return mapper.deleteByIds(ids);}@Overridepublic int update(V model) {Preconditions.checkArgument(model != null);T po = orikaMapper.convert(model, poClazz);return mapper.updateByPrimaryKeySelective(po);}@Overridepublic V findById(Serializable id) {Preconditions.checkArgument(id != null);return orikaMapper.convert(mapper.selectByPrimaryKey(id), voClazz);}@Overridepublic List<V> findByIds(String ids) {Preconditions.checkArgument(!Strings.isNullOrEmpty(ids));return orikaMapper.convertList(mapper.selectByIds(ids), voClazz);}@Overridepublic List<V> findAll() {return orikaMapper.convertList(mapper.selectAll(), voClazz);}}
复制代码

很明显此处实现了基于泛型的注入

Service接口

    /*** Service 层 基础接口,其他Service 接口 请继承该接口*/public interface Service<V extends Vo, S extends So> {int save(V model);//持久化int save(List<V> models);//批量持久化int deleteById(Serializable id);//通过主鍵刪除int deleteByIds(String ids);//批量刪除 eg:ids -> “1,2,3,4”int update(V model);//更新V findById(Serializable id);//通过ID查找List<V> findByIds(String ids);//通过多个ID查找//eg:ids -> “1,2,3,4”List<V> findAll();//获取所有}
复制代码

service层次并没有提供po的 泛型 各位可以思考这是为啥?

抽象Controller

    /*** @author qixiaobo*/public abstract class AbstractRestController<V extends Vo, S extends So> {@Autowiredprivate Service<V, S> service;@PostMapping()@ApiOperation(value = "新建实体", notes = "")public Result add(@RequestBody V vo) {service.save(vo);return ResultGenerator.genSuccessResult();}@DeleteMapping("/{id}")@ApiOperation(value = "删除实体", notes = "")public Result delete(@PathVariable Serializable id) {service.deleteById(id);return ResultGenerator.genSuccessResult();}@PutMapping@ApiOperation(value = "更新实体", notes = "")public Result update(@RequestBody V vo) {service.update(vo);return ResultGenerator.genSuccessResult();}@GetMapping@ApiOperation(value = "获取实体列表", notes = "")public Result list(S so) {PageHelper.startPage(so.getCurrentPage(), so.getPageSize());List<V> list = service.findAll();PageInfo pageInfo = new PageInfo(list);return ResultGenerator.genSuccessResult(pageInfo);}@GetMapping("/{id}")@ApiOperation(value = "获取单个实体", notes = "")public Result detail(@PathVariable Serializable id) {V vo = service.findById(id);return ResultGenerator.genSuccessResult(vo);}@DeleteMapping("/batch")@ApiOperation(value = "批量删除实体", notes = "")public Result batchDelete(@RequestParam String ids) {service.deleteByIds(ids);return ResultGenerator.genSuccessResult();}@GetMapping("/batch")@ApiOperation(value = "批量获取实体", notes = "")public Result batchDetail(@RequestParam String ids) {List<V> vos = service.findByIds(ids);return ResultGenerator.genSuccessResult(vos);}@PostMapping("/batch")@ApiOperation(value = "批量新建实体", notes = "")public Result add(@RequestBody List<V> vos) {service.save(vos);return ResultGenerator.genSuccessResult();}}
复制代码

生成器

    public class CodeGenerator {private static final String JDBC_URL = "jdbc:mysql://192.168.1.7:3306/f6dms_20160522";private static final String JDBC_USERNAME = "root";private static final String JDBC_PASSWORD = "root";private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.jdbc.Driver";public static final ThreadLocal<List<Field>> PO_FIELDS = new ThreadLocal<>();private static final String PROJECT_PATH = System.getProperty("user.dir");private static final String TEMPLATE_FILE_PATH = PROJECT_PATH + "/src/test/resources/template";private static final String JAVA_PATH = "/src/main/java";private static final String RESOURCES_PATH = "/src/main/resources";private static final String PACKAGE_PATH_SERVICE = packageConvertPath(SERVICE_PACKAGE);private static final String PACKAGE_PATH_SERVICE_IMPL = packageConvertPath(SERVICE_IMPL_PACKAGE);private static final String PACKAGE_PATH_SO = packageConvertPath(SO_PACKAGE);private static final String PACKAGE_PATH_VO = packageConvertPath(VO_PACKAGE);private static final String PACKAGE_PATH_CONTROLLER = packageConvertPath(CONTROLLER_PACKAGE);private static final String AUTHOR = "qixiaobo";private static final Splitter TABLE_NAME_SPLITTER = Splitter.on(UNDER_LINE).trimResults().omitEmptyStrings();private static final String DATE = new DateTime().toString("yyyy-MM-dd");private static final List<String> VO_EXCLUED_FIELD_NAMES = Lists.newArrayList("creator", "modifier", "modifiedtime", "creationtime");private static final Joiner PATH_JOINER = Joiner.on("/");private static GroupTemplate gt;static {ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("template");org.beetl.core.Configuration cfg = null;try {cfg = org.beetl.core.Configuration.defaultConfiguration();} catch (IOException e) {e.printStackTrace();}gt = new GroupTemplate(resourceLoader, cfg);}public static void main(String[] args) throws IOException {genCode("tb_user", "tb_org", "tb_menu", "tb_org_mac");}/*** 通过数据表名称生成代码,Model 名称通过解析数据表名称获得,下划线转大驼峰的形式。* 如输入表名称 "t_user_detail" 将生成 TUserDetail、TUserDetailMapper、TUserDetailService ...** @param tableNames 数据表名称...*/public static void genCode(String... tableNames) throws IOException {for (String tableName : tableNames) {genCodeByCustomModelName(tableName, null);}}/*** 通过数据表名称,和自定义的 Model 名称生成代码* 如输入表名称 "t_user_detail" 和自定义的 Model 名称 "User" 将生成 User、UserMapper、UserService ...** @param tableName 数据表名称* @param modelName 自定义的 Model 名称*/public static void genCodeByCustomModelName(String tableName, String modelName) throws IOException {String subPackage = "";List<String> strings = TABLE_NAME_SPLITTER.splitToList(tableName);if (strings.size() >= 2) {if (strings.get(0).length() <= 2) {subPackage = strings.get(1);}}genModelAndMapper(tableName, modelName, subPackage);genService(tableName, modelName, subPackage);genController(tableName, modelName, subPackage);}public static void genModelAndMapper(String tableName, String modelName, String subPackageName) {Context context = new Context(ModelType.FLAT);context.setId("f6car");context.setTargetRuntime("MyBatis3Simple");context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();jdbcConnectionConfiguration.setConnectionURL(JDBC_URL);jdbcConnectionConfiguration.setUserId(JDBC_USERNAME);jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD);jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME);context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);JavaTypeResolverConfiguration javaTypeResolverConfiguration = new JavaTypeResolverConfiguration();javaTypeResolverConfiguration.setConfigurationType(F6JavaTypeResolverDefaultImpl.class.getName());context.setJavaTypeResolverConfiguration(javaTypeResolverConfiguration);PluginConfiguration pluginConfiguration = new PluginConfiguration();pluginConfiguration.setConfigurationType(F6MapperPlugin.class.getName());pluginConfiguration.addProperty("mappers", MAPPER_INTERFACE_REFERENCE);context.addPluginConfiguration(pluginConfiguration);JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();javaModelGeneratorConfiguration.setTargetProject(PROJECT_PATH + Module.model.moduleDir + JAVA_PATH);String javaPackage = MODEL_PACKAGE;String mapperPackage = MAPPER_PACKAGE;String xmlPackage = "mapper";if (!Strings.isNullOrEmpty(subPackageName)) {javaPackage += ("." + subPackageName);mapperPackage += ("." + subPackageName);xmlPackage += ("/" + subPackageName);}javaModelGeneratorConfiguration.setTargetPackage(javaPackage);context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();sqlMapGeneratorConfiguration.setTargetProject(PROJECT_PATH + Module.dao.moduleDir + RESOURCES_PATH);sqlMapGeneratorConfiguration.setTargetPackage(xmlPackage);context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();javaClientGeneratorConfiguration.setTargetProject(PROJECT_PATH + Module.dao.moduleDir + JAVA_PATH);javaClientGeneratorConfiguration.setTargetPackage(mapperPackage);javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER");context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);TableConfiguration tableConfiguration = new TableConfiguration(context);tableConfiguration.setTableName(tableName);if (!Strings.isNullOrEmpty(modelName)) {tableConfiguration.setDomainObjectName(modelName);}tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));context.addTableConfiguration(tableConfiguration);List<String> warnings;MyBatisGenerator generator;try {Configuration config = new Configuration();config.addContext(context);config.validate();boolean overwrite = true;DefaultShellCallback callback = new DefaultShellCallback(overwrite);warnings = new ArrayList<>();generator = new MyBatisGenerator(config, callback, warnings);generator.generate(null);} catch (Exception e) {throw new RuntimeException("生成Model和Mapper失败", e);}if (generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {throw new RuntimeException("生成Model和Mapper失败:" + warnings);}if (StringUtils.isEmpty(modelName)) {modelName = tableNameConvertUpperCamel(tableName);}System.out.println(modelName + ".java 生成成功");System.out.println(modelName + "Mapper.java 生成成功");System.out.println(modelName + "Mapper.xml 生成成功");}public static void genService(String tableName, String modelName, String subPackage) throws IOException {Map<String, Object> data = new HashMap<>();data.put("date", DATE);data.put("author", AUTHOR);String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName) : modelName;data.put("modelNameUpperCamel", modelNameUpperCamel);data.put("modelNameLowerCamel", tableNameConvertLowerCamel(tableName));data.put("basePackage", BASE_PACKAGE);String servicePackageDir = PROJECT_PATH + Module.service.moduleDir + JAVA_PATH + PACKAGE_PATH_SERVICE;String serviceImplPackageDir = PROJECT_PATH + Module.serviceimpl.moduleDir + JAVA_PATH + PACKAGE_PATH_SERVICE_IMPL;String soPackageDir = PROJECT_PATH + Module.dto.moduleDir + JAVA_PATH + PACKAGE_PATH_SO;String voPackageDir = PROJECT_PATH + Module.dto.moduleDir + JAVA_PATH + PACKAGE_PATH_VO;if (!Strings.isNullOrEmpty(subPackage)) {data.put("subPackage", "." + subPackage);servicePackageDir += ("/" + subPackage + "/");serviceImplPackageDir += ("/" + subPackage + "/");soPackageDir += ("/" + subPackage + "/");voPackageDir += ("/" + subPackage + "/");}generateByTemplate(gt, "/service.beetl", servicePackageDir + modelNameUpperCamel + "Service.java", data);generateByTemplate(gt, "/service-impl.beetl", serviceImplPackageDir + modelNameUpperCamel + "ServiceImpl.java", data);data.put("fields", getVoFields());generateByTemplate(gt, "/so.beetl", soPackageDir + modelNameUpperCamel + "So.java", data);generateByTemplate(gt, "/vo.beetl", voPackageDir + modelNameUpperCamel + "Vo.java", data);}private static Collection<Field> getVoFields() {if (PO_FIELDS.get().isEmpty()) {return Collections.emptyList();} else {return Collections2.filter(PO_FIELDS.get(), new Predicate<Field>() {@Overridepublic boolean apply(Field input) {if (VO_EXCLUED_FIELD_NAMES.contains(input.getName())) {return false;}return true;}});}}private static void generateByTemplate(GroupTemplate groupTemplate, String templateFile, String filename, Map data) throws IOException {File serviceFile = new File(filename);if (!serviceFile.getParentFile().exists()) {serviceFile.getParentFile().mkdirs();}Template template = groupTemplate.getTemplate(templateFile);template.binding(data);template.renderTo(new FileWriter(serviceFile));System.out.println(filename + "生成成功");}public static void genController(String tableName, String modelName, String subPackage) throws IOException {Map<String, Object> data = new HashMap<>();data.put("date", DATE);data.put("author", AUTHOR);String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName) : modelName;List<String> strings = TABLE_NAME_SPLITTER.splitToList(tableName.toLowerCase());if (strings.size() >= 2) {if (strings.get(0).length() <= 2) {strings = Lists.newArrayList(strings);strings.remove(0);}data.put("baseRequestMapping", PATH_JOINER.join(strings));}if (!data.containsKey("baseRequestMapping")) {data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel));}data.put("modelNameUpperCamel", modelNameUpperCamel);data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));data.put("basePackage", BASE_PACKAGE);String controllerPackageDir = PROJECT_PATH + Module.web.moduleDir + JAVA_PATH + PACKAGE_PATH_CONTROLLER;if (!Strings.isNullOrEmpty(subPackage)) {data.put("subPackage", "." + subPackage);controllerPackageDir += ("/" + subPackage + "/");}generateByTemplate(gt, "/controller.beetl", controllerPackageDir + modelNameUpperCamel + "Controller.java", data);PO_FIELDS.remove();}private static String tableNameConvertLowerCamel(String tableName) {return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName.toLowerCase());}private static String tableNameConvertUpperCamel(String tableName) {return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName.toLowerCase());}private static String tableNameConvertMappingPath(String tableName) {tableName = tableName.toLowerCase();return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName);}private static String modelNameConvertMappingPath(String modelName) {String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName);return tableNameConvertMappingPath(tableName);}private static String packageConvertPath(String packageName) {return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);}private static enum Module {dao("/dao"), web("/web"), service("/service"), serviceimpl("/serviceimpl"), dto("/dto"), model("/model");private String moduleDir;Module(String moduleDir) {this.moduleDir = moduleDir;}}}
复制代码

基于我们系统中使用uuid_short 必须使用bigint unsigned (20) 目前Java中并无基础数据类型可以对应 所以使用了String类型

    public class F6JavaTypeResolverDefaultImpl extends JavaTypeResolverDefaultImpl {public F6JavaTypeResolverDefaultImpl() {super();//bigint unsigned!typeMap.put(Types.BIGINT, new JdbcTypeInformation("BIGINT",new FullyQualifiedJavaType(String.class.getName())));}}
复制代码

生成器模板

vo

    package com.f6car.base.vo${subPackage!};import com.f6car.base.common.Vo;import java.util.Date;import java.math.BigDecimal;/*** Created by ${author} on ${date}.*/public class ${modelNameUpperCamel}Vo extends Vo {private static final long serialVersionUID = -6920934492324729614L;<%for(field in fields){%>private ${ field.type.shortName}   ${field.name};<%}%><%for(field in fields){%><%var firstChar = strutil.subStringTo(field.name,0,1);var firstChar_upper =  strutil.toUpperCase(firstChar);var fieldNameWithUpper = strutil.replace (field.name,firstChar,firstChar_upper);%>public void set${fieldNameWithUpper}(${ field.type.shortName} ${field.name}) {this.${field.name} = ${field.name};}public ${ field.type.shortName} get${fieldNameWithUpper}() {return ${field.name};}<%}%>}
复制代码

so

    package com.f6car.base.so${subPackage!};import com.f6car.base.common.So;/*** Created by ${author} on ${date}.*/public class ${modelNameUpperCamel}So extends So {private static final long serialVersionUID = -6920934492324729614L;}
复制代码

service

    package ${basePackage}.service${subPackage!};import ${basePackage}.vo${subPackage!}.${modelNameUpperCamel}Vo;import ${basePackage}.so${subPackage!}.${modelNameUpperCamel}So;import ${basePackage}.common.Service;/*** Created by ${author} on ${date}.*/public interface ${modelNameUpperCamel}Service extends Service<${modelNameUpperCamel}Vo,${modelNameUpperCamel}So> {}
复制代码

service-impl

    package ${basePackage}.service.impl${subPackage!};import ${basePackage}.dao${subPackage!}.${modelNameUpperCamel}Mapper;import ${basePackage}.po${subPackage!}.${modelNameUpperCamel};import ${basePackage}.vo${subPackage!}.${modelNameUpperCamel}Vo;import ${basePackage}.so${subPackage!}.${modelNameUpperCamel}So;import ${basePackage}.service${subPackage!}.${modelNameUpperCamel}Service;import ${basePackage}.core.AbstractService;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;/*** Created by ${author} on ${date}.*/@Service@Transactional(rollbackFor = Exception.class)public class ${modelNameUpperCamel}ServiceImpl extends AbstractService<${modelNameUpperCamel},${modelNameUpperCamel}Vo,${modelNameUpperCamel}So> implements ${modelNameUpperCamel}Service {@Resourceprivate ${modelNameUpperCamel}Mapper ${modelNameLowerCamel}Mapper;}
复制代码

controller

    package ${basePackage}.controller${subPackage!};import ${basePackage}.common.Result;import ${basePackage}.common.ResultGenerator;import ${basePackage}.vo${subPackage!}.${modelNameUpperCamel}Vo;import ${basePackage}.so${subPackage!}.${modelNameUpperCamel}So;import ${basePackage}.service${subPackage!}.${modelNameUpperCamel}Service;import ${basePackage}.controller.base.AbstractRestController;import com.github.pagehelper.PageHelper;import com.github.pagehelper.PageInfo;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;import java.io.Serializable;import java.util.List;/*** Created by ${author} on ${date}.*/@RestController@RequestMapping("${baseRequestMapping}")public class ${modelNameUpperCamel}Controller extends AbstractRestController<${modelNameUpperCamel}Vo, ${modelNameUpperCamel}So> {@Resourceprivate ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service;}
复制代码

当运行生成器比如传入

    genCode("tb_user", "tb_org", "tb_menu", "tb_org_mac");
复制代码

生成如下

    package com.f6car.base.po.user;import com.f6car.base.common.Po;import java.util.Date;import javax.persistence.*;@Table(name = "tb_user")public class TbUser extends Po {/*** 主键*/@Id@Column(name = "pk_id")private String pkId;/*** 用户名*/private String username;@Column(name = "cell_phone")private String cellPhone;/*** 密码*/private String password;/*** 是否管理员*/@Column(name = "is_admin")private Byte isAdmin;/*** 角色ID*/@Column(name = "id_role")private String idRole;/*** 创建人*/private String creator;/*** 修改人*/private String modifier;/*** 修改日期*/private Date modifiedtime;/*** 创建日期*/private Date creationtime;/*** 组织*/@Column(name = "id_own_org")private String idOwnOrg;/*** 员工ID*/@Column(name = "id_employee")private String idEmployee;@Column(name = "is_del")private Byte isDel;/*** 向导默认开关:0默认关闭,1默认打开*/@Column(name = "is_guide_open")private Byte isGuideOpen;/*** 维小宝用户ID*/@Column(name = "id_wxb_user")private String idWxbUser;/*** 维小宝店铺ID*/@Column(name = "id_wxb_station")private String idWxbStation;private String openid;/*** 是否限定PC登录设备 0 不选中 1 选中*/@Column(name = "limit_mac")private Byte limitMac;/*** 获取主键** @return pk_id - 主键*/public String getPkId() {return pkId;}/*** 设置主键** @param pkId 主键*/public void setPkId(String pkId) {this.pkId = pkId;}/*** 获取用户名** @return username - 用户名*/public String getUsername() {return username;}/*** 设置用户名** @param username 用户名*/public void setUsername(String username) {this.username = username;}/*** @return cell_phone*/public String getCellPhone() {return cellPhone;}/*** @param cellPhone*/public void setCellPhone(String cellPhone) {this.cellPhone = cellPhone;}/*** 获取密码** @return password - 密码*/public String getPassword() {return password;}/*** 设置密码** @param password 密码*/public void setPassword(String password) {this.password = password;}/*** 获取是否管理员** @return is_admin - 是否管理员*/public Byte getIsAdmin() {return isAdmin;}/*** 设置是否管理员** @param isAdmin 是否管理员*/public void setIsAdmin(Byte isAdmin) {this.isAdmin = isAdmin;}/*** 获取角色ID** @return id_role - 角色ID*/public String getIdRole() {return idRole;}/*** 设置角色ID** @param idRole 角色ID*/public void setIdRole(String idRole) {this.idRole = idRole;}/*** 获取创建人** @return creator - 创建人*/public String getCreator() {return creator;}/*** 设置创建人** @param creator 创建人*/public void setCreator(String creator) {this.creator = creator;}/*** 获取修改人** @return modifier - 修改人*/public String getModifier() {return modifier;}/*** 设置修改人** @param modifier 修改人*/public void setModifier(String modifier) {this.modifier = modifier;}/*** 获取修改日期** @return modifiedtime - 修改日期*/public Date getModifiedtime() {return modifiedtime;}/*** 设置修改日期** @param modifiedtime 修改日期*/public void setModifiedtime(Date modifiedtime) {this.modifiedtime = modifiedtime;}/*** 获取创建日期** @return creationtime - 创建日期*/public Date getCreationtime() {return creationtime;}/*** 设置创建日期** @param creationtime 创建日期*/public void setCreationtime(Date creationtime) {this.creationtime = creationtime;}/*** 获取组织** @return id_own_org - 组织*/public String getIdOwnOrg() {return idOwnOrg;}/*** 设置组织** @param idOwnOrg 组织*/public void setIdOwnOrg(String idOwnOrg) {this.idOwnOrg = idOwnOrg;}/*** 获取员工ID** @return id_employee - 员工ID*/public String getIdEmployee() {return idEmployee;}/*** 设置员工ID** @param idEmployee 员工ID*/public void setIdEmployee(String idEmployee) {this.idEmployee = idEmployee;}/*** @return is_del*/public Byte getIsDel() {return isDel;}/*** @param isDel*/public void setIsDel(Byte isDel) {this.isDel = isDel;}/*** 获取向导默认开关:0默认关闭,1默认打开** @return is_guide_open - 向导默认开关:0默认关闭,1默认打开*/public Byte getIsGuideOpen() {return isGuideOpen;}/*** 设置向导默认开关:0默认关闭,1默认打开** @param isGuideOpen 向导默认开关:0默认关闭,1默认打开*/public void setIsGuideOpen(Byte isGuideOpen) {this.isGuideOpen = isGuideOpen;}/*** 获取维小宝用户ID** @return id_wxb_user - 维小宝用户ID*/public String getIdWxbUser() {return idWxbUser;}/*** 设置维小宝用户ID** @param idWxbUser 维小宝用户ID*/public void setIdWxbUser(String idWxbUser) {this.idWxbUser = idWxbUser;}/*** 获取维小宝店铺ID** @return id_wxb_station - 维小宝店铺ID*/public String getIdWxbStation() {return idWxbStation;}/*** 设置维小宝店铺ID** @param idWxbStation 维小宝店铺ID*/public void setIdWxbStation(String idWxbStation) {this.idWxbStation = idWxbStation;}/*** @return openid*/public String getOpenid() {return openid;}/*** @param openid*/public void setOpenid(String openid) {this.openid = openid;}/*** 获取是否限定PC登录设备 0 不选中 1 选中** @return limit_mac - 是否限定PC登录设备 0 不选中 1 选中*/public Byte getLimitMac() {return limitMac;}/*** 设置是否限定PC登录设备 0 不选中 1 选中** @param limitMac 是否限定PC登录设备 0 不选中 1 选中*/public void setLimitMac(Byte limitMac) {this.limitMac = limitMac;}}
复制代码
    package com.f6car.base.vo.user;import com.f6car.base.common.Vo;import java.util.Date;import java.math.BigDecimal;/*** Created by qixiaobo on 2017-11-21.*/public class TbUserVo extends Vo {private static final long serialVersionUID = -6920934492324729614L;private String   pkId;private String   username;private String   cellPhone;private String   password;private Byte   isAdmin;private String   idRole;private String   idOwnOrg;private String   idEmployee;private Byte   isDel;private Byte   isGuideOpen;private String   idWxbUser;private String   idWxbStation;private String   openid;private Byte   limitMac;public void setPkId(String pkId) {this.pkId = pkId;}public String getPkId() {return pkId;}public void setUsername(String username) {this.username = username;}public String getUsername() {return username;}public void setCellPhone(String cellPhone) {this.cellPhone = cellPhone;}public String getCellPhone() {return cellPhone;}public void setPassword(String password) {this.password = password;}public String getPassword() {return password;}public void setIsAdmIn(Byte isAdmin) {this.isAdmin = isAdmin;}public Byte getIsAdmIn() {return isAdmin;}public void setIdRole(String idRole) {this.idRole = idRole;}public String getIdRole() {return idRole;}public void setIdOwnOrg(String idOwnOrg) {this.idOwnOrg = idOwnOrg;}public String getIdOwnOrg() {return idOwnOrg;}public void setIdEmployee(String idEmployee) {this.idEmployee = idEmployee;}public String getIdEmployee() {return idEmployee;}public void setIsDel(Byte isDel) {this.isDel = isDel;}public Byte getIsDel() {return isDel;}public void setIsGuIdeOpen(Byte isGuideOpen) {this.isGuideOpen = isGuideOpen;}public Byte getIsGuIdeOpen() {return isGuideOpen;}public void setIdWxbUser(String idWxbUser) {this.idWxbUser = idWxbUser;}public String getIdWxbUser() {return idWxbUser;}public void setIdWxbStatIon(String idWxbStation) {this.idWxbStation = idWxbStation;}public String getIdWxbStatIon() {return idWxbStation;}public void setOpenid(String openid) {this.openid = openid;}public String getOpenid() {return openid;}public void setLimitMac(Byte limitMac) {this.limitMac = limitMac;}public Byte getLimitMac() {return limitMac;}}
复制代码
    package com.f6car.base.so.user;import com.f6car.base.common.So;/*** Created by qixiaobo on 2017-11-21.*/public class TbUserSo extends So {private static final long serialVersionUID = -6920934492324729614L;}
复制代码
    package com.f6car.base.service.user;import com.f6car.base.vo.user.TbUserVo;import com.f6car.base.so.user.TbUserSo;import com.f6car.base.common.Service;/*** Created by qixiaobo on 2017-11-21.*/public interface TbUserService extends Service<TbUserVo,TbUserSo> {}package com.f6car.base.service.impl.user;import com.f6car.base.dao.user.TbUserMapper;import com.f6car.base.po.user.TbUser;import com.f6car.base.vo.user.TbUserVo;import com.f6car.base.so.user.TbUserSo;import com.f6car.base.service.user.TbUserService;import com.f6car.base.core.AbstractService;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;/*** Created by qixiaobo on 2017-11-21.*/@Service@Transactional(rollbackFor = Exception.class)public class TbUserServiceImpl extends AbstractService<TbUser,TbUserVo,TbUserSo> implements TbUserService {@Resourceprivate TbUserMapper tbUserMapper;}
复制代码
    package com.f6car.base.controller.user;import com.f6car.base.common.Result;import com.f6car.base.common.ResultGenerator;import com.f6car.base.vo.user.TbUserVo;import com.f6car.base.so.user.TbUserSo;import com.f6car.base.service.user.TbUserService;import com.f6car.base.controller.base.AbstractRestController;import com.github.pagehelper.PageHelper;import com.github.pagehelper.PageInfo;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;import java.io.Serializable;import java.util.List;/*** Created by qixiaobo on 2017-11-21.*/@RestController@RequestMapping("user")public class TbUserController extends AbstractRestController<TbUserVo, TbUserSo> {@Resourceprivate TbUserService tbUserService;}复制代码

声明

本代码基于 https://github.com/lihengming/spring-boot-api-project-seed 改造

感谢这位小伙伴~~~

本人项目 https://github.com/qixiaobo/zeus

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

seaborn线性关系数据可视化:时间线图|热图|结构化图表可视化

一、线性关系数据可视化lmplot( ) 表示对所统计的数据做散点图&#xff0c;并拟合一个一元线性回归关系。 lmplot(x, y, data, hueNone, colNone, rowNone, paletteNone,col_wrapNone, height5, aspect1,markers"o", sharexTrue,shareyTrue, hue_orderNone, col_orde…

hdu 1257

http://acm.hdu.edu.cn/showproblem.php?pid1257 题意&#xff1a;有个拦截系统&#xff0c;这个系统在最开始可以拦截任意高度的导弹&#xff0c;但是之后只能拦截不超过这个导弹高度的导弹&#xff0c;现在有N个导弹需要拦截&#xff0c;问你最少需要多少个拦截系统 思路&am…

eda可视化_5用于探索性数据分析(EDA)的高级可视化

eda可视化Early morning, a lady comes to meet Sherlock Holmes and Watson. Even before the lady opens her mouth and starts telling the reason for her visit, Sherlock can tell a lot about a person by his sheer power of observation and deduction. Similarly, we…

我的AWS开发人员考试未通过。 现在怎么办?

I have just taken the AWS Certified Developer - Associate Exam on July 1st of 2019. The result? I failed.我刚刚在2019年7月1日参加了AWS认证开发人员-联考。结果如何&#xff1f; 我失败了。 The AWS Certified Developer - Associate (DVA-C01) has a scaled score …

关系数据可视化gephi

表示对象之间的关系&#xff0c;可通过gephi软件实现&#xff0c;软件下载官方地址https://gephi.org/users/download/ 如何来表示两个对象之间的关系&#xff1f; 把对象变成点&#xff0c;点的大小、颜色可以是它的两个参数&#xff0c;两个点之间的关系可以用连线表示。连线…

Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用

Hyperledger Fabric 1.0 从零开始&#xff08;十&#xff09;——智能合约&#xff08;参阅&#xff1a;Hyperledger Fabric Chaincode for Operators——实操智能合约&#xff09; Hyperledger Fabric 1.0 从零开始&#xff08;十一&#xff09;——CouchDB&#xff08;参阅&a…

css跑道_如何不超出跑道:计划种子的简单方法

css跑道There’s lots of startup advice floating around. I’m going to give you a very practical one that’s often missed — how to plan your early growth. The seed round is usually devoted to finding your product-market fit, meaning you start with no or li…

将json 填入表格_如何将Google表格用作JSON端点

将json 填入表格UPDATE: 5/13/2020 - New Share Dialog Box steps available below.更新&#xff1a;5/13/2020-下面提供了 新共享对话框步骤。 Thanks Erica H!谢谢埃里卡H&#xff01; Are you building a prototype dynamic web application and need to collaborate with …

leetcode 173. 二叉搜索树迭代器

实现一个二叉搜索树迭代器类BSTIterator &#xff0c;表示一个按中序遍历二叉搜索树&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在…

jyputer notebook 、jypyter、IPython basics

1 、修改jupyter默认工作目录&#xff1a;打开cmd&#xff0c;在命令行下指定想要进的工作目录&#xff0c;即键入“cd d/ G:\0工作面试\学习记录”标红部分是想要进入的工作目录。 2、Tab补全 a、在命令行输入表达式时&#xff0c;按下Tab键即可为任意变量&#xff08;对象、…

cookie和session(1)

cookie和session 1.cookie产生 识别用户 HTTP是无状态协议&#xff0c;这就回出现这种现象&#xff1a;当你登录一个页面&#xff0c;然后转到登录网站的另一个页面&#xff0c;服务器无法认识到。或者说两次的访问&#xff0c;服务器不能认识到是同一个客户端的访问&#xff0…

熊猫数据集_为数据科学拆箱熊猫

熊猫数据集If you are already familiar with NumPy, Pandas is just a package build on top of it. Pandas provide more flexibility than NumPy to work with data. While in NumPy we can only store values of single data type(dtype) Pandas has the flexibility to st…

2018年,你想从InfoQ获取什么内容?丨Q言Q语

- Q 言 Q 语 第 三 期 - Q言Q语是 InfoQ 推出的最新板块&#xff0c; 旨在给所有 InfoQer 一个展示观点的平台。 每期一个主题&#xff0c; 不扣帽子&#xff0c;不论对错&#xff0c;不看输赢&#xff0c; 只愿跟有趣的灵魂相遇。 本期话题&#xff1a; 2018年&#xff0c;你想…

特征阻抗输入阻抗输出阻抗_软件阻抗说明

特征阻抗输入阻抗输出阻抗by Milan Mimica米兰米米卡(Milan Mimica) 软件阻抗说明 (Software impedance explained) 数据处理组件之间的阻抗不匹配 (The impedance mismatch between data processing components) It all starts with the simplest signal-processing diagram …

数学建模3

数学建模3 转载于:https://www.cnblogs.com/Forever77/p/11423169.html

leetcode 190. 颠倒二进制位(位运算)

颠倒给定的 32 位无符号整数的二进制位。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中&#xff0c;没有无符号整数类型。在这种情况下&#xff0c;输入和输出都将被指定为有符号整数类型&#xff0c;并且不应影响您的实现&#xff0c;因…

JAVA基础——时间Date类型转换

在java中有六大时间类&#xff0c;分别是&#xff1a; 1、java.util包下的Date类&#xff0c; 2、java.sql包下的Date类&#xff0c; 3、java.text包下的DateFormat类&#xff0c;&#xff08;抽象类&#xff09; 4、java.text包下的SimpleDateFormat类&#xff0c; 5、java.ut…

LeetCode第五天

leetcode 第五天 2018年1月6日 22.(566) Reshape the Matrix JAVA class Solution {public int[][] matrixReshape(int[][] nums, int r, int c) {int[][] newNums new int[r][c];int size nums.length*nums[0].length;if(r*c ! size)return nums;for(int i0;i<size;i){ne…

matplotlib可视化_使用Matplotlib改善可视化设计的5个魔术技巧

matplotlib可视化It is impossible to know everything, no matter how much our experience has increased over the years, there are many things that remain hidden from us. This is normal, and maybe an exciting motivation to search and learn more. And I am sure …

adb 多点触碰_无法触及的神话

adb 多点触碰On Twitter, in Slack, on Discord, in IRC, or wherever you hang out with other developers on the internet, you may have heard some formulation of the following statements:在Twitter上&#xff0c;在Slack中&#xff0c;在Discord中&#xff0c;在IRC…