Mybatis-Generator自动生成Dao、Model、Mapping高级实现
完整示例代码: 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&characterEncoding=utf8&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
6. Mybatis-Generator 生成文件
执行 maven 或 Eclipse Debug,生成 dao、mapping、model 文件
重点解析
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 类变量和方法结构:
我们分析一个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-Generator自动生成Dao、Model、Mapping
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2017-05-19 22:07:29
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!


