Install this theme
MyBatis Generator Plugins

MyBatis is a data mapping framework providing capabilities to map SQL statements to Java Objects using Annotations or XML.

(Typical) Mapping rules can be written by hand or automatically generated by MyBatis Generator.

MyBatis Generator will generate:

  • SqlMap XML Files
  • Java Classes to match the primary key and fields of the table(s)
  • Java Client Classes that use the above objects (optional)

Furthermore it is possible to write custom plugins to enhance the generation process and to provide additional capabilities to generated sources.

Several months ago i’ve written some MyBatis Generator Plugins presented in this post. Check out the project’s source code on GitHub: https://github.com/bigpuritz/mybatis-generator-plugins

Before we start let’s assume we have following 2 tables in the database:

CREATE TABLE t_user (
	id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, 
	username VARCHAR(15) NOT NULL, 
	"alias" VARCHAR(30), 
	password VARCHAR(32) NOT NULL, 
	email VARCHAR(50) NOT NULL, 
	CONSTRAINT PK_T_USER PRIMARY KEY (id), 
	UNIQUE (username)
)

CREATE TABLE t_blog (
	id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, 
	name VARCHAR(50) NOT NULL, 
	url VARCHAR(10) NOT NULL, 
	description VARCHAR(10000), 
	owner_id BIGINT DEFAULT 0 NOT NULL, 
	CONSTRAINT PK_T_BLOG PRIMARY KEY (id), 
	CONSTRAINT fk_t_blog_owner_2_t_user FOREIGN KEY (owner_id) REFERENCES t_user(id) ON DELETE CASCADE, 
	UNIQUE (url)
)

Note! Above scripts are for HSQLDB but you can simply convert them to any other database of your choice.

Typical MyBatis Generator configuration file generatorConfig.xml looks like this:

<?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>
    <context id="tables" targetRuntime="MyBatis3">
        <jdbcConnection driverClass="org.hsqldb.jdbc.JDBCDriver"
                        connectionURL="jdbc:hsqldb:file:src/test/resources/database/testdb;readonly=true"
                        userId="sa" password="">
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <javaModelGenerator targetPackage="com.google.code.mybatis.generator.plugins.gen" targetProject="MAVEN">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
            <property name="constructorBased" value="false"/>
        </javaModelGenerator>
        <sqlMapGenerator targetPackage="com.google.code.mybatis.generator.plugins.gen"
                         targetProject="src/gen/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <javaClientGenerator type="ANNOTATEDMAPPER" targetPackage="com.google.code.mybatis.generator.plugins.gen"
                             targetProject="MAVEN">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <table tableName="t_user" domainObjectName="User">
            <generatedKey column="id" sqlStatement="JDBC" identity="true"/>
        </table>
        <table tableName="t_blog" domainObjectName="Blog">
            <generatedKey column="id" sqlStatement="JDBC" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

Model Builder Plugin

Model Builder Plugin implements Builder Pattern by adding Builder inner-class to the generated domain model classes.

To activate it just add following configuration to the generatorConfig.xml:

<plugin type="com.google.code.mybatis.generator.plugins.ModelBuilderPlugin">
        <property name="builderClassName" value="Builder"/>
        <property name="excludeClassNamesRegexp" value="com.*Blog"/>
</plugin>

After generation run this will create User class like this (Note! Blog class was excluded and will not get the Builder added to it):

