Mybatis Generator 的使用 一直想试试 mybatis 的代码生成,最近闲来无事,查了些资料,自己搞了下。
Mybatis Generator 支持多种实现方式:
- From a Command Prompt(命令行)
- With Ant(使用Ant )
- With Maven(使用maven)
- With Java(使用java代码)
- with Eclipse(使用Eclipse IDE 工具)
命令行方式 工具准备:
- 数据库驱动(笔者这里使用的是mysql)
- Mybatis Generator的jar包
- 新建 generatorConfig.xml 配置文件
="cn.lovehao.mapper" targetProject="src">
- 新建对应导出路径的文件加(我这里是 src )
新建以后,目录结构如下:
文章图片
在当前目录 启动 命令行(shift + 鼠标右键),选择 (在此处打开powershell)
文章图片
执行结果:
文章图片
表示成功。
文章图片
命令行的方式比较简单,但是有一个问题:表格多的话,一个个table 写比较麻烦。
下面我们来看看 Java 代码的方式
Java 代码方式 【Mybatis Generator 的使用】基于命令行提出的问题,引发的思考:
- 是否可以用Java 代码动态生成 xml 配置文件 ?(可以使用dom4j)
- 是否可以使用Java 代码去调用 Mybatis Generator ?(官方有调用方法)
- 是否可以以web的形式,将生成的代码压缩并下载?(完全可行)
- 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 成功");
}
- 调用 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();
}
- 接下来就是提供下载功能了
我这里选用的是 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 文件中会有重复的代码
推荐阅读
- 框架|Mybatis的一级缓存和二级缓存
- Mybatis日志工厂
- MyBatis的功能架构是怎样的
- Mybatis入门之CRUD
- mybatis之缓存机制
- Mybatis练习(1)
- Java|MyBatis(五)——MyBatis中的缓存机制
- mybatis之脚本解析器
- mybatis|记mybatis查询null字段导致的NPE
- Mybatis 动态查询、插入、修改操作