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
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!