public class User {
    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column T_USER.ID
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    private Long id;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column T_USER.USERNAME
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    private String username;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column T_USER.alias
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    private String alias;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column T_USER.PASSWORD
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    private String password;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column T_USER.EMAIL
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    private String email;

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column T_USER.ID
     *
     * @return the value of T_USER.ID
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public Long getId() {
        return id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column T_USER.ID
     *
     * @param id the value for T_USER.ID
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column T_USER.USERNAME
     *
     * @return the value of T_USER.USERNAME
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public String getUsername() {
        return username;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column T_USER.USERNAME
     *
     * @param username the value for T_USER.USERNAME
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column T_USER.alias
     *
     * @return the value of T_USER.alias
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public String getAlias() {
        return alias;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column T_USER.alias
     *
     * @param alias the value for T_USER.alias
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public void setAlias(String alias) {
        this.alias = alias == null ? null : alias.trim();
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column T_USER.PASSWORD
     *
     * @return the value of T_USER.PASSWORD
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public String getPassword() {
        return password;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column T_USER.PASSWORD
     *
     * @param password the value for T_USER.PASSWORD
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column T_USER.EMAIL
     *
     * @return the value of T_USER.EMAIL
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public String getEmail() {
        return email;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column T_USER.EMAIL
     *
     * @param email the value for T_USER.EMAIL
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public void setEmail(String email) {
        this.email = email == null ? null : email.trim();
    }

    /**
     * This class was generated by MyBatis Generator.
     * This class corresponds to the database table T_USER
     *
     * @mbggenerated Wed Nov 30 10:19:04 CET 2011
     */
    public static class Builder {
        private User obj;

        public Builder() {
            this.obj = new User();
        }

        /**
         * This method was generated by MyBatis Generator.
         * This method corresponds to the database table T_USER
         *
         * @mbggenerated Wed Nov 30 10:19:04 CET 2011
         */
        public Builder id(Long id) {
            obj.id = id;
            return this;
        }

        /**
         * This method was generated by MyBatis Generator.
         * This method corresponds to the database table T_USER
         *
         * @mbggenerated Wed Nov 30 10:19:04 CET 2011
         */
        public Builder username(String username) {
            obj.username = username;
            return this;
        }

        /**
         * This method was generated by MyBatis Generator.
         * This method corresponds to the database table T_USER
         *
         * @mbggenerated Wed Nov 30 10:19:04 CET 2011
         */
        public Builder alias(String alias) {
            obj.alias = alias;
            return this;
        }

        /**
         * This method was generated by MyBatis Generator.
         * This method corresponds to the database table T_USER
         *
         * @mbggenerated Wed Nov 30 10:19:04 CET 2011
         */
        public Builder password(String password) {
            obj.password = password;
            return this;
        }

        /**
         * This method was generated by MyBatis Generator.
         * This method corresponds to the database table T_USER
         *
         * @mbggenerated Wed Nov 30 10:19:04 CET 2011
         */
        public Builder email(String email) {
            obj.email = email;
            return this;
        }

        /**
         * This method was generated by MyBatis Generator.
         * This method corresponds to the database table T_USER
         *
         * @mbggenerated Wed Nov 30 10:19:04 CET 2011
         */
        public User build() {
            return this.obj;
        }
    }
}

Criteria Builder Plugin

Adds “builder-style” to the generated XXXExample classes. Thus inner XXXExample.Criteria class will become an additional “example()” method the returns the example instance itself.

Configure it like this:

<plugin type="com.google.code.mybatis.generator.plugins.CriteriaBuilderPlugin"/>

“Select One By Example” Plugin

Adds “selectOneByExample” method to the appropriate Mapper interface returning exactly one object instance.

Example configuration:

<plugin type="com.google.code.mybatis.generator.plugins.SelectOneByExamplePlugin">
	<property name="methodToGenerate" value="selectOnlyOneByExample"/>
	<property name="excludeClassNamesRegexp" value="com.*BlogMapper"/>
</plugin>

Now it is possible to select a single User like this:

UserMapper mapper = .... ; // get the mapper
UserExample example = ....; // create example instance

User user = mapper.selectOnlyOneByExample(example);

Cache Plugin

Provides caching support to the mybatis generator by adding @CacheNamespace annotation to the generated mapper interface.

<plugin type="com.google.code.mybatis.generator.plugins.CachePlugin">
	<property name=".*UserMapper" 
		value="implementation=org.mybatis.caches.ehcache.LoggingEhcache.class,eviction=org.apache.ibatis.cache.decorators.LruCache.class,flushInterval=100,size=100" />
	<property name=".*BlogMapper"
		value="implementation=org.mybatis.caches.ehcache.LoggingEhcache.class" />

	<!-- global -->
	<!--
	<property name="implementation" value="org.mybatis.caches.ehcache.LoggingEhcache"/>
	<property name="flushInterval" value="Long.MAX_VALUE"/>
	-->

	<!-- class/table specific -->
	<!--
	<property name="t_blog:eviction" value="org.apache.ibatis.cache.decorators.LruCache"/>
	<property name="t_blog:size" value="1000"/>
	<property name="t_blog:readWrite" value="true"/>
	-->
</plugin> 

This plugin can deal with any number of properties defined using following pattern:

  • name is a regular expression to match a fully qualified name of the class.
  • value is the value of the @CacheNamespace annotation

Plugin configuration above will enhance BlogMapper and UserMapper with following caching annotations:

@CacheNamespace(
   implementation=org.mybatis.caches.ehcache.LoggingEhcache.class
)
public interface BlogMapper {
...
}

@CacheNamespace(
   implementation=org.mybatis.caches.ehcache.LoggingEhcache.class,
   eviction=org.apache.ibatis.cache.decorators.LruCache.class,
   flushInterval=100,
   size=100
)
public interface UserMapper {
...
}

Options Plugin

Adds @Options annotation to the specified mapper method.

<plugin type="com.google.code.mybatis.generator.plugins.OptionsPlugin">
	<property name=".*UserMapper#.*"
			  value="fetchSize=1,timeout=0,useCache=true,flushCache=true" />
</plugin>

This will add to UserMapper methods following annotation:

@Options(fetchSize=1,timeout=0,useCache=true,flushCache=true)

See here complete generated source file.

Mapper Decorator Plugin

Generic plugin that can decorate existing mapper methods. It will generate new mapper methods delegating to the existing methods by adding additional sql behavior to them.

Example configuration:

<plugin type="com.google.code.mybatis.generator.plugins.MapperDecoratorPlugin">
	<property name="methodToGenerate" value="selectByExampleDecorated"/>
	<property name="methodToDecorate" value="selectByExample"/>
	<property name="sql" value="select * from ( #{methodToDecorate} ) a where 1 = 1"/>
</plugin>

This will add new “selectByExampleDecorated”-method to the UserMapper, that internally overrides the original SQL statement defined in the “selectByExample”-method.

public interface UserMapper {

    @SelectProvider(type=UserSqlProvider.class, method="selectByExampleDecorated")
    @Results({
        @Result(column="ID", property="id", jdbcType=JdbcType.BIGINT, id=true),
        @Result(column="USERNAME", property="username", jdbcType=JdbcType.VARCHAR),
        @Result(column="alias", property="alias", jdbcType=JdbcType.VARCHAR),
        @Result(column="PASSWORD", property="password", jdbcType=JdbcType.VARCHAR),
        @Result(column="EMAIL", property="email", jdbcType=JdbcType.VARCHAR)
    })
    @Options(fetchSize=1,timeout=0,useCache=true,flushCache=true)
    List selectByExampleDecorated(UserExample example);

} 

Following properties can be used to configure the plugin:

  • methodToDecorate (required) : the name of the mapper method to decorate.
  • methodToGenerate (required) : the name of the new mapper method to generate.
  • excludeClassNamesRegexp (optional): classes to exclude from generation as regular expression. Default: none
  • sql (required) : is an sql statement to use in the new method
  • (Optional) Any number of property definitions &lt;property name=“propName” value=“propType”/&gt; describing new properties to add to the corresponding XXXExample class

Mapper Decorator Plugin can be used to create complexiest SQL statements just by decorating existing methods and extending/enhancing whose SQL expressions with custom behavior.

 
  1. javaforge posted this
Blog comments powered by Disqus