office tool plus使用方法(office和wps区别)
856
2022-05-30
项目中常常用到代码生成器生成代码,下面介绍velocity代码生成原理,及如何编写代码生成器。
Velocity介绍
Velocity是一个基于Java的模板引擎,基于MVC模型实现,其提供了一个Context容器(相当于Spring的Model),在java代码里面我们可以往容器中存值,然后在vm文件中使用特定的语法获取(相当于Spring页面中取值如freemarker、thymeleaf)。
官网:http://velocity.apache.org/
maven引入
velocity 基本语法
设置变量 #set($foo =“hello”) 取值 $foo
访问对象属性 $user.name ${user.name}
使用
v
a
r
i
获取变量时,如果变量不存在,
V
e
l
o
c
i
t
y
引擎会将其原样输出,通过使用
vari获取变量时,如果变量不存在,Velocity引擎会将其原样输出,通过使用
vari获取变量时,如果变量不存在,Velocity引擎会将其原样输出,通过使用!{}的形式可以将不存在的变量变成空白输出. 见示例 ${notExist} $!{notExistEmpty}
velocity中大小写敏感。
#foreach($i in $list) $i #end
velocity 只会替换变量,所以velocity的语句一般顶行写,以保持文件格式
如上 $i前的空格将会原样输出
#if(condition) ...dosonmething... #elseif(condition) ...dosomething... #else ...dosomething... #end
hello world generator
初始化了VelocityEngine这个模板引擎,对其设置参数进行初始化,指定使用ClasspathResourceLoader来加载vm文件。
在VelocityContext这个Velocity容器中存放对象了。
在.vm文件中我们可以取出这些变量,
Template模板输出 template.merge(ctx,sw)
public class HelloWorldVelocity { public static void main(String[] args) { // 初始化模板引擎 VelocityEngine velocityEngine = new VelocityEngine(); velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); velocityEngine.init(); // 获取模板文件 Template template = velocityEngine.getTemplate("helloVelocity.vm"); // 设置变量 VelocityContext ctx = new VelocityContext(); ctx.put("name", "Velocity"); User user = new User(); user.setName("zhang san"); user.setPhone("18612345678"); ctx.put("user", user); List list = new ArrayList(); list.add("1"); list.add("2"); ctx.put("list", list); // 输出 StringWriter sw = new StringWriter(); template.merge(ctx,sw); System.out.println(sw.toString()); }
resouces目录下的模板文件helloVelocity.vm
#set($foo = 'hello') $foo $name ${notExist} $!{notExistEmpty} $user.name ${user.name} #foreach($i in $list) $i #end
Gitee: https://gitee.com/tg_seahorse/paw-demos/tree/master/paw-generator
Mybatsi-plus官网文档
官网源码Git
MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl模板引擎
参照官网修改的生成代码类
配置信息写在了main方法的开头,项目路径、包名、要生成的表、表前缀
配置数据源 mysql 引入依赖mysql-connector-java
cfg.setFileCreate 文件生成策略,return true 会生成文件,覆盖原有文件。
开启swaggergc.setSwagger2(true);代码使用时需引入swagger依赖
代码生成类
public class CodeGenerator { public static void main(String[] args) { String projectPath = "/Users/rubble/workSpace/paw/paw-demos/paw-generator"; String author = "Rubble"; String packageParent = "com.paw.generator"; String module = "system"; // 多个用,分隔 String tables = "sys_user"; String tablePrefix = "sys_"; // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor(author); gc.setOpen(false); // gc.setSwagger2(true); 实体属性 Swagger2 注解 mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/ry?useUnicode=true&useSSL=false&characterEncoding=utf8"); // dsc.setSchemaName("public"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); pc.setModuleName(module); pc.setParent(packageParent); mpg.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker // String templatePath = "/templates/mapper.xml.ftl"; // 如果模板引擎是 velocity String templatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List
CodeGenerator可以用于日常基于mybatis-plus项目的开发中。
自定义模板
扩展control模板
Mybatis-plus 模板默认位置resources/templates下,可在配置中进行修改templatePath
从git项目或jar包中复制controller.java.vm 增加CRUD的方法,只写了简单的add、list方法,可自行就行扩展,如增加分页查找。
package ${package.Controller}; import java.util.List; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.paw.generator.system.entity.User; import com.paw.generator.system.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; #if(${restControllerStyle}) import org.springframework.web.bind.annotation.RestController; #else import org.springframework.stereotype.Controller; #end #if(${superControllerClassPackage}) import ${superControllerClassPackage}; #end /** *
* $!{table.comment} 前端控制器 *
* * @author ${author} * @since ${date} */ #if(${restControllerStyle}) @RestController #else @Controller #end @RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end") #if(${kotlin}) class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end #else #if(${superControllerClass}) public class ${table.controllerName} extends ${superControllerClass} { #else public class ${table.controllerName} { #end @Autowired private ${table.serviceName} service; @GetMapping("add") public Object add(${entity} entity){ boolean saved = service.save(entity); return entity; } @GetMapping("list") public List<${entity}> list(${entity} entity){ return service.list(new QueryWrapper<>(entity)); } } #end生成代码
/** *
* 用户信息表 前端控制器 *
* * @author Rubble * @since 2021-07-07 */ @RestController @RequestMapping("/system/user") public class UserController { @Autowired private IUserService service; @GetMapping("add") public Object add(User entity){ boolean saved = service.save(entity); return entity; } @GetMapping("list") public List自定义模板hello
配置中增加模板hello.java.vm,定义文件输出位置
String helloTemplatePath = "/templates/hello.java.vm"; focList.add(new FileOutConfig(helloTemplatePath) { @Override public String outputFile (TableInfo tableInfo) { return projectPath + "/src/main/java/" + packageParent.replace(".", File.separator) + File.separator + pc.getModuleName() + File.separator + "entity" + File.separator + "Hello" + tableInfo.getEntityName() + StringPool.DOT_JAVA; } });
最简单的模板
package ${package.Entity}; public class Hello${entity}{ }
执行输出
package com.paw.generator.system.entity; public class HelloUser{ }
mybatis-plus-generator解析
git下载项目,用jdk8, gradle 6.3 编译通过。
自动配置类AutoGenerator, 除datasource外其他均可默认设置。
/** * 配置信息 */ protected ConfigBuilder config; /** * 注入配置 */ protected InjectionConfig injection; /** * 数据源配置 */ private DataSourceConfig dataSource; /** * 数据库表配置 */ private StrategyConfig strategy; /** * 包 相关配置 */ private PackageConfig packageInfo; /** * 模板 相关配置 */ private TemplateConfig template; /** * 全局 相关配置 */ private GlobalConfig globalConfig;
模板引擎
AbstractTemplateEngine 实现了文件的输出controller、service、 entity、mapper。
VelocityTemplateEngine模板引擎
init()初始化VelocityEngine指定文件位置、编码等;
writer引擎模板的渲染 template.merge(new VelocityContext(objectMap), writer);
Map
@Override public @NotNull VelocityTemplateEngine init(@NotNull ConfigBuilder configBuilder) { if (null == velocityEngine) { Properties p = new Properties(); p.setProperty(ConstVal.VM_LOAD_PATH_KEY, ConstVal.VM_LOAD_PATH_VALUE); p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, StringPool.EMPTY); p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8); p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8); p.setProperty("file.resource.loader.unicode", StringPool.TRUE); velocityEngine = new VelocityEngine(p); } return this; } @Override public void writer(@NotNull Map
// objectMap在 AbstractTemplateEngine类中 从配置文件中生成上下文变量加入到context中
objectMap.put的即在模板中可用的属性。
主要属性 PackageInfo, TableInfo
@NotNull public Map
下载源码的方式扩展可以任意的put你想要的属性。
引用jar的方式可以增加全局自定义配置, 模板中使用 ${cfg.abc}
// 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap () { // to do nothing Map
若依(ruoyi)框架中的generator
本文是若依单体项目thymeleaf版本。module: ruoyi-generator.
生成工具通过后台管理界面的方式让用户进行设置,配置信息保存在数据库中,根据配置生成一套CRUD代码,很是方便。
入口控制类GenController preview 预览代码, download 下载zip包,genCode生成代码。
数据库查询配置信息GenTable 加入到VelocityContext中,在vm模板中即可取值
对定义的模板进行渲染 tpl.merge(context, sw)
public Map
Put到VelocityContext中的变量
public static VelocityContext prepareContext(GenTable genTable) { String moduleName = genTable.getModuleName(); String businessName = genTable.getBusinessName(); String packageName = genTable.getPackageName(); String tplCategory = genTable.getTplCategory(); String functionName = genTable.getFunctionName(); VelocityContext velocityContext = new VelocityContext(); velocityContext.put("tplCategory", genTable.getTplCategory()); velocityContext.put("tableName", genTable.getTableName()); velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); velocityContext.put("ClassName", genTable.getClassName()); velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); velocityContext.put("moduleName", genTable.getModuleName()); velocityContext.put("businessName", genTable.getBusinessName()); velocityContext.put("basePackage", getPackagePrefix(packageName)); velocityContext.put("packageName", packageName); velocityContext.put("author", genTable.getFunctionAuthor()); velocityContext.put("datetime", DateUtils.getDate()); velocityContext.put("pkColumn", genTable.getPkColumn()); velocityContext.put("importList", getImportList(genTable)); velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); velocityContext.put("columns", genTable.getColumns()); velocityContext.put("table", genTable); setMenuVelocityContext(velocityContext, genTable); if (GenConstants.TPL_TREE.equals(tplCategory)) { setTreeVelocityContext(velocityContext, genTable); } if (GenConstants.TPL_SUB.equals(tplCategory)) { setSubVelocityContext(velocityContext, genTable); } return velocityContext; }
生成代码的模板,
html: crud的方法add.html,edit.html,list.html,list-tree.html
Java: controller,service,domain,mapper,serviceImpl
Sql:生成菜单用
自定义的mapper.xml
若依框架generator为前端页面框架ruoyi-admin生成了一套完美契合的快速开发的CRUD代码,并支持的用户的选择配置,页面的查询功能都已封装,在此学习,向大神致敬。
总结:
velocity模板引擎分三步,1.初始化 配置模板加载地址;2.放置上下文变量velocityContext;3.渲染模板。
有框架的项目一般会为,框架定制一个代码生成器,以使代码规范化,同时提高开发效率。
个人项目或中小项目开发应用现成框架即可,若不满足需求,要进行修改,了解模板原理,即可快速扩展。
撸文不易,感谢您的鼓励。
Generator Java MyBatis
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。