网站首页 > java教程 正文
本文介绍如何用Java编写高度自定义的代码生成器
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息。
上面这一段话来自Mybatis官网的介绍, 初用Mybatis时感觉这个框架相比于JDBC优雅多了, 用起来也如官网说的非常简单。但是用了一段时间之后, 弊端就慢慢凸显出来了
使用Mybatis时不得不为每个表创建一个Entity.java、Mapper.xml(Mapper可以融合入Dao中)、Dao.java,Service.java 层次很清晰, 但是太多重复性的工作了, 费时间且易于出错
并且当数据库发生一点改动的时候... 苦不堪言
后来出现了自动生成代码的插件, 但是总是不尽人意, 不能随心所欲地控制, 毕竟每个人的需求都不一样
本文就来介绍如何简单的编写一个自己的代码生成器
项目源码
mybatis-generator
代码实现
实现的思路很简单, 首先查询数据库的表结构, 得到列名, 列类型...等信息
创建文件模版, 将这些信息插入模版中, 最后打包模版进压缩包导出
代码实现 一共五个Java类
- TableDO
- ColumnDO
- GeneratorMapper
- GeneratorUtils
- GeneratorService
首先来看两个实体类
TableDO 和 ColumnDO
TableDO 存放表名, 对于的类名, 以及列信息
完整类代码 TableDO.java
public class TableDO { private String tableName; private List<ColumnDO> columns; private String className; private String suffix; // get()... set()... }
ColumnDO 存放列名, 数据库字段类型, 以及对应Java中的属性名和类型
完整类代码 ColumnDO.java
public class ColumnDO { private String columnName; private String dataType; private String attrName; private String attrLowerName; private String attrType; // get()... set()... }
GeneratorMapper
在GeneratorMapper 中, 我们通过表名查询表自动的信息
完整类代码 GeneratorMapper.java
@Mapper public interface GeneratorMapper { @Select("select column_name columnName, data_type dataType from information_schema.columns where table_name = #{tableName} and table_schema = (select database()) order by ordinal_position") List<ColumnDO> listColumns(String tableName); }
GeneratorUtils
在GeneratorUtils 中进行类信息与模版之间的转换
完整类代码 GeneratorUtils.java
将表信息放入Velocity模版的上下文中
Map<String, Object> map = new HashMap<>(); map.put("tableName", table.getTableName()); map.put("className", table.getClassName()); map.put("pathName", getPackageName().substring(getPackageName().lastIndexOf(".") + 1)); map.put("columns", table.getColumns()); map.put("package", getPackageName()); map.put("suffix", table.getSuffix()); Properties prop = new Properties(); prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.init(prop); VelocityContext context = new VelocityContext(map);
添加模版
List<String> templates = new ArrayList<>(); templates.add("mybatis/Model.java.vm"); templates.add("mybatis/Query.java.vm"); templates.add("mybatis/Dao.java.vm"); templates.add("mybatis/Mapper.xml.vm"); templates.add("mybatis/Service.java.vm");
编译模版
StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, "UTF-8"); tpl.merge(context, sw);
Utils类完成了生成代码的主要工作, 但是代码也是比较简单的
GeneratorService
在Service 中注入Mapper 查询列信息, 并用Utils生成代码, 然后导出压缩包
完整类代码 GeneratorService.java
@Service public class GeneratorService { @Resource private GeneratorMapper generatorMapper; @Resource private Environment environment; public void generateZip(String[] tableNames, String zipPath) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(outputStream); for (String tableName : tableNames) { TableDO table = new TableDO(); table.setTableName(tableName); table.setColumns(generatorMapper.listColumns(tableName)); GeneratorUtils.generatorCode(table, zip,getConfig()); } IOUtils.closeQuietly(zip); FileOutputStream file = new FileOutputStream(zipPath); file.write(outputStream.toByteArray()); file.close(); } // getConfig ... }
VM模版
自己写代码生成器的好处就是, 可以根据需求定制自己的模版, 下面是我的几个模版可以供参考
- Mapper.xml.vm
- Dao.java.vm
- Service.java.vm
- Model.java.vm
- Query.java.vm
生成的代码是在commons-mybatis架构下使用的
Dao.java.vm
package ${package}.database.dao; import ${package}.database.model.${className}${suffix}; import org.apache.ibatis.annotations.Mapper; import org.laziji.commons.mybatis.dao.${suffix}Dao; @Mapper public interface ${className}Dao extends ${suffix}Dao<${className}${suffix}> { }
其余模版
使用
配置文件
在resources下创建application-${name}.yml文件, ${name}随意, 例如: application-example.yml, 可创建多个
配置文件内容如下, 填入数据库配置, 以及生成代码的包名, 源文件路径
spring: datasource: url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxxx?characterEncoding=utf-8 username: xxxxxx password: xxxxxx generator: package: com.xxx.xxx resources: mapper
Test
在test文件下创建测试类
- @ActiveProfiles("example")中填入刚才配置文件名的name
- tableNames需要生成的表, 可以多个
- zipPath 代码导出路径 运行测试方法即可
package pg.laziji.generator; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; import pg.laziji.generator.mybatis.GeneratorService; import javax.annotation.Resource; import java.io.IOException; @ActiveProfiles("example") @RunWith(SpringRunner.class) @SpringBootTest public class ExampleTest { @Resource private GeneratorService generatorService; @Test public void test() throws IOException { String[] tableNames = new String[]{"example_table1", "example_table2"}; String zipPath = "/home/code.zip"; generatorService.generateZip(tableNames,zipPath); } }
猜你喜欢
- 2024-10-04 谷歌Bard可使用C++、Python等20多种语言生成、调试和注释代码
- 2024-10-04 java代码生成word文档(1)(java代码生成xml文件)
- 2024-10-04 GitHub 2W 星:一键生成前后端代码
- 2024-10-04 java 数字签名以及证书生成(电子签章java 数字证书)
- 2024-10-04 【Spring系列】10 MyBatis-Plus 如何自动生成代码 #java
- 2024-10-04 一键生成前后端代码,一个36k星的企业级低代码平台
- 2024-10-04 推荐一个基于SpringBoot + Mybatis + Vue的代码生成器
- 2024-10-04 一个简单的代码生成器(代码生成器思路)
- 2024-10-04 Java 开源的支持多种sql的基于spring boot的代码生成器的调试
- 2024-10-04 java开发开源工具,api文档自动生成工具
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)