This article explains how to write a highly customized code generator in Java
MyBatis is an excellent persistence layer framework that supports customized SQL, stored procedures, and advanced mapping. MyBatis avoids almost all of the JDBC code and manual setting of parameters and fetching result sets. MyBatis can configure and map native information using simple XML or annotations.
This paragraph comes from the introduction of Mybatis official website. When I first use Mybatis, I feel that this framework is much more elegant than JDBC, and it is very simple to use as the official website says. But after a period of use, the disadvantages gradually become apparent
Java, mapper. XML (Mapper can be merged into Dao), Dao.java, service. Java hierarchy is very clear, but too much repetitive work, time consuming and error prone
And when the database changes a bit… miserable
Plugins that generate code automatically came along, but they weren’t always easy to control because everyone’s needs were different
This article explains how to write your own code generator easily
Program source code
mybatis-generator
Code implementation
The idea is very simple, first query database table structure, get column name, column type… Information such as
Create a file template, insert this information into the template, and finally package the template into a compressed package and export it
The code implements a total of five Java classes
TableDO
ColumnDO
GeneratorMapper
GeneratorUtils
GeneratorService
Let’s start with two entity classes
TableDO and ColumnDO
TableDO holds the table name, the class name, and column information
In GeneratorMapper, we query for automatic information about a table by its name
The complete class code generatorMapper.java
@MapperpublicinterfaceGeneratorMapper{
@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);
}
Copy the code
GeneratorUtils
Converts class information to and from templates in GeneratorUtils
The complete class code generatorutils.java
Put the table information into the context of the Velocity template
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);
Copy the code
Add the template
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");
Copy the code
Compiling templates
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, "UTF-8");
tpl.merge(context, sw);
Copy the code
The Utils class does most of the work of generating code, but the code is relatively simple
GeneratorService
The Mapper query column information is injected into the Service, the code is generated with Utils, and the compressed package is exported
The complete class code generatorService.java
@ServicepublicclassGeneratorService{
@Resourceprivate GeneratorMapper generatorMapper;
@Resourceprivate Environment environment;
publicvoidgenerateZip(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 ...
}
Copy the code
The VM template
The great thing about writing your own code generator is that you can customize your own templates to your needs. Here are a few of my templates for reference
Mapper.xml.vm
Dao.java.vm
Service.java.vm
Model.java.vm
Query.java.vm
The generated code is used under the Commons-Mybatis architecture
Create application-${name}. Yml file under Resources. ${name} = ${name}
The configuration file contains the following contents, including the database configuration, the package name of the generated code, and the source file path