Mybatis Generator 的使用

Mybatis Generator 的使用 一直想试试 mybatis 的代码生成,最近闲来无事,查了些资料,自己搞了下。
Mybatis Generator 支持多种实现方式:

  1. From a Command Prompt(命令行)
  2. With Ant(使用Ant )
  3. With Maven(使用maven)
  4. With Java(使用java代码)
  5. with Eclipse(使用Eclipse IDE 工具)
笔者这里试了两种实现方式,分别是From a Command Prompt 与With Java
命令行方式 工具准备:
  1. 数据库驱动(笔者这里使用的是mysql)
  2. Mybatis Generator的jar包
实现步骤:
  1. 新建 generatorConfig.xml 配置文件
="cn.lovehao.mapper" targetProject="src">

  1. 新建对应导出路径的文件加(我这里是 src )
    新建以后,目录结构如下:
Mybatis Generator 的使用
文章图片

在当前目录 启动 命令行(shift + 鼠标右键),选择 (在此处打开powershell)
Mybatis Generator 的使用
文章图片

执行结果:
Mybatis Generator 的使用
文章图片

表示成功。
Mybatis Generator 的使用
文章图片

命令行的方式比较简单,但是有一个问题:表格多的话,一个个table 写比较麻烦
下面我们来看看 Java 代码的方式
Java 代码方式 【Mybatis Generator 的使用】基于命令行提出的问题,引发的思考:
  1. 是否可以用Java 代码动态生成 xml 配置文件 ?(可以使用dom4j)
  2. 是否可以使用Java 代码去调用 Mybatis Generator ?(官方有调用方法)
  3. 是否可以以web的形式,将生成的代码压缩并下载?(完全可行)
实现步骤:
  1. java 代码生成 generatorConfig.xml 文件
    笔者在考虑做这个的时候,对 java 生成 xml 的代码有些生疏了,所以又去温习了一遍。一开始使用的是 dom,后来发现dom 不好添加 文档声明,就是 标签。最后选用 dom4j 来生成 xml。具体代码如下:
