第四篇:[特殊字符] 深入理解MyBatis[特殊字符] 掌握MyBatis Generator ——入門與實戰

引言

什么是 MyBatis Generator?

MyBatis Generator (MBG) 是一個代碼生成工具,專為 MyBatis 框架設計。它可以根據數據庫表結構自動生成 Java 實體類、Mapper 接口、Mapper XML 文件以及 Example 類。通過使用 MBG,開發者可以顯著減少編寫重復代碼的工作量,提高開發效率,并確保代碼的一致性和質量。

為什么需要使用 MyBatis Generator?
  1. 提高開發效率

    • 手動編寫實體類、Mapper 接口和 XML 文件是一項繁瑣且容易出錯的任務。MBG 可以自動完成這些工作,讓開發者可以專注于業務邏輯的實現。
  2. 減少錯誤

    • 自動生成的代碼通常比手動編寫的代碼更一致且不易出錯。MBG 生成的代碼經過嚴格的測試,減少了因人為因素引入的錯誤。
  3. 一致性保證

    • 使用 MBG 生成的代碼在風格和格式上保持一致,這有助于團隊協作和代碼維護。
  4. 快速響應變化

    • 當數據庫結構發生變化時,只需重新運行 MBG 即可更新相應的 Java 代碼,大大簡化了維護工作。
  5. 支持多種數據庫

    • MBG 支持多種數據庫系統(如 MySQL、Oracle、PostgreSQL 等),使得跨數據庫平臺的應用開發更加方便。
本文的目標讀者
  • 初學者:如果你是剛剛接觸 MyBatis 或者對 MyBatis Generator 不太了解,這篇文章將幫助你從零開始學習如何使用 MBG。

  • 中級開發者:對于已經熟悉 MyBatis 但希望進一步提高開發效率的開發者,本文提供了詳細的配置和使用指南,幫助你更好地利用 MBG 的功能。

  • 高級開發者:如果你已經在項目中使用過 MBG,但希望探索其更高級的功能(如自定義模板、插件等),本文也將提供一些進階內容和最佳實踐。

  • 項目經理和技術負責人:對于負責項目管理和技術決策的人員,本文可以幫助你了解 MBG 在項目中的應用價值,從而做出更好的技術選型和決策。

?

第一部分:MyBatis Generator 概述

1.什么是 MyBatis Generator?

定義和用途

MyBatis Generator (MBG) 是一個強大的代碼生成工具,專為 MyBatis 框架設計。它可以根據數據庫表結構自動生成 Java 實體類、Mapper 接口、Mapper XML 文件以及 Example 類。通過使用 MBG,開發者可以顯著減少編寫重復代碼的工作量,提高開發效率,并確保代碼的一致性和質量。

主要功能

  1. 生成 Java 實體類

    • 根據數據庫表結構生成對應的 Java 實體類。
    • 支持基本的 CRUD 操作所需的字段和方法。
    • 可以配置是否生成構造函數、getter 和 setter 方法等。
  2. 生成 Mapper 接口

    • 生成包含基本 CRUD 操作(如 select, insert, update, delete)的 Mapper 接口。
    • 支持自定義方法的生成,可以通過插件擴展來實現更復雜的功能。
  3. 生成 Mapper XML 文件

    • 生成包含 SQL 語句映射的 XML 文件。
    • 包括基本的 SQL 語句(如 SELECT, INSERT, UPDATE, DELETE)。
    • 支持動態 SQL 生成,如 WHERE 子句的條件拼接。
  4. 生成 Example 類

    • 生成用于構建動態查詢條件的 Example 類。
    • 通過 Example 類可以方便地構建復雜的查詢條件,支持多條件組合。
  5. 支持多種數據庫

    • 支持 MySQL、Oracle、PostgreSQL、SQL Server 等多種主流數據庫系統。
    • 可以根據不同的數據庫類型生成相應的 SQL 語句。
  6. 高度可配置

    • 通過 generatorConfig.xml 配置文件,可以靈活控制生成的內容和行為。
    • 支持配置目標包路徑、表映射、生成選項等。
  7. 插件擴展

    • 支持自定義插件以擴展生成器的功能。
    • 可以通過插件實現更復雜的生成邏輯,如生成特定的業務邏輯代碼。
  8. 模板定制

    • 支持自定義 Velocity 模板,以滿足項目特定的需求。
    • 可以修改默認模板或創建新的模板,以生成符合項目規范的代碼。
  9. 增量生成

    • 支持增量生成,即只生成新增或修改的表結構對應的代碼。
    • 可以配置 overwrite 選項,決定是否覆蓋已存在的文件。
  10. 集成到 CI/CD 流程

    • 可以輕松集成到持續集成和持續部署流程中。
    • 自動化生成代碼,確保每次構建時代碼的一致性和最新性。

2 MyBatis Generator 的優勢

MyBatis Generator (MBG) 為開發者提供了多種優勢,使其成為 MyBatis 項目中不可或缺的工具。以下是 MBG 的主要優勢:

提高開發效率
  1. 自動化生成

    • MBG 可以自動生成 Java 實體類、Mapper 接口、Mapper XML 文件和 Example 類,這些通常是手動編寫時非常繁瑣且容易出錯的部分。
    • 開發者可以將更多時間集中在業務邏輯的實現上,而不是重復的代碼編寫。
  2. 快速響應變化

    • 當數據庫表結構發生變化時,只需重新運行 MBG 即可更新相應的 Java 代碼,大大簡化了維護工作。
    • 自動化生成確保了代碼與數據庫結構的一致性,減少了手動同步的工作量。
  3. 減少配置時間

    • 通過配置文件 generatorConfig.xml,可以一次性定義多個表的生成規則,避免了逐個手動配置的時間消耗。
    • 配置文件支持靈活的選項,可以根據項目需求進行調整。
減少重復代碼
  1. 一致的代碼風格

    • 自動生成的代碼在風格和格式上保持一致,減少了因人為因素引入的錯誤。
    • 一致的代碼風格使得團隊協作更加順暢,代碼維護也變得更加簡單。
  2. 避免手動錯誤

    • 手動編寫大量相似的代碼容易引入拼寫錯誤、語法錯誤等,而 MBG 生成的代碼經過嚴格的測試,減少了這類錯誤的發生。
    • 生成的代碼通常比手動編寫的代碼更可靠,提高了代碼的質量。
  3. 減少冗余代碼

    • MBG 只生成必要的代碼,避免了冗余和不必要的代碼片段。
    • 通過配置文件,可以控制生成哪些方法和字段,進一步減少冗余代碼。
一致性保證
  1. 統一的代碼模板

    • MBG 使用預定義的模板生成代碼,確保生成的代碼在風格和格式上保持一致。
    • 可以通過自定義模板來滿足項目的特定需求,但仍保持一致的代碼風格。
  2. 易于維護

    • 一致的代碼風格使得團隊成員更容易理解和維護代碼。
    • 當新的開發者加入項目時,一致的代碼風格有助于他們更快地熟悉項目代碼。
  3. 版本控制友好

    • 生成的代碼可以輕松納入版本控制系統(如 Git),便于團隊協作和版本管理。
    • 生成器配置文件也可以納入版本控制,確保所有團隊成員使用相同的生成規則。
  4. 文檔生成

    • 生成的代碼通常包含注釋和文檔,幫助開發者理解代碼的功能和用途。
    • 一致的文檔風格也有助于提高代碼的可讀性和可維護性。

3 MyBatis Generator 的工作原理

生成器的架構

MyBatis Generator (MBG) 的架構設計使其能夠高效地從數據庫表結構生成 Java 代碼。以下是 MBG 的主要組成部分及其功能:

  1. 配置文件 (generatorConfig.xml)

    • 定義了生成器的行為,包括數據庫連接信息、目標包路徑、表映射等。
    • 支持多種配置選項,如是否生成某些特定的方法(例如 selectByExample)。
  2. 數據庫元數據讀取

    • 從數據庫中讀取表結構、字段信息等元數據。
    • 支持多種數據庫驅動,如 MySQL、Oracle、PostgreSQL 等。
  3. 代碼生成器

    • 根據配置文件和數據庫元數據生成 Java 實體類、Mapper 接口、Mapper XML 文件和 Example 類。
    • 支持自定義模板和插件擴展。
  4. 輸出文件

    • 生成的代碼文件被寫入指定的目標包路徑。
    • 包括 Java 實體類、Mapper 接口、Mapper XML 文件和 Example 類。
生成過程詳解

