mybatis-generator 自定义插件
mybatis-generator提供了丰富的自定义插件的接入方式,便于自定义拓展。因为在日常工作中的需要,拓展了一些插件如下。
插件地址:https://github.com/suyin58/mybatis-generator-tddl
提供如下功能:
- 字段注释工具,将表字段注释添加到属性上
- Lombok插件,提供lombok的注解插件。
- 唯一索引插件,提供基于unique key 的select、update、insert操作,便于分库分表情况下,不是使用id子增长主键的sql查询
- upsert 存在即更新插件
- 分页查询
- 批量插入插件
各个插件详情见配置文件插件部分(https://github.com/suyin58/mybatis-generator-tddl/blob/master/generator-test/src/test/resources/generatorConfigMyBatis3.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> <!--defaultModelType="flat": 不生成复合主键对象--> <context id="generatorTables" targetRuntime="MyBatis3" defaultModelType="flat"> <!--是否支持合并--> <property name="mergeable" value="false"/> <plugin type="org.mybatis.generator.plugins.MapperConfigPlugin"> <property name="fileName" value="mybatis-config.xml"/> <property name="targetPackage" value="/"/> <property name="targetProject" value="src/main/resources"/> </plugin> <!-- 此处是将Example改名为Criteria 当然 想改成什么都行 --> <!-- <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin">--> <!-- <property name="searchString" value="Example"/>--> <!-- <property name="replaceString" value="Criteria"/>--> <!-- </plugin>--> <!-- 自定义插件开始 --> <!--序列化插件--> <plugin type="com.toolplat.generator.plugins.SerializablePlugin"/> <!-- lombok 插件 --> <plugin type="com.toolplat.generator.plugins.LombokPlugin"> <property name="data" value="true"/> <property name="builder" value="true"/> <property name="allArgsConstructor" value="true"/> <property name="noArgsConstructor" value="true"/> <property name="toString" value="true"/> </plugin> <!-- 自定义unique key操作插件 --> <plugin type="com.toolplat.generator.plugins.SelectByUniqueKeyPlugin"> </plugin> <plugin type="com.toolplat.generator.plugins.UpdateByUniqueKeySelectivePlugin"> </plugin> <plugin type="com.toolplat.generator.plugins.DeleteByUniqueKeyPlugin"> </plugin> <!--存在即更新插件--> <plugin type="com.toolplat.generator.plugins.UpsertByUniqueKeyPlugin"> </plugin> <plugin type="com.toolplat.generator.plugins.UpsertByPrimaryKeyPlugin"> </plugin> <!--批量插入插件--> <plugin type="com.toolplat.generator.plugins.BatchInsertPlugin"> </plugin> <!--for update 插件--> <plugin type="com.toolplat.generator.plugins.SelectByPrimaryForUpdate"> </plugin> <plugin type="com.toolplat.generator.plugins.SelectByExampleForUpdate"> </plugin> <plugin type="com.toolplat.generator.plugins.SelectByUniqueKeyForUpdatePlugin"> </plugin> <!--分页插件--> <plugin type="com.toolplat.generator.plugins.LimitPlugin"> </plugin> <!-- 自定义插件结束 --> <!--自定义注释开始 --> <!-- commentGenerator 去除自动生成的注释 --> <commentGenerator type="com.toolplat.generator.plugins.CommentGenerator"> <property name="author" value="szy" /> </commentGenerator> <!--自定义注释结束 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/temp_utf8" userId="root" password="root"> <property name="useInformationSchema" value="true"/> </jdbcConnection> <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer true,把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="true" /> </javaTypeResolver> <!-- javaModelGenerator是模型的生成信息,这里将指定这些Java model类的生成路径; --> <javaModelGenerator targetPackage="com.toolplat.demo.domain" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- sqlMapGenerator是mybatis 的sqlMapper XML文件的生成信息,包括生成路径等; 先生成xml,在生成java--> <sqlMapGenerator targetPackage="com.toolplat.demo.dao" targetProject="src/main/resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- javaClientGenerator是应用接口的生成信息; --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.toolplat.demo.dao" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!-- table是用户指定的被生成相关信息的表,它必须在指定的jdbc连接中已经被建立。可以多个 --> <table tableName="table_one_unique_key" domainObjectName="TableOneUniqueKeyPO" > <!-- enableInsert="true"--> <!-- enableSelectByPrimaryKey="false" enableUpdateByPrimaryKey="false"--> <!-- enableDeleteByPrimaryKey="false" enableCountByExample="false"--> <!-- enableDeleteByExample="false"--> <!-- enableSelectByExample="false" enableUpdateByExample="false"--> </table> <table tableName="table_two_unique_key" domainObjectName="TableTwoUniqueKeyPO"> <property name="uniqueKey" value="uk_org_cid"/> </table> <table tableName="table_with_identify" domainObjectName="TableWithIdentifyPO"></table> </context> </generatorConfiguration>
记录一下:
1. 自定义SQL语句,案例(https://github.com/suyin58/mybatis-generator-tddl/blob/master/generator-plugin/src/main/java/com/toolplat/generator/plugins/BatchInsertPlugin.java)
案例项目中的:BatchInsertPlugin、DeleteByUniqueKeyPlugin、SelectByExampleForUpdate、UpsertByUniqueKeyPlugin等等。
1.1 插件需要继承PluginAdapter
public class BasePlugin extends PluginAdapter { }
1.2 重载mapper接口生成(clientGenerated)和XML文件生成(sqlMapDocumentGenerated)
@Override public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) { // 1. batchInsert FullyQualifiedJavaType listType = FullyQualifiedJavaType.getNewListInstance(); listType.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass()); Method method = JavaElementGeneratorTools.generateMethod( METHOD, JavaVisibility.DEFAULT, FullyQualifiedJavaType.getIntInstance(), true, new Parameter(listType, "list", "@Param(\"list\")") ); context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable); // interface 增加方法 JavaElementGeneratorTools.addMethodToInterface(interfaze, method); return super.clientGenerated(interfaze, introspectedTable); } @Override public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) { // 1. batchInsert XmlElement answer = new XmlElement("insert"); answer.addAttribute(new Attribute("id", METHOD)); // 参数类型 answer.addAttribute(new Attribute("parameterType", "map")); // 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated) context.getCommentGenerator().addComment(answer); // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer // XmlElementGeneratorTools.useGeneratedKeys(answer, introspectedTable); answer.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime())); for (VisitableElement element : XmlElementGeneratorTools.generateKeys(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(allColumns), true)) { answer.addElement(element); } // 添加foreach节点 XmlElement foreachElement = new XmlElement("foreach"); foreachElement.addAttribute(new Attribute("collection", "list")); foreachElement.addAttribute(new Attribute("item", "item")); foreachElement.addAttribute(new Attribute("separator", ",")); XmlElement valuesTrimElement = new XmlElement("trim"); foreachElement.addElement(valuesTrimElement); valuesTrimElement.addElement(XmlElementGeneratorTools.generateValuesSelective(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(allColumns), "item.", true) ); // values 构建 answer.addElement(new TextElement("values")); answer.addElement(foreachElement); XmlElementGeneratorTools.addElementWithBestPosition(document.getRootElement(), answer); return true; }
1.3 配置文件添加插件
<!--批量插入插件--> <plugin type="com.toolplat.generator.plugins.BatchInsertPlugin"> </plugin>
2.注释生成插件,案例(https://github.com/suyin58/mybatis-generator-tddl/blob/master/generator-plugin/src/main/java/com/toolplat/generator/plugins/CommentGenerator.java)
2.1 插件需要继承DefaultCommentGenerator
public class CommentGenerator extends DefaultCommentGenerator { }
2.2 重载类注释和属性注释以及方法注释
/** * set model comment from table remark * @param topLevelClass * @param introspectedTable */ @Override public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { String auth = properties.getProperty("author"); String tableDesc = introspectedTable.getRemarks(); topLevelClass.addJavaDocLine("/**"); topLevelClass.addJavaDocLine(" * " + tableDesc); if (null != auth && auth.length() > 0) { topLevelClass.addJavaDocLine(" * @author " + auth); } topLevelClass.addJavaDocLine(" */"); } /** * set field comment from field remark * @param field * @param introspectedTable * @param introspectedColumn */ @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { String remark = introspectedColumn.getRemarks(); field.addJavaDocLine("/**"); field.addJavaDocLine(" * " + remark); field.addJavaDocLine(" */"); } /** * remove java mapping coment * * @param method * @param introspectedTable */ @Override public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) { // method.addJavaDocLine("/**"); // method.addJavaDocLine(" * auto method:" + method.getName()); // if (method.getParameters() != null && method.getParameters().size() > 0) { // for (Parameter param : method.getParameters()) { // method.addJavaDocLine(" * @param " + param.getName()); // } // } // Optional<FullyQualifiedJavaType> ret = method.getReturnType(); // if (ret.isPresent()) { // method.addJavaDocLine(" * @return " + ret.get().getShortName()); // } // method.addJavaDocLine(" */"); }
2.3. 配置文件添加插件
<!-- commentGenerator 去除自动生成的注释 --> <commentGenerator type="com.toolplat.generator.plugins.CommentGenerator"> <property name="author" value="szy" /> </commentGenerator>