Java的MyBatis框架中MyBatis Generator代码生成器的用法
作者:红烧狮子头
关于Mybatis Generator
MyBatis Generator (MBG) 是一个Mybatis的代码生成器 MyBatis 和 iBATIS. 他可以生成Mybatis各个版本的代码,和iBATIS 2.2.0版本以后的代码。 他可以内省数据库的表(或多个表)然后生成可以用来访问(多个)表的基础对象。 这样和数据库表进行交互时不需要创建对象和配置文件。 MBG的解决了对数据库操作有最大影响的一些简单的CRUD(插入,查询,更新,删除)操作。 您仍然需要对联合查询和存储过程手写SQL和对象。
MyBatis Generator 会生成:
匹配表结构的Java POJO,可能包括:
- 一个和表主键匹配的类(如果存在主键[注:只有联合主键会有])
- 一个包含了非主键字段的类(BLOB字段除外[注:单字段做主键时这里会包含])
- 一个包含了BLOB字段的类 (如果表包含了BLOB字段)
- 一个允许动态查询、更新和删除的类[注:指的是Example查询]
这些类之间会有适当的继承关系。 请注意可以配置生成器来生成不同类型的 POJO 的层次结构。 例如,如果您愿意您可能会选择针对每个表生成一个单独的实体对象。
MyBatis/iBATIS 兼容 SQL 映射 XML 文件。MBG 在配置中为每个表简单的 CRUD 操作生成 SQL。 生成的 SQL 语句包括:
- insert (插入)
- update by primary key (根据主键更新记录)
- update by example (根据条件更新记录)
- delete by primary key (根据主键删除记录)
- delete by example (根据条件删除记录)
- select by primary key (根据主键查询记录)
- select by example (根据条件查询记录集)
- count by example (根据条件查询记录总数)
根据表的结构,生成的这些语句会有不同的变化(例如,如果表中没有主键,那么 MBG 将不会生成update by primary key方法)。
Java客户端类会适当的使用上面的对象,生成Java客户端类时可选的。 MBG会为MyBatis 3.x生成如下客户端类:
一个可以和MyBatis 3.x一起使用的mapper接口类
MBG会为iBATIS 2.x生成如下的客户端类:
符合 Spring 框架的DAO类。
只使用iBATIS SQL映射API的DAO。 这种DAO可以通过下面两种方式生成:提供SqlMapClient通过构造方法或者setter注入。
符合iBATIS DAO 框架的DAO (iBATIS可选的一部分,这一框架已经过时,我们建议您使用Spring框架替代)。
MyBatis generator 可以在迭代开发环境中良好的运行, 在持续的构建环境中作为一个ant任务或maven插件。 运行MBG时要记住以下重要的事:
MBG 会自动合并已经存在并且和新生成的文件重名的 XML。MBG 不会覆盖您对已经生成xml所做的修改。 您可以反复的运行而不必担心失去您自定义的更改。 MBG 将取代所有以前运行中生成的 XML 元素。
MBG 不会 合并 Java 文件,他可以覆盖已经存在的文件或者保存新生成的文件为一个不同的唯一的名字。 您可以手动合并这些更改。 当您使用Eclipse 插件时, MBG 可以自动合并 Java 文件.
基本用法
MBG的运行主要依靠一份XML配置文件,首先我们可以重新新建一个项目名为MybatisGenerator,新建3个包分别名叫config,david.test,与david.mbg,config包主要存放真正的Mybatis里面需要用到的配置文件,可以把前几章中项目中的mybatis_demo_config.xml拷贝过来放在这个目录下,等等用作测试程序之用,david.test顾名思义就是存放以下常用的方法和测试程序大家也可以吧前几章中用到MybatisUtils工具类拿过来,新建好相应的MainFunction以备测试之用。而最后的david.mbg中就是我们今天要配置的XML,MBG生成配置文件。
如图所示,我们在下面新建好一个名为mbg_configuration.xml的配置文件,详情如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <classPathEntry location="./lib/mysql-connector-java-5.1.26-bin.jar" /> <context id="mybatisDemoForMysql" targetRuntime="MyBatis3"> <!-- 控制注释 --> <commentGenerator> <!-- 是否去除所有自动生成的注释文件 --> <property name="suppressAllComments" value="true" /> <!-- 是否去除所有自动生成的文件的时间戳,默认为false --> <property name="suppressDate" value="true" /> </commentGenerator> <!-- 控制数据库 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis_db?characterEncoding=utf8" userId="root" password="david0110" /> <javaTypeResolver> <!-- 把jdbc中的decimal与numberic类型转化为integer类型 --> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- 数据库表对应的model --> <javaModelGenerator targetPackage="david.model" targetProject="src"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- 控制Model的xmlMapper文件 --> <sqlMapGenerator targetPackage="david.mappers" targetProject="src"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- 控制mapper接口 --> <javaClientGenerator targetPackage="david.inter" type="XMLMAPPER" targetProject="src"> <property name="enableSubPackages" value="true" /> <property name="methodNameCalculator" value="extended" /> </javaClientGenerator> <!-- schema你的数据库,tableName表明,domainObjectName对应你的javabean类名,是否生成相应的example --> <table schema="mybatis_db" tableName="visitor" domainObjectName="Visitor" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> <generatedKey column="id" sqlStatement="MySql" /> <columnOverride column="name" property="visitor_name" /> <ignoreColumn column="status" delimitedColumnName="false" /> </table> </context> </generatorConfiguration>
大家可以注意到其实主要是这几个节点
<classPathEntry>=> 存放jdbc驱动包的位置,可以采用相对路径,也可以采用绝对路径,此处示例中采用了相对路径
<context>=>对应一个数据库下所有表的配置,可以有多个context,一个配置mysql,一个配置oracle。
<context>节点下主要有:
<commentGenerator> => 注释生成节点,此示例中下的2个子节点分表代表
suppressAllComments => 是否去除所有自动生成的注释文件
suppressDate => 是否去除所有自动生成的文件的时间戳,默认为false
<jdbcConnection> => 数据库连接配置信息
<javaTypeResolver> => 把jdbc中的decimal与numberic类型转化为java.math.BigDeciaml形式表示
<javaModelGenerator> => 配置你的POJO实体类,targetPackage="david.model",对应你的报名,可以自己根据实际业务取名,targetProject="src",在Eclipse环境下,指代的是项目和源文件夹的路径一般是指src目录,你的包都会新建在这个目录下,如果不是Eclipse环境,此处的值应该是个实际存在的文件系统路径,如果指定的路径不存在会报错,因为MBG不会自己创建相应的文件夹
<sqlMapGenerator> => 配置生成相应的实体Mapper.xml,对于Mapper3.X我们需要把type="XMLMAPPER"
<javaClientGenerator> => 配置生成相应的接口类,对应与Mapper.xml中的一系列CRUD方法SQL语句
<table> => 配置相应的数据库,对应的表明与想要生成领域类名(也就是实体类名字),此示例中我关闭了所有不必要的Example生成信息
上述所有的信息都可以去官网查阅相应文档,或者到我的文件中去下载,里面相应的配置说明与相关应用示例。下载文档
配置完上面的信息,最后一步是什么呢,我们就是要运行这个脚本文件了,官方说明中有4种方式,第一通过命令行方式,第二,三都是通过Ant或者Maven之类的工具生成,最后一种就是通过Java代码生成,我们这里就采用通过Java大麦生成的方式。在DemoRun类中添加一个生成脚本的方法如下:
private static void generateMbgConfiguration() { /* * Mybatis自带Generator工具生成相应东西 */ List<String> warnings = new ArrayList<String>(); boolean overwrite = true; File configFile = new File("./src/david/mbg/mbg_configuration.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = null; try { config = cp.parseConfiguration(configFile); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (XMLParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } DefaultShellCallback callback = new DefaultShellCallback(overwrite); try { MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } catch (InvalidConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("生成Mybatis配置成功!"); }
运行后再Refresh下项目你会发现下面神奇的帮你生成了主要配置,下图红框部分:
最后我们来使用下自动生成的成果吧,我们可以参照前六章的方式,在DemoRun中添加相应的CRUD测试方法如下:
/* * 查询访问者信息 */ public static void testGenerateAdd() { SqlSession session = MybatisUtils.getSqlSession(); VisitorMapper vOperation = session.getMapper(VisitorMapper.class); Visitor visitor = new Visitor(); visitor.setVisitor_name("hello2"); visitor.setEmail("helloworld2@qq.com"); visitor.setCreatetime(new Date()); int count = vOperation.insert(visitor); session.commit(); MybatisUtils.closeSession(session); MybatisUtils.showMessages(CRUD_Enum.Add, count); } /* * 查询访问者信息 */ public static void testGenerateQuery(int id) { SqlSession session = MybatisUtils.getSqlSession(); VisitorMapper vOperation = session.getMapper(VisitorMapper.class); Visitor visitor = vOperation.selectByPrimaryKey(id); MybatisUtils.closeSession(session); MybatisUtils.showMessages(CRUD_Enum.Query, 1); System.out.println(visitor); } public static void testGenerateDelete(int id) { SqlSession session = MybatisUtils.getSqlSession(); VisitorMapper vOperation = session.getMapper(VisitorMapper.class); int count = vOperation.deleteByPrimaryKey(id); session.commit(); MybatisUtils.closeSession(session); MybatisUtils.showMessages(CRUD_Enum.Delete, count); } public static void testGenerateUpdate(int id) { SqlSession session = MybatisUtils.getSqlSession(); VisitorMapper vOperation = session.getMapper(VisitorMapper.class); Visitor visitor = vOperation.selectByPrimaryKey(id); System.out.println(visitor); String name = visitor.getVisitor_name(); if (name.contains("update")) { visitor.setVisitor_name(name.substring(0, name.indexOf("update"))); } else { visitor.setVisitor_name(name + "update"); } int count = vOperation.updateByPrimaryKey(visitor); session.commit(); MybatisUtils.closeSession(session); MybatisUtils.showMessages(CRUD_Enum.Update, count); System.out.println(visitor); }
运行下测试程序,结果就出来了
有没有感觉使用这个帮你提高了不少效率,不必在为繁琐的配置而头痛了,至少不用做重复的无谓的步骤了,让这些都交给工具去做吧^0^,当然在实际的使用中我们可能需要在生成后修改相应的类信息与接口信息名字,当然这些工作量已经不是太多了。希望今天这些内容对需要配置的同学有所帮助。