import java.io.File; import java.io.IOException; import java.util.List; public class GeneratorInfo {private String driverPath; //数据库驱动路径private String generateXmlPath; //生成的XML 文件的保存路径private String generateJavaFilePath; // 生成的java文件保存路径private String entityPath; //实体类的包路径private String daoPath; //dao层的包路径private String mapperPath; //mybatis 映射xml文件路径private List> tableNames; getter... sertter... }

public static void createXml(GeneratorInfo info) throws IOException {//1.创建document 对象 Document document = DocumentHelper.createDocument(); //2.添加文档声明 document.addDocType("generatorConfiguration", "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" ,"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"); //3.创建 根节点 generatorConfiguration Element root = document.addElement("generatorConfiguration"); //4.添加数据库驱动节点 与 context节点 Element classPathEntry = root.addElement("classPathEntry"); Element context = root.addElement("context"); //5. 设置驱动地址 classPathEntry.addAttribute("location",info.getDriverPath()); //6. 设置 context 的 id 以及 targetRuntime context.addAttribute("id","DB2Tables"); context.addAttribute("targetRuntime","MyBatis3"); //7. context 添加子节点 commentGenerator Element commentGenerator =context.addElement("commentGenerator"); //7.1设置属性1 Element property1 = commentGenerator.addElement("property"); property1.addAttribute("name","suppressDate"); property1.addAttribute("value","true"); //7.2设置属性2 Element property2 =commentGenerator.addElement("property"); property2.addAttribute("name","suppressAllComments"); property2.addAttribute("value","true"); //8. context 添加子节点 jdbcConnection Element jdbcConnection = context.addElement("jdbcConnection"); //8.1 设置参数 jdbcConnection.addAttribute("driverClass",DRIVER_CLASS); jdbcConnection.addAttribute("connectionURL",JDBC_URL); jdbcConnection.addAttribute("userId",USER_ID); jdbcConnection.addAttribute("password",PASSWORD); //8.2 设置属性 Element jdbcConnectionProperty = jdbcConnection.addElement("property"); jdbcConnectionProperty.addAttribute("name","nullCatalogMeansCurrent"); jdbcConnectionProperty.addAttribute("value","true"); //9. 添加 javaTypeResolver 节点 Element javaTypeResolver = context.addElement("javaTypeResolver"); ElementjavaTypeResolverProperty = javaTypeResolver.addElement("property"); javaTypeResolverProperty.addAttribute("name","forceBigDecimals"); javaTypeResolverProperty.addAttribute("value","false"); //10.添加 javaModelGenerator 节点 (生成model类存放位置) Element javaModelGenerator = context.addElement("javaModelGenerator"); javaModelGenerator.addAttribute("targetPackage",info.getEntityPath()); javaModelGenerator.addAttribute("targetProject",info.getGenerateJavaFilePath()); //10.1 Element javaModelGeneratorProperty1 = javaModelGenerator.addElement("property"); javaModelGeneratorProperty1.addAttribute("name","enableSubPackages"); javaModelGeneratorProperty1.addAttribute("value","true"); //10.2 Element javaModelGeneratorProperty2 = javaModelGenerator.addElement("property"); javaModelGeneratorProperty2.addAttribute("name","trimStrings"); javaModelGeneratorProperty2.addAttribute("value","true"); //11.添加 sqlMapGenerator 节点 (生成映射文件存放位置) Element sqlMapGenerator = context.addElement("sqlMapGenerator"); sqlMapGenerator.addAttribute("targetPackage",info.getMapperPath()); sqlMapGenerator.addAttribute("targetProject",info.getGenerateJavaFilePath()); Element sqlMapGeneratorProperty1 = sqlMapGenerator.addElement("property"); sqlMapGeneratorProperty1.addAttribute("name","enableSubPackages"); sqlMapGeneratorProperty1.addAttribute("value","true"); //12.添加 javaClientGenerator 节点 (生成Dao类存放位置) Element javaClientGenerator = context.addElement("javaClientGenerator"); javaClientGenerator.addAttribute("type","XMLMAPPER"); javaClientGenerator.addAttribute("targetPackage",info.getDaoPath()); javaClientGenerator.addAttribute("targetProject",info.getGenerateJavaFilePath()); Element javaClientGeneratorProperty1 = javaClientGenerator.addElement("property"); javaClientGeneratorProperty1.addAttribute("name","enableSubPackages"); javaClientGeneratorProperty1.addAttribute("value","true"); //13.配置表格 for(String s : info.getTableNames()){ Element table =context.addElement("table"); table.addAttribute("tableName",s); table.addAttribute("domainObjectName",mapObjectStr(s)); table.addAttribute("enableCountByExample","false"); table.addAttribute("enableUpdateByExample","false"); table.addAttribute("enableDeleteByExample","false"); table.addAttribute("enableSelectByExample","false"); table.addAttribute("selectByExampleQueryId","false"); } //14.设置生成xml的格式 OutputFormat format = OutputFormat.createPrettyPrint(); //设置编码格式 format.setEncoding("UTF-8"); //15.生成xml文件 String path =GeneratorUtils.class.getResource("/").getFile(); File file = new File(path+ "generatorConfig.xml"); XMLWriter writer = new XMLWriter(new FileOutputStream(file),format); //设置是否转义,默认使用转义字符 writer.setEscapeText(false); writer.write(document); writer.close(); System.out.println("生成xml 成功"); }

  1. 调用 Mybatis Generator 提供的生成方法
//生成代码 List> warnings = new ArrayList>(); boolean overwrite = true; ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = null; try { //我之前的xml文件直接生成到 classpath String path2 =GeneratorUtils.class.getResource("/").getFile(); File file2 = new File(path2 + "generatorConfig.xml"); config = cp.parseConfiguration(file2); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); System.out.println(warnings); } catch (Exception e) { e.printStackTrace(); }

  1. 接下来就是提供下载功能了
    我这里选用的是 jdk 提供的压缩功能.自己实现了一个utils 类
public class ZIPUtils {/** * @param sourceFilePath压缩源路径 * @param toFilePath压缩目的路径 */ public static void compress(String sourceFilePath,String toFilePath){ File source = new File(sourceFilePath); if(!source.exists()){ throw new RuntimeException(sourceFilePath + "不存在"); }File zipFile = new File(toFilePath); try{ FileOutputStream fos = new FileOutputStream(zipFile); ZipOutputStream zos = new ZipOutputStream(fos); String baseDir = ""; compressbyType(source, zos, baseDir); zos.close(); } catch (IOException e) { e.printStackTrace(); }}private static void compressbyType(File source, ZipOutputStream zos, String baseDir) {if(!source.exists()){ return; } System.out.println("压缩路径" + baseDir + source.getName()); //判断文件是否是文件,如果是文件调用compressFile方法,如果是路径,则调用compressDir方法;if(source.isFile()){ compressFile( source, zos, baseDir); } else if (source.isDirectory()) { //src是文件夹,调用此方法 compressDir(source, zos, baseDir); }}private static void compressFile(File file, ZipOutputStream zos, String baseDir) { if (!file.exists()) return; try { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); ZipEntry entry = new ZipEntry(baseDir + file.getName()); zos.putNextEntry(entry); int count; byte[] buf = new byte[1024]; while ((count = bis.read(buf)) != -1) { zos.write(buf, 0, count); } bis.close(); } catch (Exception e) { // TODO: handle exception} }private static void compressDir(File dir, ZipOutputStream zos, String baseDir) { if (!dir.exists()) return; File[] files = dir.listFiles(); if(files.length == 0){ try { zos.putNextEntry(new ZipEntry(baseDir + dir.getName()+File.separator)); } catch (IOException e) { e.printStackTrace(); } } for (File file : files) { compressbyType(file, zos, baseDir + dir.getName() + File.separator); } } }

在 service 服务层的代码成成好的时候,调用工具类的压缩方法即可
@Autowired TablesService tablesService; @Override public boolean generator(GeneratorInfo info) { //获取当前数据库中所有的表名 info.setTableNames(tablesService.getAllTablesName()); try { GeneratorUtils.createXml(info); String path = info.getGenerateJavaFilePath(); ZIPUtils.compress(path,path+".zip"); //TODO:删除生成的文件 //如果多次生成,mapper.xml 文件中会有重复 //这里把文件删除,每次重新生成 File file = new File(path); deleteDir(file); return true; } catch (IOException e) { e.printStackTrace(); } return false; }

这里需要注意的是,压缩文件生成好以后,一定要将之前生成的java代码删除掉。
不然多次生成代码的时候,mapper 文件中会有重复的代码

    推荐阅读