Java实现Mybatis代码生成器
本文介绍如何用Java编写高度自定义的代码生成器
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息。
上面这一段话来自Mybatis官网
的介绍, 初用Mybatis时感觉这个框架相比于JDBC优雅多了, 用起来也如官网说的非常简单。但是用了一段时间之后, 弊端就慢慢凸显出来了
使用Mybatis时不得不为每个表创建一个Entity.java
、Mapper.xml(Mapper可以融合入Dao中)
、Dao.java
,Service.java
层次很清晰, 但是太多重复性的工作了, 费时间且易于出错
并且当数据库发生一点改动的时候… 苦不堪言
后来出现了自动生成代码的插件, 但是总是不尽人意, 不能随心所欲地控制, 毕竟每个人的需求都不一样
本文就来介绍如何简单的编写一个自己的代码生成器
项目源码
代码实现
实现的思路很简单, 首先查询数据库的表结构, 得到列名, 列类型...
等信息
创建文件模版, 将这些信息插入模版中, 最后打包模版进压缩包导出
代码实现 一共五个Java类
- TableDO
- ColumnDO
- GeneratorMapper
- GeneratorUtils
- GeneratorService
首先来看两个实体类
TableDO 和 ColumnDO
TableDO 存放表名, 对于的类名, 以及列信息
完整类代码 TableDO.java
1 | public class TableDO { |
ColumnDO 存放列名, 数据库字段类型, 以及对应Java中的属性名和类型
完整类代码 ColumnDO.java
1 | public class ColumnDO { |
GeneratorMapper
在GeneratorMapper 中, 我们通过表名查询表字段的信息
完整类代码 GeneratorMapper.java
1 |
|
GeneratorUtils
在GeneratorUtils 中进行类信息与模版之间的转换
完整类代码 GeneratorUtils.java
将表信息放入Velocity
模版的上下文中
1 | Map<String, Object> map = new HashMap<>(); |
添加模版
1 | List<String> templates = new ArrayList<>(); |
编译模版
1 | StringWriter sw = new StringWriter(); |
Utils类完成了生成代码的主要工作, 但是代码也是比较简单的
GeneratorService
在Service 中注入Mapper 查询列信息, 并用Utils生成代码, 然后导出压缩包
完整类代码 GeneratorService.java
1 |
|
VM模版
自己写代码生成器的好处就是, 可以根据需求定制自己的模版, 下面是我的几个模版可以供参考
- Mapper.xml.vm
- Dao.java.vm
- Service.java.vm
- Model.java.vm
- Query.java.vm
生成的代码是在commons-mybatis架构下使用的
Dao.java.vm
1 | package ${package}.database.dao; |
…
使用
配置文件
在resources
下创建application-${name}.yml
文件, ${name}
随意, 例如: application-example.yml
, 可创建多个
配置文件内容如下, 填入数据库配置, 以及生成代码的包名, 源文件路径
1 | spring: |
Test
在test文件下创建测试类
@ActiveProfiles("example")
中填入刚才配置文件名的name
tableNames
需要生成的表, 可以多个zipPath
代码导出路径
运行测试方法即可1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package 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;
public class ExampleTest {
private GeneratorService generatorService;
public void test() throws IOException {
String[] tableNames = new String[]{"example_table1", "example_table2"};
String zipPath = "/home/code.zip";
generatorService.generateZip(tableNames,zipPath);
}
}