Java实现Mybatis代码生成器

栏目: Java · 发布时间: 7年前

内容简介:本文介绍如何用Java编写高度自定义的代码生成器MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息。上面这一段话来自

本文介绍如何用 Java 编写高度自定义的代码生成器

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL 、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息。

上面这一段话来自 Mybatis官网 的介绍, 初用Mybatis时感觉这个框架相比于JDBC优雅多了, 用起来也如官网说的非常简单。但是用了一段时间之后, 弊端就慢慢凸显出来了

使用Mybatis时不得不为每个表创建一个 Entity.javaMapper.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);
        }
    }
    

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro JavaScript Techniques

Pro JavaScript Techniques

John Resig / Apress / 2006-12-13 / USD 44.99

Pro JavaScript Techniques is the ultimate JavaScript book for the modern web developer. It provides everything you need to know about modern JavaScript, and shows what JavaScript can do for your web s......一起来看看 《Pro JavaScript Techniques》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

html转js在线工具
html转js在线工具

html转js在线工具