基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析
项目简单说明
mybatis-generator,是根据数据库表、字段反向生成实体类等代码文件。我在国庆时候,没事剖析了mybatis-generator-core源码,写了相当详细的中文注释,可以去看看。目前我剖析修改的是1.3.5版本。
在原版本的基础上,增加批量增加、修改的操作,增加统一模块生成,并且 生成的代码,支持最新的阿里巴巴java规范。
源码剖析说明
1.剖析org.mybatis.generator.plugins.ToStringPlugin源码
2.剖析org.mybatis.generator.plugins.MapperConfigPlugin源码
3.剖析org.mybatis.generator.api.ShellRunner源码,Main入口
3.剖析org.mybatis.generator.config.xml.ConfigurationParser源码,配置解析器,用于对generatorConfig.xml配置文件的解析
4.剖析org.mybatis.generator.config.Context源码,封装元素内容
修改源码说明(原版本没有的功能)
1.数据表的备注信息的添加:在FullyQualifiedTable类中添加remark字段,并在org.mybatis.generator.internal.db.DatabaseIntrospector类calculateIntrospectedTables方法,添加一段获取数据库备注的代码
1 //设置数据库表的备注信息 2 //start 3 Statement stmt = this.databaseMetaData.getConnection().createStatement(); 4 ResultSet rs = stmt.executeQuery( 5 new StringBuilder() 6 .append("SHOW TABLE STATUS LIKE '") 7 .append(atn.getTableName()) 8 .append("'") 9 .toString()); 10 while (rs.next()) 11 table.setRemark(rs.getString("COMMENT")); 12 closeResultSet(rs); 13 stmt.close(); 14 //end
2..非model类Example的注释方法的添加,方法名addExampleClassComment(TopLevelClass topLevelClass)
3.重构部分org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3Impl包里getGeneratedJavaFiles方法
4.详细中文注释的添加,入口包函数在org.mybatis.generator.api.ShellRunner
5.生成的中文注释信息可在修DefaultCommentGenerator类修改
6.增加MybatisServicePlugin:service层的代码生成,个人觉得不完美,因为业务会变,所以service层也会变,仅供学习参考
7.增加MapperPlugin:Mapper层有大量生成的重复方法,所以增加了统一继承IMapper接口实现
8.为IMapper接口加入批量插入数据的方法
9.删除ibatis2内容,并删除CaseInsensitiveLikePlugin插件(这个插件用来在XXXExample类中生成大小写敏感的LIKE方法插件本身用处不大,但是我们可以通过这个插件学习给XXXExample类添加额外的方法)),因此引用了ibatis2 10.为IMapper接口加入批量更新数据的方法
11.生成的代码符合阿里规范
使用方式
在项目.pom中,添加以下部分,更新maven即可(因为我已经把项目发布到maven中央仓库去了)。
<build> <defaultGoal>compile</defaultGoal> <plugins> <!-- 指定java版本--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.5</version> <configuration> <verbose>true</verbose> <overwrite>true</overwrite> <!-- 指定配置文件的路径,默认是在resources下--> <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile> </configuration> <executions> <execution> <id>Generate MyBatis Artifacts</id> <goals> <goal>generate</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>io.github.orange1438</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.5</version> </dependency> </dependencies> </plugin> </plugins> </build>
配置文件
1.generatorConfig.properties
# data base info jdbc.dataSource.url:jdbc:mysql://localhost:3306/manage_system?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8 jdbc.dataSource.driverClassName:com.mysql.jdbc.Driver jdbc.dataSource.username:root jdbc.dataSource.password:123456 # Mybatis Generator configuration # classPath:maven repository path,下载到仓库里,根据仓库路径修改 jdbc.mybatisGenerator.classPath=E:/orange/Documents/IdeaProjects/repository/mysql/mysql-connector-java/5.1.35/mysql-connector-java-5.1.35.jar # javaModelGenerator model.path=src/main/resources/test model.package=orange1438.entity # javaClientGenerator mapper.path=src/main/resources/test mapper.package=orange1438.mappers # sqlMapGenerator mapper.xml.path=src/main/resources/test mapper.xml.package=orange1438.mapper # service——If configuration service.path=src/main/resources/test service.package=orange1438.service service.package.impl=orange1438.service.impl
2.generatorConfig.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"> <!-- 参考官方文档 http://www.mybatis.org/generator/configreference/xmlconfig.html http://generator.sturgeon.mopaas.com/index.html http://www.jianshu.com/p/e09d2370b796 http://mbg.cndocs.tk/ --> <generatorConfiguration> <!-- 引入配置文件 --> <properties resource="test/generatorConfig.properties"/> <!-- 指定数据连接驱动jar地址 --> <classPathEntry location="${jdbc.mybatisGenerator.classPath}"/> <!-- 一个数据库一个context --> <context id="testTables" targetRuntime="MyBatis3"> <!-- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表; 一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖 --> <property name="autoDelimitKeywords" value="false"/> <!-- 生成的Java文件的编码 --> <property name="javaFileEncoding" value="UTF-8"/> <!-- 格式化java代码 --> <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/> <!-- 格式化XML代码 --> <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/> <!--开启抑制类型的警告信息--> <property name="suppressTypeWarnings" value="true"/> <!-- 插件 :其他插件参考http://www.jianshu.com/p/1b826d43dbaf--> <!--插件 :用来给Java模型生成equals和hashcode方法--> <!--<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>--> <!--插件 :用来为生成的Java模型类添加序列化接口--> <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/> <!--插件 :生成的Java模型创建一个toString方法--> <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/> <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin"> <property name="searchString" value="Example$"/> <property name="replaceString" value="Criteria"/> </plugin> <!-- 统一Mapper 接口 --> <plugin type="org.mybatis.generator.plugins.MapperPlugin"> <property name="interfaceName" value="IMapper"/> <!-- 是否删除Mapper类里的方法,默认删除--> <property name="deleteMethod" value="true"/> </plugin> <!-- service层插件 --> <plugin type="org.mybatis.generator.plugins.MybatisServicePlugin"> <property name="targetPackage" value="${service.package}"/> <property name="implementationPackage" value="${service.package.impl}"/> <property name="targetProject" value="${service.path}"/> <property name="enableInsert" value="true"/> <property name="enableUpdateByExampleSelective" value="true"/> <property name="enableInsertSelective" value="true"/> <property name="enableUpdateByPrimaryKey" value="true"/> <property name="enableDeleteByPrimaryKey" value="true"/> <property name="enableDeleteByExample" value="true"/> <property name="enableUpdateByPrimaryKeySelective" value="true"/> <property name="enableUpdateByExample" value="true"/> </plugin> <!-- 注释 --> <commentGenerator> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="false"/> <!-- 是否给实体类生成的备注的注释 true:是 : 默认为false:否 --> <property name="addRemarkComments" value="true"/> <!-- 是否去掉注释代时间戳 true:是 : false:否,默认yyyy-MM-dd HH:mm:ss(1.3.5-chinese-annotation修改版)--> <property name="suppressDate" value="false"/> <property name="dateFormat" value="yyyy/MM/dd HH:mm"/> <!-- 自己添加的参数属性:数据表字段的get、set方法是否添加final关键字,默认为true --> <property name="addMethodFinal" value="true"/> <property name="author" value="orange1438"/> </commentGenerator> <!--数据库连接的信息:驱动类、连接地址、用户名、密码 --> <jdbcConnection driverClass="${jdbc.dataSource.driverClassName}" connectionURL="${jdbc.dataSource.url}" userId="${jdbc.dataSource.username}" password="${jdbc.dataSource.password}"> </jdbcConnection> <!-- 类型转换 --> <javaTypeResolver> <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal --> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!-- 生成实体类的位置 --> <javaModelGenerator targetPackage="${model.package}" targetProject="${model.path}"> <!-- for MyBatis3/MyBatis3Simple 自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter; --> <property name="constructorBased" value="false"/> <!-- 是否在当前路径下新加一层schema, eg:false路径com.orange1438.entity, true:com.orange1438.entity.[schemaName] --> <property name="enableSubPackages" value="true"/> <!-- 是否针对string类型的字段在set/get的时候进行trim调用:清理前后的空格 --> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- 生成mapper xml文件 --> <sqlMapGenerator targetPackage="${mapper.xml.package}" targetProject="${mapper.xml.path}"> <!-- 解释同上:生成实体类的位置 --> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口 targetPackage/targetProject:同javaModelGenerator type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下): 1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML; 2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中; 3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML; 注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER --> <!-- 生成mapper接口生成的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="${mapper.package}" targetProject="${mapper.path}"> <!-- 解释同上:生成实体类的位置 --> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!-- mvn mybatis-generator:generate --> <!-- 指定生成的数据库表 --> <!-- domainObjectName:指定生成的实体类的文件名 --> <!--<table tableName="sys_user" domainObjectName="User"/>--> <table tableName="test" domainObjectName="Test"/> <!-- 其他需求:有些表的字段需要指定java类型 --> <!--<table schema="management_system" tableName="s_user"--> <!--domainObjectName="UserEntity" enableCountByExample="false"--> <!--enableDeleteByExample="false" enableSelectByExample="false"--> <!--enableUpdateByExample="false">--> <!--<!– schema即为数据库名 tableName为对应的数据库表 domainObjectName是要生成的实体类 enable*ByExample--> <!--是否生成 example类 –>--> <!--<!– 忽略列,不生成bean 字段 –>--> <!--<ignoreColumn column="FRED" />--> <!--<!– 指定列的java数据类型 –>--> <!--<columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />--> <!--</table>--> </context> </generatorConfiguration>