MyBatis Generator(MBG)是MyBatis MyBatis 和iBATIS的代碼生成器。它將爲所有版本的MyBatis以及版本2.2.0之後的iBATIS版本生成代碼。它將內省數據庫表(或許多表),並將生成可用於訪問表的工件。這減少了設置對象和配置文件以與數據庫表交互的初始麻煩。MBG尋求對簡單CRUD(創建,檢索,更新,刪除)的大部分數據庫操作產生重大影響。您仍然需要爲連接查詢或存儲過程手動編寫SQL和對象代碼。
MyBatis Generator將生成:
與表結構匹配的Java POJO。這可能包括:
-
一個匹配表的主鍵的類(如果有主鍵)
-
一個匹配表的非主鍵字段的類(BLOB字段除外)
-
包含表的BLOB字段的類(如果表具有BLOB字段)
-
用於啓用動態選擇,更新和刪除的類
這些類之間存在適當的繼承關係。請注意,生成器可以配置爲生成不同類型的POJO層次結構 - 例如,如果 您願意,可以選擇爲每個表生成單個域對象。
MyBatis / iBATIS兼容的SQL Map XML文件。MBG在配置中的每個表上爲簡單的CRUD函數生成SQL。生成的SQL語句包括:
- 插入
- 按主鍵更新
- 通過示例更新(使用動態where子句)
- 按主鍵刪除
- 按示例刪除(使用動態where子句)
- 按主鍵查詢
- 按示例查詢(使用動態where子句)
根據表的結構,這些語句有不同的變體(例如,如果表沒有主鍵,則MBG不會通過主鍵功能生成更新)。
適當使用上述對象的Java客戶端類。Java客戶端類的生成是可選的。MBG將爲MyBatis 3.x生成以下類型的
Java客戶端:適用於MyBatis 3.x映射器基礎結構的映射器接口。
MyBatis生成器設計在迭代開發環境中運行良好,並且可以作爲Ant任務或Maven插件包含在連續構建環境中。運行MBG時需要注意的重要事項包括:
- 如果存在與新生成的XML文件同名的現有文件,MBG將自動合併XML文件。MBG不會覆蓋您對其生成的XML文件所做的任何自定義更改。您可以反覆運行它,而不必擔心會丟失對XML的自定義更改。MBG將替換先前運行中生成的任何XML元素。
- MBG 不會合並Java文件,它可以覆蓋現有文件或使用不同的唯一名稱保存新生成的文件。如果對生成的Java文件進行更改並以迭代方式運行MBG,則必須手動合併更改。當作爲Eclipse 插件運行時 ,MBG可以自動合併Java文件
mybatis-generator官方地址:https://github.com/mybatis/generator/releases
mybatis-generator文檔地址:http://www.mybatis.org/generator/index.html
本文項目搭建地址:https://github.com/zhuquanwen/mybatis-learn/releases/tag/with-generator
搭建過程:
在上一篇文章基礎上搭建,有些過程不詳細描述,源碼在上一篇已附上,參見上一篇:https://blog.csdn.net/u011943534/article/details/104706455
項目結構:
1、引入mybatis-generator依賴
在pom.xml中添加依賴
<!-- mybatis-generator -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
添加編譯時資源編譯方式,把src/main/java下xml文件也編譯
<build>
...
<resources>
<!--編譯src/main/java目錄下的xml文件-->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
2、導入測試的sql
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50722
Source Host : localhost:3306
Source Database : mybatis_learn
Target Server Type : MYSQL
Target Server Version : 50722
File Encoding : 65001
Date: 2020-03-07 15:47:03
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`real_name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', 'zhangsan', '張三');
INSERT INTO `student` VALUES ('2', 'lisi', '李四');
INSERT INTO `student` VALUES ('3', 'wangwu', '王五');
3、resources下編寫代碼生成器配置XML文件generatorConfig.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指定環境 -->
<context id="MyGererator" targetRuntime="MyBatis3">
<!-- 這個標籤可以去掉各類元素生成的註釋,默認是全部生成的 -->
<commentGenerator>
<!-- 去掉註釋 -->
<property name="suppressAllComments" value="true"/>
<!-- 去掉時間戳 -->
<property name="suppressDate" value="true"/>
</commentGenerator>
<!-- 數據庫連接信息 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis_learn?useUnicode=true&characterEncoding=utf8"
userId="root"
password="root">
</jdbcConnection>
<!-- JAVA JDBC數據類型轉換,可以參照官方文檔 -->
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- javaModelGenerator javaBean配置
targetPackage 輸入包名 輸出路徑
targetProject 輸出項目位置 -->
<javaModelGenerator targetPackage="com.learn.zqw.generator.domain" targetProject="src/main/java">
<!-- enableSubPackages 是否開啓子包名稱 是否在包名後邊加上scheme名稱 -->
<property name="enableSubPackages" value="false" />
<!-- 在Set方法中加入.trim -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 映射文件mapper.xml配置 -->
<sqlMapGenerator targetPackage="com.learn.zqw.generator.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 動態代理類接口,和mapper.xml在要同一個路徑 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.learn.zqw.generator.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 數據表 根據數據庫中的表來生成 -->
<table tableName="student"/>
<!-- 數據表更詳細的屬性參見官方文檔,也可參照https://www.jianshu.com/p/e09d2370b796,裏註釋掉-->
<!-- <table schema="DB2ADMIN" tableName="ALLTYPES" domainObjectName="Customer" >
<property name="useActualColumnNames" value="true"/>
<generatedKey column="ID" sqlStatement="DB2" identity="true" />
<columnOverride column="DATE_FIELD" property="startDate" />
<ignoreColumn column="FRED" />
<columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
</table> -->
</context>
</generatorConfiguration>
如上面的配置,都已經在註釋中作了說明,更多配置可參考:https://www.jianshu.com/p/e09d2370b796
4、編寫代碼生成器主類
package com.learn.zqw.generator;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* //TODO
*
* @author zhuquanwen
* @vesion 1.0
* @date 2020/3/7 15:43
* @since jdk1.8
*/
public class Generator {
public static void main(String[] args) throws IOException, XMLParserException,
InvalidConfigurationException, SQLException, InterruptedException {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("E:\\coding\\idea\\project\\mybatis-learn\\src\\main\\resources\\generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
上面代碼中的路徑爲配置的代碼生成器配置XML的路徑
5、運行生成器
運行生成器,在配置文件配置的包下自動生成Student.java、StudentExample.java、StudentMapper.java、StudentMapper.xml
,其中Student.java爲實體,StudentExample.java爲一些條件操作的幫助類,StudentMapper.java爲數據接口,StudentMapper.xml爲SQL定義文件。
修改Student.java,去除get、set方法,並添加lombok註解。
package com.learn.zqw.generator.domain;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private String realName;
}
注意多次運行生成器會引起xml文件重疊,其他文件也會覆蓋一些已修改的內容,可以先配置一個臨時路徑,再拷貝到真實路徑下
6、增加分頁支持(可選)
可在後面的測試中看到分頁的效果
修改StudentMapper.xml再orderByClause下添加分頁支持
<if test="orderByClause != null">
order by ${orderByClause}
</if>
<if test="limit != null">
limit ${limit}
</if>
在StudentExample.java中添加屬性limit,並生成get、set方法
protected String limit;
7、在SqlMapConfig.xml中添加StudentMapper.xml的配置
<mappers>
<mapper resource="com/learn/zqw/IUserMapper.xml" />
<mapper resource="com/learn/zqw/generator/mapper/StudentMapper.xml" />
</mappers>
8、測試各類數據庫操作接口
代碼中已做了註釋
package com.learn.zqw.generator;
import com.learn.zqw.generator.domain.Student;
import com.learn.zqw.generator.domain.StudentExample;
import com.learn.zqw.generator.mapper.StudentMapper;
import lombok.Cleanup;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
/**
* //TODO
*
* @author zhuquanwen
* @vesion 1.0
* @date 2020/3/7 15:49
* @since jdk1.8
*/
@RunWith(JUnit4.class)
public class GeneratorTests {
/**
* 測試按照ID查詢
* */
@Test
public void Test1() throws IOException {
//1.讀取配置文件
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
//2. 創建SqlSessionFactory
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
//按主鍵查詢
Student student = mapper.selectByPrimaryKey(1);
Assert.assertNotNull(student);
System.out.println(student);
}
/**
* 使用Example查詢
* */
@Test
public void Test2() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentExample example = new StudentExample();
//將條件封裝到createCriteria集合中 -條件列表
example.createCriteria().andNameEqualTo("zhangsan").andRealNameIsNotNull();
//按條件查詢
List<Student> list = mapper.selectByExample(example);
System.out.println("按條件查詢:");
Assert.assertNotNull(list);
list.forEach(System.out::println);
}
/**
* 測試條件插入
* */
@Test
public void Test3() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = new Student() ;
student.setName(UUID.randomUUID().toString());
int i = mapper.insertSelective(student);
session.commit();
Assert.assertEquals(1, i);
}
/**
* 按照Example求條目
* */
@Test
public void Test4() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentExample example = new StudentExample();
example.createCriteria().andIdBetween(1, 200).andNameIn(Arrays.asList("zhangsan", "lisi"));
long l = mapper.countByExample(example);
Assert.assertEquals(2, l);
}
/**
* 測試按照Example刪除
* */
@Test
public void Test5() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = new Student();
String name = UUID.randomUUID().toString();
student.setName(name);
mapper.insertSelective(student);
session.commit();
StudentExample example = new StudentExample();
example.createCriteria().andNameEqualTo(name);
int i = mapper.deleteByExample(example);
Assert.assertEquals(1, i);
session.commit();
}
/**
* 測試按照ID刪除
* */
@Test
public void Test6() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = new Student();
String name = UUID.randomUUID().toString();
student.setName(name);
student.setId(1001);
mapper.insertSelective(student);
session.commit();
StudentExample example = new StudentExample();
example.createCriteria().andNameEqualTo(name);
int i = mapper.deleteByPrimaryKey(1001);
Assert.assertEquals(1, i);
session.commit();
}
/**
* 測試普通插入
* */
@Test
public void Test7() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = new Student();
student.setName(UUID.randomUUID().toString());
student.setRealName("測試名字");
mapper.insert(student);
session.commit();
}
/**
* 測試條件修改,並使用example
* */
@Test
public void Test8() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = new Student();
student.setRealName("測試名字");
StudentExample example = new StudentExample();
example.createCriteria().andIdGreaterThan(3);
mapper.updateByExampleSelective(student, example);
session.commit();
}
/**
* 測試普通修改,並使用example
* */
@Test
public void Test9() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentExample example = new StudentExample();
example.createCriteria().andIdGreaterThan(100);
List<Student> students = mapper.selectByExample(example);
Student student = students.get(0);
student.setRealName("測試名字22");
mapper.updateByExample(student, example);
session.commit();
}
/**
* 測試條件修改,並使用Id
* */
@Test
public void Test10() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentExample example = new StudentExample();
example.createCriteria().andIdGreaterThan(100);
List<Student> students = mapper.selectByExample(example);
Student student = students.get(0);
student.setRealName("測試名字33");
mapper.updateByPrimaryKeySelective(student);
session.commit();
}
/**
* 測試普通修改,並使用Id
* */
@Test
public void Test11() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentExample example = new StudentExample();
example.createCriteria().andIdGreaterThan(100);
List<Student> students = mapper.selectByExample(example);
Student student = students.get(0);
student.setRealName(null);
mapper.updateByPrimaryKey(student);
session.commit();
}
/**
* 測試查詢並排序
* */
@Test
public void Test12() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentExample example = new StudentExample();
example.createCriteria().andIdGreaterThan(0);
example.setOrderByClause("name asc");
List<Student> students = mapper.selectByExample(example);
students.forEach(System.out::println);
session.commit();
}
/**
* 測試自定義的排序
* */
@Test
public void Test13() throws IOException {
@Cleanup InputStream in = Resources.getResourceAsStream ("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentExample example = new StudentExample();
example.createCriteria().andIdGreaterThan(0);
example.setOrderByClause("name asc");
example.setLimit("0, 3");
List<Student> students = mapper.selectByExample(example);
students.forEach(System.out::println);
session.commit();
}
}