mybatis的使用及源碼分析(二) mybatis添加generator插件

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&amp;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();
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章