基于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.pswp.cn/news/391549.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391549.shtml
英文地址,請注明出處:http://en.pswp.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…