完整示例代码: batis-generator

改进的优点:

1) 完整实现代码,可直接使用

2) 增加了分页、过滤功能

3) 满足任意查询条件

 

1. 导入MySQL

解压项目,找到mysql文件,导入数据库

mysql文件路径: \batis-generator\src\main\resources\mytest.sql

新建数据库:

mysql -uroot -p123456
create database mytest charset=utf8;

导入数据库:

mysql -uroot -p123456 mytest < mytest.sql

 

2. pom.xml 文件配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mimvp</groupId>
	<artifactId>batis-generator</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>batis-generator</name>
	<description>batis-generator of mimvp</description>
	<url>http://maven.apache.org</url>

	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<mybatis-generator.version>1.3.5</mybatis-generator.version>
		<mybatis.version>3.4.4</mybatis.version>
		<mysql-connector.version>5.1.42</mysql-connector.version>
	</properties>

	<repositories>
		<repository>
			<id>nexus</id>
			<name>maven nexus</name>
			<url>http://repo1.maven.org/maven2/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

	<dependencies>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>

		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator-core</artifactId>
			<version>${mybatis-generator.version}</version>
		</dependency>
	</dependencies>

	<!-- Maven编译项配置 -->
	<build>
		<sourceDirectory>src/main/java</sourceDirectory>
		<testSourceDirectory>src/test/java</testSourceDirectory>
		<outputDirectory>target/classes</outputDirectory>
		<testOutputDirectory>target/test-classes</testOutputDirectory>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
			</resource>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.*</include>
				</includes>
				<excludes>
					<exclude>**/*.java</exclude>
				</excludes>
			</resource>
		</resources>

		<testResources>
			<testResource>
				<filtering>true</filtering>
				<directory>src/test/resources</directory>
			</testResource>
		</testResources>

		<plugins>
			<plugin>
				<!-- usage : mvn mybatis-generator:generate -->
				<groupId>org.mybatis.generator</groupId>
				<artifactId>mybatis-generator-maven-plugin</artifactId>
				<version>${mybatis-generator.version}</version>

				<configuration>
					<configurationFile>src/main/resources/mybatisConfig.xml</configurationFile>
					<overwrite>true</overwrite>
					<verbose>true</verbose>
					<contexts>DB2Tables</contexts>
				</configuration>

				<!-- 依赖必须放入此处: plugins/plugin/dependencies -->
				<dependencies>
					<dependency>
						<groupId>mysql</groupId>
						<artifactId>mysql-connector-java</artifactId>
						<version>${mysql-connector.version}</version>
					</dependency>

					<dependency>
						<groupId>com.mimvp.mybatis</groupId>
						<artifactId>mimvp-mybatis-pagination</artifactId>
						<version>0.0.1</version>
						<scope>system</scope>
						<systemPath>${project.basedir}/lib/mimvp-mybatis-pagination.jar</systemPath>
					</dependency>
				</dependencies>
			</plugin>
		</plugins>
	</build>
</project>

 

3. mybatisConfig.xml 文件配置

文件路径: \batis-generator\src\main\resources\mybatisConfig.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>

	<context id="DB2Tables" targetRuntime="MyBatis3">
	    <property name="autoDelimitKeywords" value="true" />
	    <property name="beginningDelimiter" value="`" />
	    <property name="endingDelimiter" value="`" />
	    <plugin type="com.mimvp.mybatis.plugin.PaginationPlugin" />
	    <plugin type="com.mimvp.mybatis.plugin.FieldFilterPlugin" />
	    <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
	    <plugin type="org.mybatis.generator.plugins.SerializablePlugin">
	        <property name="suppressJavaInterface" value="false" />
	    </plugin>
	    
		<commentGenerator>
			<property name="suppressDate" value="true" />
			<property name="suppressAllComments" value="true" />
		</commentGenerator>
		
		<!-- 数据库链接URL、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver" 
									connectionURL="jdbc:mysql://localhost:3306/mytest?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true" 
									userId="root" 
									password="123456">
		</jdbcConnection>
		
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>
		
		<!-- 生成模型的包名和位置 -->
		<javaModelGenerator targetPackage="com.mimvp.demo.model" targetProject="src/main/java">
			<property name="enableSubPackages" value="true" />
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
		
		<!-- 生成的映射文件包名和位置 -->
		<sqlMapGenerator targetPackage="com.mimvp.demo.mapping" targetProject="src/main/java">
			<property name="enableSubPackages" value="true" />
		</sqlMapGenerator>
		
		<!-- 生成DAO的包名和位置 -->
		<javaClientGenerator type="XMLMAPPER" targetPackage="com.mimvp.demo.dao" targetProject="src/main/java">
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>
		
		<!-- 要生成那些表(更改tableName和domainObjectName就可以) -->
		<table tableName="student" domainObjectName="Student"
			enableCountByExample="true" enableUpdateByExample="true"
			enableDeleteByExample="true" enableSelectByExample="true"
			selectByExampleQueryId="true" />
	</context>
</generatorConfiguration> 

如上,重点关注项:

1) id="DB2Tables" 分页配置

2) jdbcConnection 数据库连接

3) javaModelGenerator等DAO生成

4) tableName="student" 数据库表选项定制,表可以有多个一起生成

 

4. Maven 生成命令

mvn mybatis-generator:generate

 

5. Eclipse Debug 生成配置

Debug -> Debug Configurations -> Maven Build -> 新建配置文件
Name    :    batis-generator
Main ->     Base directory    :    ${workspace_loc:/batis-generator}
Main ->     Goals            :    batis-generator:generate

mybatis-generator-zi-dong-sheng-cheng-daomodelmapping-01

 

6. Mybatis-Generator 生成文件

执行 maven 或 Eclipse Debug,生成 dao、mapping、model 文件

mybatis-generator-zi-dong-sheng-cheng-daomodelmapping-02

 

 

重点解析

1. 解析 pom.xml

pom.xml 指定了mybatisConfig.xml 配置文件路径、mysql-connector连接器、mybatis-pagination分页器

<plugins>
	<plugin>
		<!-- usage : mvn mybatis-generator:generate -->
		<groupId>org.mybatis.generator</groupId>
		<artifactId>mybatis-generator-maven-plugin</artifactId>
		<version>${mybatis-generator.version}</version>

		<!-- 指定mybatisConfig.xml配置文件路径 -->
		<configuration>
			<configurationFile>src/main/resources/mybatisConfig.xml</configurationFile>
			<overwrite>true</overwrite>
			<verbose>true</verbose>
			<contexts>DB2Tables</contexts>
		</configuration>

		<!-- 依赖必须放入此处: plugins/plugin/dependencies -->
		<dependencies>
			<dependency>
				<groupId>mysql</groupId>
				<artifactId>mysql-connector-java</artifactId>
				<version>${mysql-connector.version}</version>
			</dependency>

			<dependency>
				<groupId>com.mimvp.mybatis</groupId>
				<artifactId>mimvp-mybatis-pagination</artifactId>
				<version>0.0.1</version>
				<scope>system</scope>
				<systemPath>${project.basedir}/lib/mimvp-mybatis-pagination.jar</systemPath>
			</dependency>
		</dependencies>
	</plugin>
</plugins>

 

2. 解析分页实现

分页器是在 PaginationPlugin类 增加了 offset 和 pageSize 两个属性

PaginationPlugin类路径: 

\batis-generator\src\main\java\com\mimvp\mybatis\plugin\PaginationPlugin.java

/**
 * Author		:	mimvp.com
 * Date			:	2016.01.12
 */