以下是 MyBatis Generator 生成代碼的詳細過程:

  1. 讀取配置文件

    • 生成器首先讀取 generatorConfig.xml 配置文件,獲取數據庫連接信息、目標包路徑、表映射等配置。
    • 配置文件中的內容決定了生成器的行為,包括哪些表需要生成代碼、生成的目標包路徑、是否覆蓋現有文件等。
  2. 建立數據庫連接

    • 使用配置文件中的數據庫連接信息(如驅動類、URL、用戶名和密碼)建立數據庫連接。
    • 連接成功后,生成器可以訪問數據庫中的元數據。
  3. 讀取數據庫元數據

    • 通過數據庫連接讀取指定表的元數據,包括表名、字段名、字段類型、主鍵等信息。
    • 元數據是生成代碼的基礎,生成器會根據這些信息生成相應的 Java 類和 SQL 映射。
  4. 生成代碼

    • 根據讀取到的元數據和配置文件中的設置,生成相應的 Java 實體類、Mapper 接口、Mapper XML 文件和 Example 類。
    • 生成的代碼基于預定義的模板,支持自定義模板和插件擴展。
    • 生成的具體內容包括:
      • Java 實體類:包含表的字段、構造函數、getter 和 setter 方法等。
      • Mapper 接口:包含基本的 CRUD 操作方法(如 select, insert, update, delete)。
      • Mapper XML 文件:包含與 Mapper 接口方法對應的 SQL 語句。
      • Example 類:用于構建動態查詢條件的類。
  5. 寫入輸出文件

    • 將生成的代碼文件寫入指定的目標包路徑。
    • 如果配置文件中設置了 overwrite 選項,則會覆蓋已存在的文件;否則,將保留現有文件。
    • 生成的文件通常包括:
      • Java 實體類文件(例如 User.java
      • Mapper 接口文件(例如 UserMapper.java
      • Mapper XML 文件(例如 UserMapper.xml
      • Example 類文件(例如 UserExample.java
  6. 日志記錄

    • 生成過程中,生成器會記錄詳細的日志信息,包括生成的文件路徑、生成的狀態等。
    • 日志信息有助于調試和跟蹤生成過程中的問題。

第二部分:環境準備

在使用 MyBatis Generator 之前,需要確保你的開發環境已經安裝并配置了必要的工具和依賴。以下是詳細的環境準備步驟:

安裝 Java Development Kit (JDK)

JDK 的安裝步驟

  1. 下載 JDK

    • 訪問 Oracle 官方網站 或 OpenJDK 下載適合你操作系統的 JDK 版本。
    • 推薦使用 LTS(長期支持)版本,如 JDK 8 或 JDK 11。
  2. 安裝 JDK

    • 運行下載的安裝程序,并按照提示進行安裝。
    • 在 Windows 上,通常選擇默認安裝路徑(如 C:\Program Files\Java\jdk-<version>)。
    • 在 macOS 和 Linux 上,通常通過包管理器進行安裝,例如在 Ubuntu 上可以使用以下命令:
      sudo apt update
      sudo apt install openjdk-11-jdk
      
  3. 驗證安裝

    • 打開終端或命令提示符,輸入以下命令來驗證 JDK 是否安裝成功:
      java -version
      
    • 如果安裝成功,會顯示 JDK 的版本信息。

配置環境變量

  1. 設置 JAVA_HOME 環境變量

    • 在 Windows 上,打開“系統屬性” -> “高級系統設置” -> “環境變量”。
    • 在“系統變量”中點擊“新建”,添加 JAVA_HOME 變量,值為 JDK 的安裝路徑(例如 C:\Program Files\Java\jdk-<version>)。
    • 在“系統變量”中找到 Path 變量,點擊“編輯”,將 %JAVA_HOME%\bin 添加到路徑中。
  2. 在 macOS 和 Linux 上配置環境變量

    • 編輯 ~/.bashrc~/.zshrc 文件(取決于你使用的 shell),添加以下內容:
      export JAVA_HOME=/path/to/jdk
      export PATH=$JAVA_HOME/bin:$PATH
      
    • 保存文件后,運行以下命令使更改生效:
      source ~/.bashrc
      
安裝 Maven

Maven 的安裝步驟

  1. 下載 Maven

    • 訪問 Apache Maven 官方網站 下載最新版本的 Maven 壓縮包。
  2. 解壓 Maven

    • 將下載的壓縮包解壓到一個目錄,例如 C:\Program Files\Apache\maven-<version>(Windows)或 /usr/local/apache-maven-<version>(macOS/Linux)。
  3. 配置環境變量

    • 在 Windows 上

      • 打開“系統屬性” -> “高級系統設置” -> “環境變量”。
      • 在“系統變量”中點擊“新建”,添加 MAVEN_HOME 變量,值為 Maven 的安裝路徑(例如 C:\Program Files\Apache\maven-<version>)。
      • 在“系統變量”中找到 Path 變量,點擊“編輯”,將 %MAVEN_HOME%\bin 添加到路徑中。
    • 在 macOS 和 Linux 上

      • 編輯 ~/.bashrc~/.zshrc 文件,添加以下內容:
        export MAVEN_HOME=/path/to/maven
        export PATH=$MAVEN_HOME/bin:$PATH
        
      • 保存文件后,運行以下命令使更改生效:
        source ~/.bashrc
        
  4. 驗證安裝

    • 打開終端或命令提示符,輸入以下命令來驗證 Maven 是否安裝成功:
      mvn -v
      
    • 如果安裝成功,會顯示 Maven 的版本信息。
數據庫驅動的安裝

示例:MySQL JDBC 驅動的安裝

  1. 下載 MySQL JDBC 驅動

    • 訪問 MySQL 官方網站 下載最新版本的 MySQL Connector/J 驅動。
  2. 將驅動添加到項目中

    • 對于 Maven 項目

      • 在項目的 pom.xml 文件中添加以下依賴:
        <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version>
        </dependency>
        
      • 運行 mvn install 命令以下載并安裝依賴。
    • 對于非 Maven 項目

      • 將下載的 JAR 文件(例如 mysql-connector-java-8.0.23.jar)復制到項目的 lib 目錄下。
      • 在 IDE 中配置項目的類路徑,確保包含該 JAR 文件。
  3. 驗證驅動

    • 創建一個簡單的 Java 程序,嘗試連接到 MySQL 數據庫,以驗證驅動是否正確安裝和配置。例如:
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.SQLException;public class TestConnection {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/your_database";String user = "your_username";String password = "your_password";try (Connection conn = DriverManager.getConnection(url, user, password)) {System.out.println("Connected to the database!");} catch (SQLException e) {e.printStackTrace();}}
      }
      

第三部分:配置 MyBatis Generator

在這一部分,我們將詳細介紹如何配置 MyBatis Generator (MBG),包括創建 Maven 項目、配置 generatorConfig.xml 文件、配置表映射以及自定義模板。

創建 Maven 項目

使用 IDE 創建 Maven 項目

  1. 使用 IntelliJ IDEA 創建 Maven 項目

    • 打開 IntelliJ IDEA。
    • 選擇 File -> New -> Project
    • 選擇 Maven,點擊 Next
    • 輸入項目名稱和位置,點擊 Finish
  2. 使用 Eclipse 創建 Maven 項目

    • 打開 Eclipse。
    • 選擇 File -> New -> Other
    • 選擇 Maven -> Maven Project,點擊 Next
    • 選擇 Create a simple project (skip archetype selection),點擊 Next
    • 輸入項目名稱和位置,點擊 Finish

添加 MyBatis Generator 依賴

在項目的 pom.xml 文件中添加 MyBatis Generator 的依賴。此外,還需要添加數據庫驅動的依賴(以 MySQL 為例):

<dependencies><!-- MyBatis Generator 依賴 --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.4.0</version><scope>test</scope></dependency><!-- MySQL JDBC 驅動依賴 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency>
</dependencies>
創建 generatorConfig.xml 文件

配置文件的基本結構

generatorConfig.xml 是 MyBatis Generator 的核心配置文件,它定義了生成器的行為。以下是一個基本的配置文件結構:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!-- 數據庫連接信息 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/your_database"userId="your_username"password="your_password"></jdbcConnection><!-- Java 模型生成目標包 --><javaModelGenerator targetPackage="com.yourpackage.model" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- SQL 映射文件生成目標包 --><sqlMapGenerator targetPackage="com.yourpackage.mapper" targetProject="src/main/resources"><property name="enableSubPackages" value="true"/></sqlMapGenerator><!-- Mapper 接口生成目標包 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.yourpackage.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="true"/></javaClientGenerator><!-- 表配置 --><table tableName="users" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><generatedKey column="id" sqlStatement="MySql" identity="true"/></table>
</generatorConfiguration>

數據庫連接信息

  • driverClass:數據庫驅動類名。
  • connectionURL:數據庫連接 URL。
  • userId:數據庫用戶名。
  • password:數據庫密碼。

目標包和目標項目

  • targetPackage:生成的 Java 類的目標包路徑。
  • targetProject:生成的 Java 類的目標項目路徑。
  • enableSubPackages:是否啟用子包。
  • trimStrings:是否修剪字符串(去除前后空格)。
配置表映射

表配置詳解

  • tableName:數據庫表名。
  • domainObjectName:生成的實體類名。
  • enableCountByExampleenableUpdateByExampleenableDeleteByExampleenableSelectByExample:是否生成對應的 Example 方法。
  • selectByExampleQueryId:是否生成查詢 ID。

自定義生成選項

  • generatedKey:指定主鍵生成策略。

    <generatedKey column="id" sqlStatement="MySql" identity="true"/>
    
  • columnOverride:覆蓋列的屬性。

    <columnOverride column="name" property="userName" javaType="String" jdbcType="VARCHAR"/>
    
  • ignoreColumn:忽略某些列。

    <ignoreColumn column="created_at" />
    
自定義模板

使用 Velocity 模板

MyBatis Generator 支持使用 Velocity 模板來自定義生成的代碼。你可以在配置文件中指定模板路徑,并編寫自定義的 Velocity 模板。

自定義模板示例

  1. 創建自定義模板文件

    • 在項目的資源目錄下創建一個 templates 文件夾,并在其中創建自定義模板文件。例如,創建 JavaModel.vmJavaMapper.vm
  2. 編寫自定義模板

    • JavaModel.vm 示例:

      #set($className = $table.className)
      package ${table.javaModelGenerator.targetPackage};import java.util.Date;public class ${className} {#foreach ($column in $table.columns)private ${column.javaType} ${column.javaProperty};#end#foreach ($column in $table.columns)public ${column.javaType} get${column.javaProperty}() {return this.${column.javaProperty};}public void set${column.javaProperty}(${column.javaType} ${column.javaProperty}) {this.${column.javaProperty} = ${column.javaProperty};}#end
      }
      
    • JavaMapper.vm 示例:

      #set($className = $table.className)
      package ${table.javaClientGenerator.targetPackage};import org.apache.ibatis.annotations.*;
      import ${table.javaModelGenerator.targetPackage}.${table.className};public interface ${className}Mapper {@Select("SELECT * FROM ${table.tableName} WHERE id = #{id}")${className} selectById(@Param("id") Long id);@Insert("INSERT INTO ${table.tableName} (#{columns}) VALUES (#{values})")@Options(useGeneratedKeys = true, keyProperty = "id")int insert(${className} record);
      }
      
  3. 配置 generatorConfig.xml 使用自定義模板

    <table tableName="users" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><generatedKey column="id" sqlStatement="MySql" identity="true"/><context property="javaFileGenerator" value="com.yourpackage.MyCustomJavaFileGenerator"/><context property="javaClientGenerator" value="com.yourpackage.MyCustomJavaClientGenerator"/>
    </table><plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
    <plugin type="org.mybatis.generator.plugins.ToStringPlugin" /><javaModelGenerator targetPackage="com.yourpackage.model" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/><property name="templateFile" value="path/to/templates/JavaModel.vm"/>
    </javaModelGenerator><javaClientGenerator type="XMLMAPPER" targetPackage="com.yourpackage.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="templateFile" value="path/to/templates/JavaMapper.vm"/>
    </javaClientGenerator>
    

通過以上步驟,你可以配置 MyBatis Generator 以生成符合項目需求的代碼。接下來的部分將介紹如何運行 MyBatis Generator 并檢查生成的代碼。

第四部分:運行 MyBatis Generator

在這一部分,我們將詳細介紹如何運行 MyBatis Generator (MBG),包括使用命令行和 Maven 插件兩種方式。我們還將介紹生成的文件結構,幫助你理解生成的代碼。

使用命令行運行

命令行參數詳解

MyBatis Generator 可以通過命令行直接運行。以下是常用的命令行參數:

  • -configfile-c:指定配置文件的路徑。
  • -overwrite-o:是否覆蓋已存在的文件。
  • -verbose-v:輸出詳細的日志信息。
  • -help-h:顯示幫助信息。

運行示例

假設你已經將 MyBatis Generator 的 JAR 包下載到本地,并且配置文件 generatorConfig.xml 位于項目的 src/main/resources 目錄下,可以使用以下命令運行生成器:

java -jar mybatis-generator-core-1.4.0.jar -configfile src/main/resources/generatorConfig.xml -overwrite -verbose

這個命令會讀取 generatorConfig.xml 文件,并根據配置生成相應的代碼。如果目標文件已經存在,-overwrite 參數會覆蓋這些文件。-verbose 參數則會輸出詳細的日志信息,幫助你調試和跟蹤生成過程。

使用 Maven 插件運行

配置 Maven 插件

如果你使用 Maven 項目,可以通過配置 MyBatis Generator Maven 插件來運行生成器。在項目的 pom.xml 文件中添加以下插件配置:

<build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.4.0</version><configuration><configurationFile>src/main/resources/generatorConfig.xml</configurationFile><verbose>true</verbose><overwrite>true</overwrite></configuration><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency></dependencies></plugin></plugins>
</build>

運行插件示例

在終端或命令提示符中,導航到項目的根目錄并運行以下命令:

mvn mybatis-generator:generate

這個命令會讀取 generatorConfig.xml 文件,并根據配置生成相應的代碼。Maven 插件會自動處理依賴關系,并執行生成任務。

生成的文件結構

運行 MyBatis Generator 后,會在指定的目標包路徑下生成以下類型的文件:

生成的 Java 實體類

  • 文件位置src/main/java/com/yourpackage/model/User.java
  • 內容示例
    package com.yourpackage.model;public class User {private Long id;private String username;private String password;private Date createdAt;// Getter and Setter methodspublic Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Date getCreatedAt() {return createdAt;}public void setCreatedAt(Date createdAt) {this.createdAt = createdAt;}
    }
    

生成的 Mapper 接口

  • 文件位置src/main/java/com/yourpackage/mapper/UserMapper.java
  • 內容示例
    package com.yourpackage.mapper;import com.yourpackage.model.User;
    import org.apache.ibatis.annotations.*;public interface UserMapper {@Select("SELECT * FROM users WHERE id = #{id}")User selectById(@Param("id") Long id);@Insert("INSERT INTO users (username, password, created_at) VALUES (#{username}, #{password}, #{createdAt})")@Options(useGeneratedKeys = true, keyProperty = "id")int insert(User user);@Update("UPDATE users SET username = #{username}, password = #{password}, created_at = #{createdAt} WHERE id = #{id}")int update(User user);@Delete("DELETE FROM users WHERE id = #{id}")int deleteById(@Param("id") Long id);
    }
    

生成的 Mapper XML 文件

  • 文件位置src/main/resources/com/yourpackage/mapper/UserMapper.xml
  • 內容示例
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.yourpackage.mapper.UserMapper"><resultMap id="BaseResultMap" type="com.yourpackage.model.User"><id column="id" property="id" jdbcType="BIGINT"/><result column="username" property="username" jdbcType="VARCHAR"/><result column="password" property="password" jdbcType="VARCHAR"/><result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/></resultMap><sql id="Base_Column_List">id, username, password, created_at</sql><select id="selectById" resultMap="BaseResultMap">SELECT<include refid="Base_Column_List"/>FROM usersWHERE id = #{id}</select><insert id="insert" parameterType="com.yourpackage.model.User" useGeneratedKeys="true" keyProperty="id">INSERT INTO users (username, password, created_at)VALUES (#{username}, #{password}, #{createdAt})</insert><update id="update" parameterType="com.yourpackage.model.User">UPDATE usersSET username = #{username},password = #{password},created_at = #{createdAt}WHERE id = #{id}</update><delete id="deleteById">DELETE FROM usersWHERE id = #{id}</delete>
    </mapper>
    

生成的 Example 類

  • 文件位置src/main/java/com/yourpackage/model/UserExample.java
  • 內容示例
    package com.yourpackage.model;import java.util.ArrayList;
    import java.util.List;public class UserExample {protected String orderByClause;protected boolean distinct;protected List<Criteria> oredCriteria;public UserExample() {oredCriteria = new ArrayList<>();}public void setOrderByClause(String orderByClause) {this.orderByClause = orderByClause;}public String getOrderByClause() {return orderByClause;}public void setDistinct(boolean distinct) {this.distinct = distinct;}public boolean isDistinct() {return distinct;}public List<Criteria> getOredCriteria() {return oredCriteria;}public void or(Criteria criteria) {oredCriteria.add(criteria);}public Criteria or() {Criteria criteria = createCriteriaInternal();oredCriteria.add(criteria);return criteria;}public Criteria createCriteria() {Criteria criteria = createCriteriaInternal();if (oredCriteria.size() == 0) {oredCriteria.add(criteria);}return criteria;}protected Criteria createCriteriaInternal() {Criteria criteria = new Criteria();return criteria;}public void clear() {oredCriteria.clear();orderByClause = null;distinct = false;}protected abstract static class GeneratedCriteria {protected List<Criterion> criteria;protected GeneratedCriteria() {super();criteria = new ArrayList<>();}public boolean isValid() {return criteria.size() > 0;}public List<Criterion> getAllCriteria() {return criteria;}public List<Criterion> getCriteria() {return criteria;}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));}public Criteria andIdIsNull() {addCriterion("id is null");return (Criteria) this;}public Criteria andIdIsNotNull() {addCriterion("id is not null");return (Criteria) this;}public Criteria andIdEqualTo(Long value) {addCriterion("id =", value, "id");return (Criteria) this;}public Criteria andIdNotEqualTo(Long value) {addCriterion("id <>", value, "id");return (Criteria) this;}public Criteria andIdGreaterThan(Long value) {addCriterion("id >", value, "id");return (Criteria) this;}public Criteria andIdGreaterThanOrEqualTo(Long value) {addCriterion("id >=", value, "id");return (Criteria) this;}public Criteria andIdLessThan(Long value) {addCriterion("id <", value, "id");return (Criteria) this;}public Criteria andIdLessThanOrEqualTo(Long value) {addCriterion("id <=", value, "id");return (Criteria) this;}public Criteria andIdIn(List<Long> values) {addCriterion("id in", values, "id");return (Criteria) this;}public Criteria andIdNotIn(List<Long> values) {addCriterion("id not in", values, "id");return (Criteria) this;}public Criteria andIdBetween(Long value1, Long value2) {addCriterion("id between", value1, value2, "id");return (Criteria) this;}public Criteria andIdNotBetween(Long value1, Long value2) {addCriterion("id not between", value1, value2, "id");return (Criteria) this;}public Criteria andUsernameIsNull() {addCriterion("username is null");return (Criteria) this;}public Criteria andUsernameIsNotNull() {addCriterion("username is not null");return (Criteria) this;}public Criteria andUsernameEqualTo(String value) {addCriterion("username =", value, "username");return (Criteria) this;}public Criteria andUsernameNotEqualTo(String value) {addCriterion("username <>", value, "username");return (Criteria) this;}public Criteria andUsernameGreaterThan(String value) {addCriterion("username >", value, "username");return (Criteria) this;}public Criteria andUsernameGreaterThanOrEqualTo(String value) {addCriterion("username >=", value, "username");return (Criteria) this;}public Criteria andUsernameLessThan(String value) {addCriterion("username <", value, "username");return (Criteria) this;}public Criteria andUsernameLessThanOrEqualTo(String value) {addCriterion("username <=", value, "username");return (Criteria) this;}public Criteria andUsernameLike(String value) {addCriterion("username like", value, "username");return (Criteria) this;}public Criteria andUsernameNotLike(String value) {addCriterion("username not like", value, "username");return (Criteria) this;}public Criteria andUsernameIn(List<String> values) {addCriterion("username in", values, "username");return (Criteria) this;}public Criteria andUsernameNotIn(List<String> values) {addCriterion("username not in", values, "username");return (Criteria) this;}public Criteria andUsernameBetween(String value1, String value2) {addCriterion("username between", value1, value2, "username");return (Criteria) this;}public Criteria andUsernameNotBetween(String value1, String value2) {addCriterion("username not between", value1, value2, "username");return (Criteria) this;}public Criteria andPasswordIsNull() {addCriterion("password is null");return (Criteria) this;}public Criteria andPasswordIsNotNull() {addCriterion("password is not null");return (Criteria) this;}public Criteria andPasswordEqualTo(String value) {addCriterion("password =", value, "password");return (Criteria) this;}public Criteria andPasswordNotEqualTo(String value) {addCriterion("password <>", value, "password");return (Criteria) this;}public Criteria andPasswordGreaterThan(String value) {addCriterion("password >", value, "password");return (Criteria) this;}public Criteria andPasswordGreaterThanOrEqualTo(String value) {addCriterion("password >=", value, "password");return (Criteria) this;}public Criteria andPasswordLessThan(String value) {addCriterion("password <", value, "password");return (Criteria) this;}public Criteria andPasswordLessThanOrEqualTo(String value) {addCriterion("password <=", value, "password");return (Criteria) this;}public Criteria andPasswordLike(String value) {addCriterion("password like", value, "password");return (Criteria) this;}public Criteria andPasswordNotLike(String value) {addCriterion("password not like", value, "password");return (Criteria) this;}public Criteria andPasswordIn(List<String> values) {addCriterion("password in", values, "password");return (Criteria) this;}public Criteria andPasswordNotIn(List<String> values) {addCriterion("password not in", values, "password");return (Criteria) this;}public Criteria andPasswordBetween(String value1, String value2) {addCriterion("password between", value1, value2, "password");return (Criteria) this;}public Criteria andPasswordNotBetween(String value1, String value2) {addCriterion("password not between", value1, value2, "password");return (Criteria) this;}public Criteria andCreatedAtIsNull() {addCriterion("created_at is null");return (Criteria) this;}public Criteria andCreatedAtIsNotNull() {addCriterion("created_at is not null");return (Criteria) this;}public Criteria andCreatedAtEqualTo(Date value) {addCriterion("created_at =", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtNotEqualTo(Date value) {addCriterion("created_at <>", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtGreaterThan(Date value) {addCriterion("created_at >", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtGreaterThanOrEqualTo(Date value) {addCriterion("created_at >=", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtLessThan(Date value) {addCriterion("created_at <", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtLessThanOrEqualTo(Date value) {addCriterion("created_at <=", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtIn(List<Date> values) {addCriterion("created_at in", values, "createdAt");return (Criteria) this;}public Criteria andCreatedAtNotIn(List<Date> values) {addCriterion("created_at not in", values, "createdAt");return (Criteria) this;}public Criteria andCreatedAtBetween(Date value1, Date value2) {addCriterion("created_at between", value1, value2, "createdAt");return (Criteria) this;}public Criteria andCreatedAtNotBetween(Date value1, Date value2) {addCriterion("created_at not between", value1, value2, "createdAt");return (Criteria) this;}}public static class Criteria extends GeneratedCriteria {protected Criteria() {super();}}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;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);}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;}}
    }
    

通過以上步驟,你可以成功運行 MyBatis Generator 并生成所需的代碼文件。生成的文件結構清晰,便于管理和維護。接下來的部分將介紹如何進一步優化和擴展 MyBatis Generator 的功能。

第五部分:生成的內容詳解

在這一部分,我們將詳細介紹 MyBatis Generator 生成的各個文件的具體內容和結構,包括 Java 實體類、Mapper 接口、Mapper XML 文件和 Example 類。這將幫助你更好地理解和使用生成的代碼。

Java 實體類

字段映射

  • 字段:Java 實體類中的字段與數據庫表中的列一一對應。
  • 注解:字段上通常會添加 @Column 注解(如果使用 JPA)或其他相關注解來描述字段屬性。

構造函數和方法

  • 默認構造函數:無參構造函數,用于對象的初始化。
  • 帶參數的構造函數:根據需要生成帶參數的構造函數。
  • Getter 和 Setter 方法:每個字段都有對應的 Getter 和 Setter 方法,用于獲取和設置字段值。

示例

假設有一個 users 表,包含 id, username, password, 和 created_at 字段,生成的 User 實體類如下:

package com.yourpackage.model;import java.util.Date;public class User {private Long id;private String username;private String password;private Date createdAt;// 默認構造函數public User() {}// 帶參數的構造函數public User(Long id, String username, String password, Date createdAt) {this.id = id;this.username = username;this.password = password;this.createdAt = createdAt;}// Getter 和 Setter 方法public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Date getCreatedAt() {return createdAt;}public void setCreatedAt(Date createdAt) {this.createdAt = createdAt;}
}
Mapper 接口

CRUD 方法

  • selectById:根據主鍵查詢單個記錄。
  • insert:插入一條新記錄。
  • update:更新現有記錄。
  • deleteById:根據主鍵刪除記錄。

自定義方法

  • 可以通過配置文件或自定義插件添加額外的方法。

示例

package com.yourpackage.mapper;import com.yourpackage.model.User;
import org.apache.ibatis.annotations.*;public interface UserMapper {@Select("SELECT * FROM users WHERE id = #{id}")User selectById(@Param("id") Long id);@Insert("INSERT INTO users (username, password, created_at) VALUES (#{username}, #{password}, #{createdAt})")@Options(useGeneratedKeys = true, keyProperty = "id")int insert(User user);@Update("UPDATE users SET username = #{username}, password = #{password}, created_at = #{createdAt} WHERE id = #{id}")int update(User user);@Delete("DELETE FROM users WHERE id = #{id}")int deleteById(@Param("id") Long id);// 自定義方法@Select("SELECT * FROM users WHERE username = #{username}")User selectByUsername(@Param("username") String username);
}
Mapper XML 文件

SQL 語句映射

  • Result Map:定義了結果集與實體類之間的映射關系。
  • SQL 語句:定義了具體的 SQL 語句,如 SELECT, INSERT, UPDATE, DELETE

參數傳遞

  • 使用 #{} 占位符傳遞參數,MyBatis 會自動處理類型轉換和防止 SQL 注入。

示例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.yourpackage.mapper.UserMapper"><resultMap id="BaseResultMap" type="com.yourpackage.model.User"><id column="id" property="id" jdbcType="BIGINT"/><result column="username" property="username" jdbcType="VARCHAR"/><result column="password" property="password" jdbcType="VARCHAR"/><result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/></resultMap><sql id="Base_Column_List">id, username, password, created_at</sql><select id="selectById" resultMap="BaseResultMap">SELECT<include refid="Base_Column_List"/>FROM usersWHERE id = #{id}</select><insert id="insert" parameterType="com.yourpackage.model.User" useGeneratedKeys="true" keyProperty="id">INSERT INTO users (username, password, created_at)VALUES (#{username}, #{password}, #{createdAt})</insert><update id="update" parameterType="com.yourpackage.model.User">UPDATE usersSET username = #{username},password = #{password},created_at = #{createdAt}WHERE id = #{id}</update><delete id="deleteById">DELETE FROM usersWHERE id = #{id}</delete><!-- 自定義方法 --><select id="selectByUsername" resultMap="BaseResultMap">SELECT<include refid="Base_Column_List"/>FROM usersWHERE username = #{username}</select>
</mapper>
Example 類

動態查詢條件

  • Criteria:用于構建復雜的查詢條件。
  • Example:封裝了多個 Criteria 對象,支持多條件組合。

使用示例

package com.yourpackage.model;import java.util.ArrayList;
import java.util.List;public class UserExample {protected String orderByClause;protected boolean distinct;protected List<Criteria> oredCriteria;public UserExample() {oredCriteria = new ArrayList<>();}public void setOrderByClause(String orderByClause) {this.orderByClause = orderByClause;}public String getOrderByClause() {return orderByClause;}public void setDistinct(boolean distinct) {this.distinct = distinct;}public boolean isDistinct() {return distinct;}public List<Criteria> getOredCriteria() {return oredCriteria;}public void or(Criteria criteria) {oredCriteria.add(criteria);}public Criteria or() {Criteria criteria = createCriteriaInternal();oredCriteria.add(criteria);return criteria;}public Criteria createCriteria() {Criteria criteria = createCriteriaInternal();if (oredCriteria.size() == 0) {oredCriteria.add(criteria);}return criteria;}protected Criteria createCriteriaInternal() {Criteria criteria = new Criteria();return criteria;}public void clear() {oredCriteria.clear();orderByClause = null;distinct = false;}protected abstract static class GeneratedCriteria {protected List<Criterion> criteria;protected GeneratedCriteria() {super();criteria = new ArrayList<>();}public boolean isValid() {return criteria.size() > 0;}public List<Criterion> getAllCriteria() {return criteria;}public List<Criterion> getCriteria() {return criteria;}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));}public Criteria andIdIsNull() {addCriterion("id is null");return (Criteria) this;}public Criteria andIdIsNotNull() {addCriterion("id is not null");return (Criteria) this;}public Criteria andIdEqualTo(Long value) {addCriterion("id =", value, "id");return (Criteria) this;}public Criteria andIdNotEqualTo(Long value) {addCriterion("id <>", value, "id");return (Criteria) this;}public Criteria andIdGreaterThan(Long value) {addCriterion("id >", value, "id");return (Criteria) this;}public Criteria andIdGreaterThanOrEqualTo(Long value) {addCriterion("id >=", value, "id");return (Criteria) this;}public Criteria andIdLessThan(Long value) {addCriterion("id <", value, "id");return (Criteria) this;}public Criteria andIdLessThanOrEqualTo(Long value) {addCriterion("id <=", value, "id");return (Criteria) this;}public Criteria andIdIn(List<Long> values) {addCriterion("id in", values, "id");return (Criteria) this;}public Criteria andIdNotIn(List<Long> values) {addCriterion("id not in", values, "id");return (Criteria) this;}public Criteria andIdBetween(Long value1, Long value2) {addCriterion("id between", value1, value2, "id");return (Criteria) this;}public Criteria andIdNotBetween(Long value1, Long value2) {addCriterion("id not between", value1, value2, "id");return (Criteria) this;}public Criteria andUsernameIsNull() {addCriterion("username is null");return (Criteria) this;}public Criteria andUsernameIsNotNull() {addCriterion("username is not null");return (Criteria) this;}public Criteria andUsernameEqualTo(String value) {addCriterion("username =", value, "username");return (Criteria) this;}public Criteria andUsernameNotEqualTo(String value) {addCriterion("username <>", value, "username");return (Criteria) this;}public Criteria andUsernameGreaterThan(String value) {addCriterion("username >", value, "username");return (Criteria) this;}public Criteria andUsernameGreaterThanOrEqualTo(String value) {addCriterion("username >=", value, "username");return (Criteria) this;}public Criteria andUsernameLessThan(String value) {addCriterion("username <", value, "username");return (Criteria) this;}public Criteria andUsernameLessThanOrEqualTo(String value) {addCriterion("username <=", value, "username");return (Criteria) this;}public Criteria andUsernameLike(String value) {addCriterion("username like", value, "username");return (Criteria) this;}public Criteria andUsernameNotLike(String value) {addCriterion("username not like", value, "username");return (Criteria) this;}public Criteria andUsernameIn(List<String> values) {addCriterion("username in", values, "username");return (Criteria) this;}public Criteria andUsernameNotIn(List<String> values) {addCriterion("username not in", values, "username");return (Criteria) this;}public Criteria andUsernameBetween(String value1, String value2) {addCriterion("username between", value1, value2, "username");return (Criteria) this;}public Criteria andUsernameNotBetween(String value1, String value2) {addCriterion("username not between", value1, value2, "username");return (Criteria) this;}public Criteria andPasswordIsNull() {addCriterion("password is null");return (Criteria) this;}public Criteria andPasswordIsNotNull() {addCriterion("password is not null");return (Criteria) this;}public Criteria andPasswordEqualTo(String value) {addCriterion("password =", value, "password");return (Criteria) this;}public Criteria andPasswordNotEqualTo(String value) {addCriterion("password <>", value, "password");return (Criteria) this;}public Criteria andPasswordGreaterThan(String value) {addCriterion("password >", value, "password");return (Criteria) this;}public Criteria andPasswordGreaterThanOrEqualTo(String value) {addCriterion("password >=", value, "password");return (Criteria) this;}public Criteria andPasswordLessThan(String value) {addCriterion("password <", value, "password");return (Criteria) this;}public Criteria andPasswordLessThanOrEqualTo(String value) {addCriterion("password <=", value, "password");return (Criteria) this;}public Criteria andPasswordLike(String value) {addCriterion("password like", value, "password");return (Criteria) this;}public Criteria andPasswordNotLike(String value) {addCriterion("password not like", value, "password");return (Criteria) this;}public Criteria andPasswordIn(List<String> values) {addCriterion("password in", values, "password");return (Criteria) this;}public Criteria andPasswordNotIn(List<String> values) {addCriterion("password not in", values, "password");return (Criteria) this;}public Criteria andPasswordBetween(String value1, String value2) {addCriterion("password between", value1, value2, "password");return (Criteria) this;}public Criteria andPasswordNotBetween(String value1, String value2) {addCriterion("password not between", value1, value2, "password");return (Criteria) this;}public Criteria andCreatedAtIsNull() {addCriterion("created_at is null");return (Criteria) this;}public Criteria andCreatedAtIsNotNull() {addCriterion("created_at is not null");return (Criteria) this;}public Criteria andCreatedAtEqualTo(Date value) {addCriterion("created_at =", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtNotEqualTo(Date value) {addCriterion("created_at <>", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtGreaterThan(Date value) {addCriterion("created_at >", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtGreaterThanOrEqualTo(Date value) {addCriterion("created_at >=", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtLessThan(Date value) {addCriterion("created_at <", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtLessThanOrEqualTo(Date value) {addCriterion("created_at <=", value, "createdAt");return (Criteria) this;}public Criteria andCreatedAtIn(List<Date> values) {addCriterion("created_at in", values, "createdAt");return (Criteria) this;}public Criteria andCreatedAtNotIn(List<Date> values) {addCriterion("created_at not in", values, "createdAt");return (Criteria) this;}public Criteria andCreatedAtBetween(Date value1, Date value2) {addCriterion("created_at between", value1, value2, "createdAt");return (Criteria) this;}public Criteria andCreatedAtNotBetween(Date value1, Date value2) {addCriterion("created_at not between", value1, value2, "createdAt");return (Criteria) this;}}public static class Criteria extends GeneratedCriteria {protected Criteria() {super();}}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;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);}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;}}
}

使用示例

import com.yourpackage.mapper.UserMapper;
import com.yourpackage.model.User;
import com.yourpackage.model.UserExample;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.InputStream;
import java.util.List;public class Main {public static void main(String[] args) {// 讀取 MyBatis 配置文件InputStream inputStream = Main.class.getResourceAsStream("/mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);try (SqlSession session = sqlSessionFactory.openSession()) {UserMapper userMapper = session.getMapper(UserMapper.class);// 查詢所有用戶List<User> users = userMapper.selectAll();for (User user : users) {System.out.println(user);}// 根據用戶名查詢用戶UserExample example = new UserExample();example.createCriteria().andUsernameEqualTo("testuser");List<User> usersByName = userMapper.selectByExample(example);for (User user : usersByName) {System.out.println(user);}// 插入新用戶User newUser = new User(null, "newuser", "newpassword", new Date());userMapper.insert(newUser);session.commit();// 更新用戶User updateUser = new User(1L, "updateduser", "updatedpassword", new Date());userMapper.update(updateUser);session.commit();// 刪除用戶userMapper.deleteById(1L);session.commit();}}
}

通過以上內容,你可以詳細了解 MyBatis Generator 生成的各個文件的具體結構和用法。這些生成的文件為你的項目提供了堅實的基礎,使你能夠更高效地進行開發。接下來的部分將介紹如何進一步擴展和優化 MyBatis Generator 的功能。

第六部分:常見問題及解決方案

在使用 MyBatis Generator 時,可能會遇到一些常見的問題。本部分將介紹這些問題及其解決方法,并提供一些性能優化的建議。

常見錯誤及解決方法

數據庫連接失敗

癥狀

  • 生成器無法連接到數據庫。
  • 日志中顯示連接超時或認證失敗等錯誤信息。

解決方法

  1. 檢查數據庫連接配置

    • 確保 generatorConfig.xml 中的數據庫連接信息(如驅動類、URL、用戶名和密碼)正確無誤。
    • 例如:
      <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/your_database"userId="your_username"password="your_password">
      </jdbcConnection>
      
  2. 檢查數據庫服務是否運行

    • 確保數據庫服務已經啟動并且可以訪問。
    • 使用數據庫管理工具(如 MySQL Workbench 或 pgAdmin)測試連接。
  3. 檢查網絡連接

    • 確保你的開發環境可以訪問數據庫服務器。
    • 檢查防火墻設置,確保端口未被阻止。
  4. 檢查驅動依賴

    • 確保項目中包含了正確的數據庫驅動依賴。
    • 例如,對于 MySQL:
      <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version>
      </dependency>
      

生成的代碼不符合預期

癥狀

  • 生成的 Java 實體類、Mapper 接口或 XML 文件不符合預期。
  • 缺少某些字段或方法。

解決方法

  1. 檢查表配置

    • 確保 generatorConfig.xml 中的 <table> 配置正確。
    • 例如:
      <table tableName="users" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><generatedKey column="id" sqlStatement="MySql" identity="true"/>
      </table>
      
  2. 檢查字段映射

    • 確保數據庫表中的字段名稱和類型正確。
    • 如果需要忽略某些字段,可以使用 <ignoreColumn> 標簽。
    • 例如:
      <ignoreColumn column="created_at" />
      
  3. 自定義模板

    • 如果默認模板生成的代碼不符合需求,可以使用自定義模板。
    • 參考前面的自定義模板部分,編寫和配置自定義模板文件。
  4. 調試日志

    • 啟用詳細日志輸出,查看生成過程中的詳細信息。
    • generatorConfig.xml 中添加 <verbose>true</verbose> 選項。
    • 例如:
      <configuration><configurationFile>src/main/resources/generatorConfig.xml</configurationFile><verbose>true</verbose><overwrite>true</overwrite>
      </configuration>
      
性能優化

優化生成配置

  1. 選擇性生成

    • 只生成必要的表和字段,避免不必要的生成。
    • 使用 <table><ignoreColumn> 標簽來控制生成的內容。
    • 例如:
      <table tableName="users" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><ignoreColumn column="created_at" />
      </table>
      
  2. 增量生成

    • 通過配置 overwrite 選項,只覆蓋已存在的文件。
    • 例如:
      <configuration><configurationFile>src/main/resources/generatorConfig.xml</configurationFile><overwrite>false</overwrite>
      </configuration>
      
  3. 減少生成的方法

    • 通過配置 <table> 的屬性,禁用不需要的方法。
    • 例如:
      <table tableName="users" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
      </table>
      

減少不必要的生成

  1. 分批生成

    • 將生成任務分成多個小任務,每次只生成一部分表。
    • 例如,創建多個 generatorConfig.xml 文件,每個文件負責一部分表的生成。
  2. 條件生成

    • 使用插件來實現條件生成邏輯,根據特定條件決定是否生成某些代碼。
    • 例如,編寫一個插件,在生成前檢查某些條件,如果條件不滿足則跳過生成。
  3. 緩存生成結果

    • 對于不經常變化的表結構,可以將生成的結果緩存起來,避免頻繁生成。
    • 例如,將生成的代碼文件存儲在版本控制系統中,只有在表結構發生變化時才重新生成。

第七部分:最佳實踐

在使用 MyBatis Generator 時,遵循一些最佳實踐可以幫助你更好地管理代碼、確保安全性,并提高開發效率。本部分將介紹代碼管理、安全性考慮和持續集成的最佳實踐。

代碼管理

將配置文件納入版本控制

  1. 配置文件版本化

    • generatorConfig.xml 文件納入版本控制系統(如 Git),確保所有團隊成員使用相同的配置。
    • 這有助于保持生成的代碼一致性和可追溯性。
  2. 文檔說明

    • 在項目文檔中詳細說明 generatorConfig.xml 的配置規則和注意事項,幫助新加入的團隊成員快速上手。
  3. 定期審查

    • 定期審查 generatorConfig.xml 文件,確保其配置符合當前項目需求。
    • 可以通過代碼審查工具(如 GitHub Pull Requests 或 GitLab Merge Requests)進行審查。

團隊協作

  1. 統一規范

    • 制定統一的命名規范和編碼風格,確保生成的代碼風格一致。
    • 例如,統一表名和類名的命名規則,字段名稱的轉換規則等。
  2. 共享知識

    • 定期組織技術分享會,讓經驗豐富的開發者向團隊成員傳授 MyBatis Generator 的使用技巧和經驗。
    • 創建內部知識庫或 Wiki,記錄常見問題及解決方案。
  3. 權限管理

    • 限制對 generatorConfig.xml 文件的修改權限,確保只有授權人員可以進行修改。
    • 使用版本控制系統中的分支管理和合并策略,避免沖突和誤操作。
安全性考慮

防止 SQL 注入

  1. 使用參數化查詢

    • 確保生成的 SQL 語句使用參數化查詢,而不是直接拼接字符串。
    • MyBatis Generator 生成的代碼默認使用參數化查詢,但仍需注意手動編寫的 SQL 語句。
  2. 輸入驗證

    • 對用戶輸入進行嚴格的驗證和過濾,確保輸入符合預期的格式和類型。
    • 例如,使用正則表達式或其他驗證庫來檢查輸入的有效性。
  3. 日志記錄

    • 記錄重要的數據庫操作,并定期審查日志文件,及時發現異常行為。
    • 避免在錯誤消息中暴露過多的細節,這可能幫助攻擊者進一步利用漏洞。

數據庫權限管理

  1. 最小權限原則

    • 數據庫用戶應僅擁有執行其任務所需的最小權限。
    • 例如,如果一個應用程序只需要讀取數據,則不要賦予其寫入或刪除數據的權限。
  2. 角色分離

    • 分離不同的數據庫角色,確保每個角色只具有必要的權限。
    • 例如,創建專門用于讀取數據的角色和專門用于寫入數據的角色。
  3. 定期審計

    • 定期審查數據庫用戶的權限設置,確保沒有不必要的權限。
    • 使用數據庫自帶的安全審計工具,監控和記錄敏感操作。
持續集成

自動化生成

  1. 集成到 CI/CD 流程

    • 將 MyBatis Generator 集成到持續集成和持續部署流程中,確保每次構建時代碼的一致性和最新性。
    • 例如,在 Jenkins 或 GitLab CI/CD 中配置自動運行 MyBatis Generator 的步驟。
  2. 定時生成

    • 設置定時任務,定期運行 MyBatis Generator 以更新生成的代碼。
    • 例如,每天凌晨自動運行生成器,確保代碼與數據庫結構同步。

測試生成的代碼

  1. 單元測試

    • 為生成的 Mapper 接口編寫單元測試,確保生成的代碼功能正確。
    • 使用 JUnit 或其他測試框架編寫測試用例,覆蓋基本的 CRUD 操作和其他自定義方法。
  2. 集成測試

    • 編寫集成測試,驗證生成的代碼與數據庫交互的正確性。
    • 使用測試數據庫或內存數據庫(如 H2)進行集成測試,確保測試環境與生產環境隔離。
  3. 代碼覆蓋率

    • 使用代碼覆蓋率工具(如 JaCoCo)監控測試覆蓋率,確保生成的代碼得到充分測試。
    • 定期審查代碼覆蓋率報告,找出未被測試的代碼路徑并補充測試用例。
  4. 靜態代碼分析

    • 使用靜態代碼分析工具(如 SonarQube)檢查生成的代碼質量。
    • 配置靜態代碼分析工具,自動檢測潛在的問題和安全漏洞。

附錄

在附錄部分,我們將提供一些常用的配置示例和相關工具及資源鏈接,幫助你更方便地使用 MyBatis Generator。

常用配置示例

基本配置示例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!-- 數據庫連接信息 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/your_database"userId="your_username"password="your_password"></jdbcConnection><!-- Java 模型生成目標包 --><javaModelGenerator targetPackage="com.yourpackage.model" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- SQL 映射文件生成目標包 --><sqlMapGenerator targetPackage="com.yourpackage.mapper" targetProject="src/main/resources"><property name="enableSubPackages" value="true"/></sqlMapGenerator><!-- Mapper 接口生成目標包 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.yourpackage.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="true"/></javaClientGenerator><!-- 表配置 --><table tableName="users" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><generatedKey column="id" sqlStatement="MySql" identity="true"/></table>
</generatorConfiguration>

多數據庫連接配置示例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!-- 數據庫連接 1 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/your_database_1"userId="your_username_1"password="your_password_1"></jdbcConnection><!-- 數據庫連接 2 --><jdbcConnection driverClass="org.postgresql.Driver"connectionURL="jdbc:postgresql://localhost:5432/your_database_2"userId="your_username_2"password="your_password_2"></jdbcConnection><!-- Java 模型生成目標包 --><javaModelGenerator targetPackage="com.yourpackage.model" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- SQL 映射文件生成目標包 --><sqlMapGenerator targetPackage="com.yourpackage.mapper" targetProject="src/main/resources"><property name="enableSubPackages" value="true"/></sqlMapGenerator><!-- Mapper 接口生成目標包 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.yourpackage.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="true"/></javaClientGenerator><!-- 表配置 1 --><table tableName="users_1" domainObjectName="User1" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><generatedKey column="id" sqlStatement="MySql" identity="true"/></table><!-- 表配置 2 --><table tableName="users_2" domainObjectName="User2" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><generatedKey column="id" sqlStatement="PostgreSQL" identity="true"/></table>
</generatorConfiguration>

自定義插件配置示例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!-- 數據庫連接信息 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/your_database"userId="your_username"password="your_password"></jdbcConnection><!-- Java 模型生成目標包 --><javaModelGenerator targetPackage="com.yourpackage.model" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- SQL 映射文件生成目標包 --><sqlMapGenerator targetPackage="com.yourpackage.mapper" targetProject="src/main/resources"><property name="enableSubPackages" value="true"/></sqlMapGenerator><!-- Mapper 接口生成目標包 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.yourpackage.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="true"/></javaClientGenerator><!-- 自定義插件 --><plugin type="com.yourpackage.CustomPlugin" /><!-- 表配置 --><table tableName="users" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><generatedKey column="id" sqlStatement="MySql" identity="true"/></table>
</generatorConfiguration>

自定義模板配置示例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!-- 數據庫連接信息 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/your_database"userId="your_username"password="your_password"></jdbcConnection><!-- Java 模型生成目標包 --><javaModelGenerator targetPackage="com.yourpackage.model" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/><property name="templateFile" value="path/to/templates/JavaModel.vm"/></javaModelGenerator><!-- SQL 映射文件生成目標包 --><sqlMapGenerator targetPackage="com.yourpackage.mapper" targetProject="src/main/resources"><property name="enableSubPackages" value="true"/><property name="templateFile" value="path/to/templates/SqlMap.vm"/></sqlMapGenerator><!-- Mapper 接口生成目標包 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.yourpackage.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="templateFile" value="path/to/templates/JavaMapper.vm"/></javaClientGenerator><!-- 表配置 --><table tableName="users" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><generatedKey column="id" sqlStatement="MySql" identity="true"/></table>
</generatorConfiguration>

    結語


    1. 回顧核心價值

    通過本系列文章的學習,我們深入探討了 MyBatis 這一靈活、高效的持久層框架,以及其代碼生成工具 MyBatis Generator 的核心機制與實踐技巧。以下是核心收獲總結:

    • MyBatis 的核心優勢

      • SQL 與代碼解耦:通過 XML 或注解直接管理 SQL,兼顧靈活性與可維護性。
      • 動態 SQL 能力:借助 <if><foreach> 等標簽,輕松應對復雜查詢邏輯。
      • 高度可定制化:插件機制(Interceptor)支持擴展框架行為(如分頁、性能監控)。
      • 與 Spring 生態無縫集成:通過 SqlSessionTemplate@MapperScan 簡化配置。
    • MyBatis Generator 的實戰意義

      • 自動化代碼生成:快速生成實體類、Mapper 接口及 XML 文件,減少重復勞動。
      • 規范開發流程:統一代碼風格,避免人工編碼的潛在錯誤。
      • 支持自定義模板:通過修改模板文件(如 generatorConfig.ftl)適配個性化需求。

    2. 實戰中的關鍵啟示

    在入門與實戰過程中,以下幾個要點值得反復強調:

    1. 配置文件是核心
      • mybatis-config.xml 中全局配置(如緩存、類型處理器)需貼合項目需求。
      • generatorConfig.xml 的精準配置(數據源、生成策略)決定了代碼生成的質量。
    2. 插件擴展與優化
      • 利用 MyBatis 插件實現 SQL 日志打印、分頁邏輯封裝。
      • 通過自定義 Generator 插件添加 Lombok 注解、Swagger 文檔等實用功能。
    3. 避免過度依賴生成工具
      • 生成的代碼需結合業務邏輯二次調整(如復雜關聯查詢、DTO 封裝)。
      • 手動編寫部分 SQL 以優化性能或實現特殊需求。

    3. 繼續探索的方向

    MyBatis 和 MyBatis Generator 的深入學習永無止境。以下是進一步精進的建議:

    • 高級特性研究
      • 深入理解 一級緩存與二級緩存 的機制與適用場景。
      • 掌握 延遲加載(Lazy Loading) 的配置與性能優化。
    • 源碼與插件開發
      • 閱讀 MyBatis 核心源碼(如 SqlSessionExecutor),理解執行流程。
      • 開發自定義插件,實現審計日志、數據脫敏等企業級功能。
    • 生態整合實踐
      • 結合 Spring Boot 的 mybatis-spring-boot-starter 實現零配置快速集成。
      • 探索與分布式框架(如 MyBatis-Plus、ShardingSphere)的協同使用。

    4. 資源推薦
    • 官方文檔
      • MyBatis 官方文檔
      • MyBatis Generator 配置指南
    • 社區與工具
      • GitHub 開源項目:MyBatis 插件集合
      • 代碼生成模板庫:MyBatis Generator 自定義模板示例
    • 延伸閱讀
      • 書籍:《MyBatis 從入門到精通》(劉增輝 著)
      • 博客系列:MyBatis 源碼深度解析

    5. 最后的話

    技術的學習不僅是工具的掌握,更是設計思想與工程實踐的融合。MyBatis 以其“輕量級”與“高可控性”,在 ORM 與原生 SQL 之間找到了完美平衡,而 MyBatis Generator 則進一步解放了開發者的生產力。

    鼓勵行動

    • 立即嘗試為你的項目引入 MyBatis Generator,感受自動化生成的便捷。
    • 在下一個需求中,嘗試手寫復雜 SQL 并優化其性能,體會 MyBatis 的靈活性。

    愿你在持久層開發的征途中,既能高效完成需求,又能深入技術本質,成為真正的“SQL 手藝人”!


    期待你的反饋與分享! 🌟

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/web/75948.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/web/75948.shtml
    英文地址,請注明出處:http://en.pswp.cn/web/75948.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    利用純JS開發瀏覽器小窗口移動廣告小功能

    效果展示 直接上代碼 如果要用到vue項目里面&#xff0c;直接按照vue的寫法改動就行&#xff0c;一般沒有多大的問題&#xff0c;頂部的占位是我項目需求&#xff0c;你可以按照要求改動。 <!DOCTYPE html> <html> <head><meta charset"utf-8"…

    React 更新 state 中的數組

    更新 state 中的數組 數組是另外一種可以存儲在 state 中的 JavaScript 對象&#xff0c;它雖然是可變的&#xff0c;但是卻應該被視為不可變。同對象一樣&#xff0c;當你想要更新存儲于 state 中的數組時&#xff0c;你需要創建一個新的數組&#xff08;或者創建一份已有數組…

    java -jar與java -cp的區別

    java -jar與java -cp 1、情景描述2、情景分析3、兩者區別 通常情況下&#xff0c;我們會看到以下兩種命令啟動的Java程序&#xff1a; java -jar xxx.jar [args] java -cp xxx.jar mainclass [args]這兩種用法有什么區別呢&#xff1f; 1、情景描述 1&#xff09;Java打包單個…

    【Java】面向對象程序三板斧——如何優雅設計包、封裝數據與優化代碼塊?

    &#x1f381;個人主頁&#xff1a;User_芊芊君子 &#x1f389;歡迎大家點贊&#x1f44d;評論&#x1f4dd;收藏?文章 &#x1f50d;系列專欄&#xff1a;【Java】內容概括 【前言】 在Java編程中&#xff0c;類和對象是面向對象編程的核心概念。而包&#xff08;Package&am…

    玩轉Docker | 使用Docker搭建Blog微博系統

    玩轉Docker | 使用Docker搭建Blog微博系統 前言一、Blog介紹項目簡介主要特點二、系統要求環境要求環境檢查Docker版本檢查檢查操作系統版本三、部署Blog服務下載鏡像創建容器檢查容器狀態設置權限檢查服務端口安全設置四、訪問Blog系統訪問Blog首頁登錄Blog五、總結前言 在數字…

    用Java NIO模擬HTTPS

    HTTPS流程 名詞解釋&#xff1a; R1:隨機數1 R2:隨機數2 R3:隨機數3 publicKey:公鑰 privateKey:私鑰 要提供https服務&#xff0c;服務端需要安裝數字證書&#xff0c;在&#xff08;TCP建立連接之后&#xff09;TLS握手時發給客戶端&#xff0c;客戶端驗證證書&#x…

    樹莓派_利用Ubuntu搭建gitlab

    樹莓派_利用Ubuntu搭建gitlab 一、給樹莓派3A搭建基本系統 1、下載系統鏡像 https://cdimage.ubuntu.com/ubuntu/releases/18.04/release/ 2、準備系統SD卡 二、給樹莓派設備聯網 1、串口后臺登錄 使用串口登錄后臺是最便捷的&#xff0c;因為前期網絡可能不好直接成功 默…

    Hook_Unfinished

    #include <windows.h>// 假設這兩個函數是存在的 void DoRD() {} void 改堆棧cal1() {} void 改回堆棧cal1() {}__declspec(naked) void HOOKcall() {__asm{pushadnop}__asm{popadmov eax, dword ptr [esi 8]sub eax, ecxretn} }int main() {// 第一個 Hook 操作DWORD H…

    數據結構(六)——紅黑樹及模擬實現

    目錄 前言 紅黑樹的概念及性質 紅黑樹的效率 紅黑樹的結構 紅黑樹的插入 變色不旋轉 單旋變色 雙旋變色 插入代碼如下所示&#xff1a; 紅黑樹的查找 紅黑樹的驗證 紅黑樹代碼如下所示&#xff1a; 小結 前言 在前面的文章我們介紹了AVL這一棵完全二叉搜索樹&…

    c# 數據結構 鏈表篇 有關雙向鏈表的一切

    本人能力有限,如有不足還請斧正 目錄 0.雙向鏈表的好處 1.雙向鏈表的分類 2.不帶頭節點的標準雙向鏈表 節點類:有頭有尾 鏈表類:也可以有頭有尾 也可以只有頭 增 頭插 尾插 刪 查 改 遍歷 全部代碼 3.循環雙向鏈表 節點類 鏈表類 增 頭插 尾插 刪 查 遍歷…

    Numba 從零基礎到實戰:解鎖 Python 性能新境界

    Numba 從零基礎到實戰&#xff1a;解鎖 Python 性能新境界 一、引言 在 Python 的世界里&#xff0c;性能一直是一個備受關注的話題。Python 以其簡潔易讀的語法和豐富的庫生態&#xff0c;深受開發者喜愛&#xff0c;但在處理一些計算密集型任務時&#xff0c;其執行速度往往…

    單位門戶網站被攻擊后的安全防護策略

    政府網站安全現狀與挑戰 近年來&#xff0c;隨著數字化進程的加速&#xff0c;政府門戶網站已成為政務公開和服務公眾的重要窗口。然而&#xff0c;網絡安全形勢卻日益嚴峻。國家互聯網應急中心的數據顯示&#xff0c;政府網站已成為黑客攻擊的重點目標&#xff0c;被篡改和被…

    Spring Boot 項目三種打印日志的方法詳解。Logger,log,logger 解讀。

    目錄 一. 打印日志的常見三種方法&#xff1f; 1.1 手動創建 Logger 對象&#xff08;基于SLF4J API&#xff09; 1.2 使用 Lombok 插件的 Slf4j 注解 1.3 使用 Spring 的 Log 接口&#xff08;使用頻率較低&#xff09; 二. 常見的 Logger&#xff0c;logger&#xff0c;…

    NI的LABVIEW工具安裝及卸載步驟說明

    一.介紹 最近接到個轉交的項目&#xff0c;項目主要作為上位機工具開發&#xff0c;在對接下位機時&#xff0c;有用到NI的labview工具。labview軟件是由美國國家儀器&#xff08;NI&#xff09;公司研制開發的一種程序開發環境&#xff0c;主要用于汽車測試、數據采集、芯片測…

    cmd 終端輸出亂碼問題 |Visual Studio 控制臺輸出中文亂碼解決

    在網上下載&#xff0c;或者移植別人的代碼到自己的電腦&#xff0c;使用VS運行后&#xff0c;控制臺輸出中文可能出現亂碼。這是因為源代碼的編碼格式和控制臺的編碼格式不一致。 文章目錄 查看源代碼文件編碼格式查看輸出控制臺編碼格式修改編碼格式修改終端代碼頁 補充總結 …

    A009-基于pytest的網易云自動化測試

    題 目 :基于pytest的網易云自動化測試 主要內容 綜合應用所學的軟件測試理論和方法,實現網易云的功能自動化測試。 (1)自動化測試介紹; (2)自動化功能測試框架介紹; (3)設計功能測試用例 (4)書寫自動化測試腳本; (5)測試評價與結論。 任務要求 (1)能…

    LVGL Video控件和Radiobtn控件詳解

    LVGL Video控件和Radiobtn控件詳解 一、 Video控件詳解1. 概述2. 創建和初始化3. 基本屬性設置4. 視頻控制5. 回調函數6. 高級功能7. 注意事項 二、Radiobtn控件詳解1. 概述2. 創建和初始化3. 屬性設置4. 狀態控制5. 組管理6. 事件處理7. 樣式設置8. 注意事項 三、效果展示四、…

    AbortController:讓異步操作隨時說停就停

    AbortController&#xff1a;讓異步操作隨時說停就停 一、什么是 AbortController&#xff1f; AbortController 是 JavaScript 在瀏覽器和部分 Node.js 環境中提供的全局類&#xff0c;用來中止正在進行或待完成的異步操作&#xff08;如 fetch() 請求、事件監聽、可寫流、數…

    機器學習 從入門到精通 day_04

    1. 決策樹-分類 1.1 概念 1. 決策節點 通過條件判斷而進行分支選擇的節點。如&#xff1a;將某個樣本中的屬性值(特征值)與決策節點上的值進行比較&#xff0c;從而判斷它的流向。 2. 葉子節點 沒有子節點的節點&#xff0c;表示最終的決策結果。 3. 決策樹的…

    C++ Primer (第五版)-第十三章 拷貝控制

    文章目錄 概述13.1拷貝、賦值與銷毀合成拷貝構造函數拷貝初始化參數和返回值拷貝初始化的限制編譯器可以繞過拷貝構造函數拷貝運算符析構函數三/五原則使用default阻止拷貝合成的拷貝控制成員可能是刪除的 private拷貝控制拷貝控制和資源管理行為像值的類類值拷貝賦值運算符定義…