0.需求
在我們使用mybatis-generator的過程中,往往其自帶的功能不能夠滿足我們的需求。
此時我們就需要進行插件開發了。
1.准備工作
新建一個Maven項目,引入依賴 mybatis-generator-core
2.開發分頁
在mysql中,我們一般使用limit來實現分頁
之前的做法是在mybatis-generator生成完成之后手動在Example中兩個屬性,offset,rows
然后在xml中添加條件判斷,追加limit。
這里我們就通過這個思路在開發分頁插件。
import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; import org.mybatis.generator.api.dom.java.*; import org.mybatis.generator.api.dom.xml.Attribute; import org.mybatis.generator.api.dom.xml.TextElement; import org.mybatis.generator.api.dom.xml.XmlElement; import java.util.List; public class LimitPlugin extends PluginAdapter { @Override public boolean validate(List<String> list) { return true; } /** * 為每個Example類添加offset和rows屬性已經set、get方法 */ @Override public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper(); Field rows = new Field(); rows.setName("rows"); rows.setVisibility(JavaVisibility.PRIVATE); rows.setType(integerWrapper); topLevelClass.addField(rows); Method setRows = new Method(); setRows.setVisibility(JavaVisibility.PUBLIC); setRows.setName("setRows"); setRows.addParameter(new Parameter(integerWrapper, "rows")); setRows.addBodyLine("this.rows = rows;"); topLevelClass.addMethod(setRows); Method getRows = new Method(); getRows.setVisibility(JavaVisibility.PUBLIC); getRows.setReturnType(integerWrapper); getRows.setName("getRows"); getRows.addBodyLine("return rows;"); topLevelClass.addMethod(getRows); Field offset = new Field(); offset.setName("offset"); offset.setVisibility(JavaVisibility.PRIVATE); offset.setType(integerWrapper); topLevelClass.addField(offset); Method setOffset = new Method(); setOffset.setVisibility(JavaVisibility.PUBLIC); setOffset.setName("setOffset"); setOffset.addParameter(new Parameter(integerWrapper, "offset")); setOffset.addBodyLine("this.offset = offset;"); topLevelClass.addMethod(setOffset); Method getOffset = new Method(); getOffset.setVisibility(JavaVisibility.PUBLIC); getOffset.setReturnType(integerWrapper); getOffset.setName("getOffset"); getOffset.addBodyLine("return offset;"); topLevelClass.addMethod(getOffset); return true; } /** * 為Mapper.xml的selectByExample添加limit */ @Override public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) { XmlElement ifLimitNotNullElement = new XmlElement("if"); ifLimitNotNullElement.addAttribute(new Attribute("test", "rows != null")); XmlElement ifOffsetNotNullElement = new XmlElement("if"); ifOffsetNotNullElement.addAttribute(new Attribute("test", "offset != null")); ifOffsetNotNullElement.addElement(new TextElement("limit ${offset}, ${rows}")); ifLimitNotNullElement.addElement(ifOffsetNotNullElement); XmlElement ifOffsetNullElement = new XmlElement("if"); ifOffsetNullElement.addAttribute(new Attribute("test", "offset == null")); ifOffsetNullElement.addElement(new TextElement("limit ${rows}")); ifLimitNotNullElement.addElement(ifOffsetNullElement); element.addElement(ifLimitNotNullElement); return true; } }
3.集成Lombok、序列化
使用lombok可以使代碼更簡潔
import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; import org.mybatis.generator.api.dom.java.*; import java.util.List; public class LombokPlugin extends PluginAdapter { @Override public boolean validate(List<String> warnings) { return true; } @Override public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { // 添加domain的import topLevelClass.addImportedType("lombok.Data"); topLevelClass.addImportedType("lombok.NoArgsConstructor"); topLevelClass.addImportedType("lombok.AllArgsConstructor"); topLevelClass.addImportedType("java.io.Serializable"); // 添加domain的注解 topLevelClass.addAnnotation("@Data"); topLevelClass.addAnnotation("@NoArgsConstructor"); topLevelClass.addAnnotation("@AllArgsConstructor"); // 序列化 generatorDefaultSerialVersionUID(topLevelClass); return true; } // 不生成getter @Override public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { return false; } // 不生成setter @Override public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { return false; } /** * 序列化 * * @param topLevelClass */ private void generatorDefaultSerialVersionUID(TopLevelClass topLevelClass) { FullyQualifiedJavaType serializable = new FullyQualifiedJavaType("java.io.Serializable"); topLevelClass.addSuperInterface(serializable); Field field = new Field(); field.setFinal(true); field.setInitializationString("1L"); field.setName("serialVersionUID"); field.setStatic(true); field.setType(new FullyQualifiedJavaType("long")); field.setVisibility(JavaVisibility.PRIVATE); topLevelClass.getFields().add(0, field); } }
4.使用運行
到這里我們就將兩個自定義的插件開發完成了。
這里建議是將這兩個插件放在一個單獨的項目,一是為了方便復用,另一個是我放在同一個項目下的時候,運行好像有點問題。
4.1.打包插件
通過mvn install將我們的插件進行打包,打包為jar包,方便后續使用。
4.2.使用插件
<plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <configuration> <configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> </configuration> <dependencies> <dependency> <groupId>com.xxxx</groupId> <artifactId>xxxx</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </plugin>
更改pom.xml,在mybatis-generator的maven插件中引入我們剛剛的項目
<?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> <!--導入屬性配置 --> <properties resource="generator/generator.properties"></properties> <!--指定特定數據庫的jdbc驅動jar包的位置 location: The full path name of a JAR/ZIP file to add to the classpath, or a directory to add to the classpath. --> <classPathEntry location="${jdbc.driverLocation}"/> <context id="default" targetRuntime="Mybatis3"> <!--使用``包裹mysql關鍵字--> <property name="autoDelimitKeywords" value="true"/> <property name="beginningDelimiter" value="`"/> <property name="endingDelimiter" value="`"/> <plugin type="com.fdzang.formybatis.config.LombokPlugin"/> <plugin type="com.fdzang.formybatis.config.LimitPlugin"/> <!-- optional,旨在創建class時,去掉注釋 --> <commentGenerator> <property name="suppressDate" value="false"/> <property name="suppressAllComments" value="true"/> </commentGenerator> <jdbcConnection driverClass="${jdbc.driver}" connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"> </jdbcConnection> <!-- 非必需,類型處理器,在數據庫類型和java類型之間的轉換控制--> <javaTypeResolver > <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!--配置實體bean--> <javaModelGenerator targetPackage="com.fdzang.microservice.blog.article.dao.domain" targetProject="src/main/java"> <!-- 是否允許子包,即targetPackage.schemaName.tableName --> <property name="enableSubPackages" value="false"/> <!-- 是否對類CHAR類型的列的數據進行trim操作 --> <property name="trimStrings" value="false"/> </javaModelGenerator> <!-- 配置實體bean的mapper.xml--> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!-- 配置實體mapper接口--> <javaClientGenerator targetPackage="com.fdzang.microservice.blog.article.dao.mapper" targetProject="src/main/java" type="XMLMAPPER"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <table tableName="test" domainObjectName="TestDO" mapperName="TestMapper" enableInsert="true" enableUpdateByPrimaryKey="true" enableDeleteByPrimaryKey="true" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> </table> </context> </generatorConfiguration>
修改generatorConfig.xml,在<context>中引入插件<plugin>,這里有個注意事項是,plugin放置的順序,需要在<property>下
4.3.運行效果
import java.io.Serializable; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) public class TestDO implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String test; }
Example,去掉了其他部分。
public class TestDOExample { private Integer rows; private Integer offset; public TestDOExample() { oredCriteria = new ArrayList<Criteria>(); } public void setRows(Integer rows) { this.rows = rows; } public Integer getRows() { return rows; } public void setOffset(Integer offset) { this.offset = offset; } public Integer getOffset() { return offset; } }
Mapper
<select id="selectByExample" parameterType="com.fdzang.microservice.blog.article.dao.domain.TestDOExample" resultMap="BaseResultMap"> select <if test="distinct"> distinct </if> 'false' as QUERYID, <include refid="Base_Column_List" /> from test <if test="_parameter != null"> <include refid="Example_Where_Clause" /> </if> <if test="orderByClause != null"> order by ${orderByClause} </if> <if test="rows != null"> <if test="offset != null"> limit ${offset}, ${rows} </if> <if test="offset == null"> limit ${rows} </if> </if> </select>
5.其他
其實自定義mybatis-generator的插件,主要是通過繼承PluginAdapter來實現的。
PluginAdapter中還有很多其他的方法,可以進行自定義修改,大家可以根據需要進行自定義改造。
參考:
http://xxgblog.com/2016/05/06/mybatis-generator-mysql-pagination/
https://www.jianshu.com/p/b243f3ec8419