public class PaginationPlugin extends PluginAdapter {

    @Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        // add field, getter, setter for limit clause
        addLimit(topLevelClass, introspectedTable, "offset");
        addLimit(topLevelClass, introspectedTable, "pageSize");
        return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
    }

    @Override
    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        XmlElement isNotNullElement = new XmlElement("if");
        isNotNullElement.addAttribute(new Attribute("test", "offset != null and offset >= 0 and pageSize != null and pageSize >= 0"));
        isNotNullElement.addElement(new TextElement("limit #{offset},#{pageSize}"));
        element.addElement(isNotNullElement);
        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
    }

    @Override
    public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        XmlElement isNotNullElement = new XmlElement("if");
        isNotNullElement.addAttribute(new Attribute("test", "offset != null and offset >= 0 and pageSize != null and pageSize >= 0"));
        isNotNullElement.addElement(new TextElement("limit #{offset},#{pageSize}"));
        element.addElement(isNotNullElement);
        return super.sqlMapSelectByExampleWithBLOBsElementGenerated(element, introspectedTable);
    }

    // .....
}

分页实现的效果,见自动生成的 StudentMapper.xml 文件,其路径为: 

\batis-generator\src\main\java\com\mimvp\demo\mapping\StudentMapper.xml

 <select id="selectByExampleWithFieldFilters" parameterType="com.mimvp.demo.model.StudentExample" resultMap="BaseResultMap">
   select
   <if test="distinct">
     distinct
   </if>
   'true' as QUERYID,
   <if test="fieldFilters != null">
     <include refid="Selective_Column_List" />
   </if>
   <if test="fieldFilters == null">
     <include refid="Base_Column_List" />
   </if>
   from student
   <if test="_parameter != null">
     <include refid="Example_Where_Clause" />
   </if>
   <if test="orderByClause != null">
     order by ${orderByClause}
   </if>
   <if test="offset != null and offset >= 0 and pageSize != null and pageSize >= 0">
     limit #{offset},#{pageSize}
   </if>
 </select>

 

3. 解析 example类

example类是自动生成,直接看 StudentExample 类,其路径:

\batis-generator\src\main\java\com\mimvp\demo\model\StudentExample.java

StudentExample.java 类变量和方法结构:

mybatis-generator-zi-dong-sheng-cheng-daomodelmapping-03

我们分析一个between查询条件(会了这一个,其它的分析都类似,很简单)

StudentExample类的内嵌类 GeneratedCriteria 有三个封装方法,分别表示的查询条件为无、一个、两个

1) 无, 如: id is null, id is not null

2) 一个, 如 id = 100, id != 100

3) 两个, 如 id beteen 1 and 100

protected abstract static class GeneratedCriteria {
    protected List<Criterion> criteria;

    protected GeneratedCriteria() {
        super();
        criteria = new ArrayList<Criterion>();
    }

    public boolean isValid() {
        return criteria.size() > 0;
    }

    protected void addCriterion(String condition) {
        if (condition == null) {
            throw new RuntimeException("Value for condition cannot be null");
        }
        criteria.add(new Criterion(condition));
    }

    protected void addCriterion(String condition, Object value, String property) {
        if (value == null) {
            throw new RuntimeException("Value for " + property + " cannot be null");
        }
        criteria.add(new Criterion(condition, value));
    }

    protected void addCriterion(String condition, Object value1, Object value2, String property) {
        if (value1 == null || value2 == null) {
            throw new RuntimeException("Between values for " + property + " cannot be null");
        }
        criteria.add(new Criterion(condition, value1, value2));
    }

    // ....
}

 

list 变量 List<Criterion> criteria 记录了所有的查询条件

分析下 Criterion 类的实现:

public static class Criterion {
    private String condition;

    private Object value;

    private Object secondValue;

    private boolean noValue;

    private boolean singleValue;

    private boolean betweenValue;

    private boolean listValue;

    private String typeHandler;

    public String getCondition() {
        return condition;
    }

    public Object getValue() {
        return value;
    }

    public Object getSecondValue() {
        return secondValue;
    }

    public boolean isNoValue() {
        return noValue;
    }

    public boolean isSingleValue() {
        return singleValue;
    }

    public boolean isBetweenValue() {
        return betweenValue;
    }

    public boolean isListValue() {
        return listValue;
    }

    public String getTypeHandler() {
        return typeHandler;
    }

    protected Criterion(String condition) {
        super();
        this.condition = condition;
        this.typeHandler = null;
        this.noValue = true;
    }

    protected Criterion(String condition, Object value, String typeHandler) {
        super();
        this.condition = condition;
        this.value = value;
        this.typeHandler = typeHandler;
        if (value instanceof List<?>) {
            this.listValue = true;
        } else {
            this.singleValue = true;
        }
    }

    protected Criterion(String condition, Object value) {
        this(condition, value, null);
    }

    protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
        super();
        this.condition = condition;
        this.value = value;
        this.secondValue = secondValue;
        this.typeHandler = typeHandler;
        this.betweenValue = true;
    }

    protected Criterion(String condition, Object value, Object secondValue) {
        this(condition, value, secondValue, null);
    }
}

如上,发现这个类是个把全部可能的查询条件都概括了,它是查询条件的最小实例,例如:

1) 没有查询条件,无 = noValue,即 id is null , id is not null

2) 一个查询条件,singleValue = true,即 id = 100, id != 100

3) 两个查询条件, betweenValue = true, 即 id between 1 and 100

以上三种可能,Criterion 在构造函数时已经做了区分,并会添加到 List<Criterion> criteria 的 list 中去,在xml中再做遍历、比较、拼接

 

xml 遍历、比较、拼接

StudentMapper.xml 文件,其路径为: 

\batis-generator\src\main\java\com\mimvp\demo\mapping\StudentMapper.xml

<sql id="Example_Where_Clause">
  <where>
    <foreach collection="oredCriteria" item="criteria" separator="or">
      <if test="criteria.valid">
        <trim prefix="(" prefixOverrides="and" suffix=")">
          <foreach collection="criteria.criteria" item="criterion">
            <choose>
              <when test="criterion.noValue">
                and ${criterion.condition}
              </when>
              <when test="criterion.singleValue">
                and ${criterion.condition} #{criterion.value}
              </when>
              <when test="criterion.betweenValue">
                and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
              </when>
              <when test="criterion.listValue">
                and ${criterion.condition}
                <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                  #{listItem}
                </foreach>
              </when>
            </choose>
          </foreach>
        </trim>
      </if>
    </foreach>
  </where>
</sql>

example类的意义:

通过两层循环,满足了在任意条件的任意字段的可定制化查询、更新、修改、删除,比手动和非example类实现的xml大大方便,可以满足任何条件的查询可能性

 

 

参考推荐

MyBatis 常用方法

MyBatis Generator 详解

Mybatis-Generator自动生成Dao、Model、Mapping