ホームページ >Java >&#&チュートリアル >1週間でMyBatisのソースコードを学習した後、10,000ワードの要約を入手しました

1週間でMyBatisのソースコードを学習した後、10,000ワードの要約を入手しました

Java后端技术全栈
Java后端技术全栈転載
2023-08-23 14:51:141277ブラウズ

ご存知のとおり、MyBatisJDBC をカプセル化した製品です。 、MyBatis のソース コードについて話す前に、まず JDBC を理解する必要があります。

JDCB

JDBC ケース:

public class JdbcDemo {
    public static final String URL = "jdbc:mysql://localhost:3306/mblog";
    public static final String USER = "root";
    public static final String PASSWORD = "123456";

    public static void main(String[] args) throws Exception { 
        Class.forName("com.mysql.jdbc.Driver"); 
        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); 
        Statement stmt = conn.createStatement(); 
        ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM m_user where id =1"); 
        while(rs.next()){
            System.out.println("name: "+rs.getString("name")+" 年龄:"+rs.getInt("age"));
        }
    }
}

説明:

データベースドライバー:

Class.forName("com.mysql.jdbc.Driver");

接続の取得:

Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);

Statement または PreparedStatement オブジェクトの作成:

Statement stmt = conn.createStatement();

执行sql数据库查询:

ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM m_user where id =1");

解析结果集:

System.out.println("name: "+rs.getString("name")+" 年龄:"+rs.getInt("age"));

在使用的时候,业务处理完成后记得关闭相关资源

使用过JDCB的朋友都知道,JDBC如果用到我们项目中基本上都会存在以下几个问题:

传统JDBC的问题

  • 创建数据库的连接存在大量的硬编码,
  • 执行statement时存在硬编码.
  • 频繁的开启和关闭数据库连接,会严重影响数据库的性能,浪费数据库的资源.
  • 存在大量的重复性编码

针对上面这些问题,于是一大堆持久化框架应运而生。

持久化框

做持久层的框架有很多,有orm系和utils系列。

  • orm シリーズの代表的なものには、hibernateeclipseLinktopLink;
    # があります。
  • ##utils シリーズの代表的なものには、MyBatisdbUtilsjdbcTemplate などが含まれます。
  • #これらのフレームワークの概要を以下に示します。

jpa に関しては、特定のフレームワークではなく仕様標準にすぎず、spring-data と同等ではありません。 -jpa; 同時に、 spring-data-jpa もこれは jpa の特定の実装ではなく、jpa 仕様標準をさらにカプセル化したものにすぎません。 Hibernate は jpa の最も一般的な実装フレームワークであり、もちろん他には eclipseLink や topLink などがあります。

MyBatis の特徴は、SQL を最適化する際に、複雑な SQL の最適化を高度に制御できることと、フレームワークの内部呼び出しレベルがシンプルであること、コードの一部を自動生成できることに加え、自分でコーディングする必要がある SQL も多数あります。 spring-data-jpa (hibernate) の特徴は、開発過程において SQL コーディングを行わずに開発されることですが、もちろんクエリ用のローカル SQL にも対応しており、フレームワークの内部呼び出しレベルが複雑です。 以上を踏まえ、実際の業務進捗や業務支援に応じて選択していただけます。

実際には、1 つのプロジェクトで MyBatis と spring-data-jpa を同時にサポートできます。複雑な SQL には mybatis を使用し、一般的な SQL には spring-data-jpa を使用します。

実際の開発での使用数を考慮して、分析対象として
MyBatis

を選択しました。 <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;border-bottom: 2px solid rgb(239, 112, 96);font-size: 1.3em;"> <span style="display: none;"></span><span style="display: inline-block;background: rgb(239, 112, 96);color: rgb(255, 255, 255);padding: 3px 10px 1px;border-top-right-radius: 3px;border-top-left-radius: 3px;margin-right: 3px;">mybatis</span><span style="display: inline-block;vertical-align: bottom;border-bottom: 36px solid #efebe9;border-right: 20px solid transparent;"> </span> </h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;"> 開発に不慣れな友人は、MyBatis の前身について知らないかもしれません。2010 年以前は、# 支払いません。 # #MyBatis<code style='font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);'>、ibatis と呼ばれます。

MyBatis は、カスタマイズされた SQL、ストアド プロシージャ、高度なマッピングをサポートする優れた永続層フレームワークです。 MyBatis は、ほとんどすべての JDBC コード、パラメータの手動設定、結果セットの取得を回避します。 MyBatis 単純な XML または注釈を使用して、ネイティブ情報を構成およびマッピングし、インターフェースおよび Java の POJOs (Plain Ordinary Java Object、通常の Java オブジェクト) をデータベース内のレコードにマッピングできます。

特点

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:MyBatis 不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql。

案例

需要来源两个jar包:MyBatis的jar包和MySQL数据库连接jar包。

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.16</version>
</dependency>

创建一个表t_user(数据库也是肯定要自己创建的哈)

 CREATE TABLE `t_user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入一条数据:

INSERT INTO `t_user` VALUES (&#39;1&#39;, &#39;tian&#39;, &#39;19&#39;, &#39;1&#39;);

创建该数据库表的实体类:

public class User {
    private Integer id;
    private String name;
    private Integer age;
    //set get
}

创建mapper配置文件:UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tian.mapper.UserMapper">
    <select id="selectUserById" resultType="com.tian.domain.User">
        select * from t_user where id = #{id}
    </select>
</mapper>

创建mapper接口:UserMapper.java

import com.tian.domain.User;

public interface UserMapper {
    User selectUserById(Integer id);
}

MyBatis 整体配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mblog?useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

上面这些就是我们使用MyBatis基本开发代码。

下面我们来写一个测试类:

import com.tian.domain.User;
import com.tian.mapper.UserMapper;
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 java.io.IOException;
import java.io.InputStream;

public class MybatisApplication {

    public static void main(String[] args) {
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        SqlSession sqlSession =null;
        try {
            //读取配置文件
            inputStream = Resources.getResourceAsStream(resource);
            //创建SqlSession工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //创建sql操作会话
            sqlSession = sqlSessionFactory.openSession();
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
            //获取数据并解析成User对象
            User user = userMapper.selectUserById(1);
            //输出
            System.out.println(user);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //关闭相关资源
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            sqlSession.close();
        }
    }

}

测试结果:

User{id=1, name='tian', age=19}

如上面的代码所示,SqlSession是MyBatis中提供的与数据库交互的接口,SqlSession实例通过工厂模式创建。

为了创建SqlSession对象,首先需要创建SqlSessionFactory对象,而SqlSessionFactory对象的创建依赖于SqlSessionFactoryBuilder类,该类提供了一系列重载的build()方法,我们需要以主配置文件的输入流作为参数调用SqlSessionFactoryBuilder对象的bulid()方法,该方法返回一个SqlSessionFactory对象。

SqlSessionFactory オブジェクトを取得したら、SqlSessionFactory オブジェクトの openSession() メソッドを呼び出して、接続を確立する SqlSession## を取得します。データベース #インスタンス。

UserMapper

インターフェイスを前に定義しました。ここでは、SqlSessiongetMapper() メソッドを呼び出して動的プロキシ オブジェクトを作成する必要があります。 UserMapperプロキシ インスタンスのメソッドを呼び出して、データベースとの対話を完了できます。 上記のケースについて、

MyBatis

の全体的な実行プロセスとコア コンポーネントを整理してみましょう。

#MyBatis コア コンポーネント

#MyBatis 実行プロセス


Configuration

は、MyBatis の主な構成情報を記述するために使用されます。 、その他 コンポーネントが構成情報を取得する必要がある場合、Configuration オブジェクトを通じて直接取得できます。さらに、MyBatis は、アプリケーションの起動時に、Mapper 構成情報、タイプ エイリアス、TypeHandler などを Configuration コンポーネントに登録します。他のコンポーネントがこの情報を必要とする場合、次のサイトからダウンロードすることもできます。 Configuration オブジェクトから取得されます。

MappedStatement

MappedStatement は、Mapper XML## への参照である Mapper 内の SQL 構成情報を記述するために使用されます。 # 構成ファイル

SqlSession

SqlSession は、MyBatis が提供するユーザー指向の API であり、対話する際のセッション オブジェクトを表します。データベース。データベースの追加、削除、変更、およびクエリ機能を完了するために使用されます。 SqlSession は Executor コンポーネントの外観であり、わかりやすく使いやすいデータベース操作インターフェイスを外部に提供することを目的としています。

Executor

Executor は、MyBatis の SQL エグゼキュータです。MyBatis のデータベースに対するすべての追加、削除、変更、クエリ操作を実行します。 Executor によって実行されます。 コンポーネントは完成します。

StatementHandler

StatementHandlerは、Statement などの JDBC Statement オブジェクトに対する操作をカプセル化します。パラメータを設定し、Statement インターフェイスによって提供されるメソッドを呼び出してデータベースと対話します。

ParameterHandler

MyBatis フレームワークで使用されるステートメント タイプが CallableStatement および # の場合## PreparedStatement が使用される場合、ParameterHandler は Statement オブジェクトのパラメーター プレースホルダーの値を設定するために使用されます。

ResultSetHandler

ResultSetHandlerSQL 型 SELECT ステートメントの実行時に、JDBC での ResultSet オブジェクトの操作をカプセル化します。 ResultSetHandler は、クエリ結果を Java オブジェクトに変換するために使用されます。

TypeHandler

TypeHandler は MyBatis の型プロセッサであり、Java 型と JDBC 型の間のマッピングを処理するために使用されます。その機能は主に、Java タイプに応じて setXXX() オブジェクトに対応する PreparedStatement または CallableStatement メソッドを呼び出す機能に反映されており、 Javaの型に応じたStatementオブジェクトの値 ResultSetオブジェクトに対応するgetXXX()を呼び出してSQLの実行結果を取得します。

JDBC API を使用してアプリケーションを開発する場合、より面倒な点の 1 つは、JDBC 型と Java 型の間の変換の処理です。 Java 型と JDBC 型の変換に関係する 2 つの状況は次のとおりです。

  • PreparedStatementオブジェクトがパラメーター プレースホルダーの値を設定するときは、PreparedStatement# で提供される一連の setXXX()## を呼び出す必要があります。 ## インターフェース #メソッド、Java 型を対応する JDBC 型に変換し、値をパラメーター プレースホルダーに割り当てます。
  • SQL ステートメントを実行して
  • ResultSet
    オブジェクトを取得した後、ResultSet オブジェクトの getXXX() メソッドを呼び出して取得する必要があります。フィールドの値 このとき、JDBC 型を Java 型に変換します。
MyBatis

は、TypeHandler と、Java 型と JDBC 型の間の対応する関係を提供します:

1週間でMyBatisのソースコードを学習した後、10,000ワードの要約を入手しました

概要ユーザーレベルの API である

SqlSession

コンポーネントを使用しました。実際、SqlSession は、より使いやすいデータベース操作インターフェイスをユーザーに提供することを目的とした Executor コンポーネントの外観であり、デザイン パターンにおける外観パターンの典型的な適用例です。 実際に SQL 操作を実行するのは Executor コンポーネントです。Executor は SQL エグゼキュータとして理解できます。

StatementHandler

コンポーネントを使用して JDBC Statement オブジェクトを操作します。 <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 1px;margin-bottom: 1px;">ステートメント タイプが <code style='font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);'>CallableStatement および PreparedStatement の場合、パラメーター プレースホルダーには、ParameterHandler コンポーネントを通じて値が割り当てられます。 ParameterHandler コンポーネントは、Java 型に基づいて、対応する TypeHandler オブジェクトを見つけます。TypeHandler は、Statement# によって提供される setXXX() メソッドを使用します。 ## オブジェクト (たとえば、setString() メソッド) は、Statement オブジェクトのパラメーター プレースホルダーの値を設定します。

StatementHandlerコンポーネントが JDBC で Statement オブジェクトを使用してデータベースとの対話を完了した後、SQL ステートメントのタイプが SELECT の場合、MyBatis は ## を通じて Statement オブジェクトから ResultSet を取得します。 #ResultSetHandler コンポーネント.オブジェクトを作成し、ResultSet オブジェクトを Java オブジェクトに変換します。

#高度なスキル ##デザイン パターン

# デザイン パターンは MyBatis で広く使用されています。MyBatis では、いくつかのデザイン パターンを学ぶことができます:
  • #ファクトリ パターン
  • テンプレート メソッド パターン
  • エージェント パターン
  • ビルダー パターン
  • シングルトン パターン
  • アダプテーション パターン
  • デコレータ パターン
  • 責任連鎖モデル
  • ....

キャッシュ

Web アプリケーションでは、キャッシュは不可欠なコンポーネントです。通常、Redis や memcached などのキャッシュ ミドルウェアを使用して、データベースへの大量のリクエストをインターセプトし、データベースへの負荷を軽減します。重要なコンポーネントとして、MyBatis は当然、内部で対応するサポートも提供します。フレームワークレベルでキャッシュ機能を追加することで、データベースへの負担軽減とクエリ速度の向上を同時に実現でき、一石二鳥と言えます。

MyBatis キャッシュ構造は、

レベル 1 キャッシュ第 2 レベル キャッシュで構成されており、どちらのレベルのキャッシュも Cache インターフェイスを使用した実装クラスです。したがって、次の章では、最初にいくつかのキャッシュ実装クラスのソース コードを紹介し、次に 1 レベル キャッシュと 2 レベル キャッシュの実装を分析します。

MyBatis の 1 次キャッシュと 2 次キャッシュの使用: MyBatis の 1 次キャッシュは SqlSession レベルのキャッシュです。デフォルトで有効になっており、オフにすることはできません。2 次キャッシュはオフにする必要があります。 MyBatis メイン設定ファイルで、cacheEnabled パラメータの値を有効に設定することで設定できます。

一次キャッシュは Executor に実装されています。 MyBatis の Executor コンポーネントには、SimpleExecutorReuseExecutor、および BatchExecutor という 3 つの異なる実装があります。これらのクラスはすべて BaseExecutor から継承されます。BaseExecutor クラスの query() メソッドでは、クエリ結果が最初にキャッシュから取得されます。そうでない場合は、結果がデータベースから取得され、次にクエリ結果が取得されます。キャッシュされます。 MyBatis の第 2 レベル キャッシュは、デコレータ モードを通じて実装されます。第 2 レベル キャッシュが、cacheEnabled パラメータを通じて有効になっている場合、MyBatis フレームワークは CachingExecutor を使用して、SimpleExecutorReuseExecutor、または BatchExecutor は装飾されており、クエリ操作が実行されるとクエリ結果がキャッシュされ、更新操作が実行されると 2 次キャッシュが更新されます。この章では最後に、MyBatis が Redis を二次キャッシュとして統合する方法を紹介します。

さらに、MyBatis は EhcacheOSCache などもサポートしています。この機能は一般的には使用されません。

プラグイン

ほとんどのフレームワークはプラグインをサポートしています。ユーザーはプラグインを作成することで機能を拡張できます。Mybatis も例外ではありません。 。

MyBatis は、Mapper 実行時の SQL の実行動作を変更できる拡張メカニズムを提供します。この拡張メカニズムはインターセプターを通じて実装され、ユーザー定義のインターセプターは MyBatis プラグインとも呼ばれます。

MyBatis フレームワークは、4 つのコンポーネントのメソッドのインターセプトをサポートしています: ExecutorParameterHandlerResultSetHandlerStatementHandler。 MyBatis プラグインの実装原理を理解した上で、ページングクエリプラグインや低速 SQL 統計プラグインを実装し、必要な機能が MyBatis フレームワークで満たせない場合は、カスタムプラグインによる実装を検討できます。 -ins。

古典的な実装: PageHelper。

Log

MyBatis は、さまざまなログ フレームワークに対応する Log インターフェイスの実装を提供します。Log インターフェイスの実装クラスは次のとおりです。以下の図に示します。実装クラスからわかるように、MyBatis は以下に詳述する 7 つの異なるログ実装をサポートしています。

1週間でMyBatisのソースコードを学習した後、10,000ワードの要約を入手しました

一般的に使用されるものの簡単な説明:

  • Apache Commons Logging: の使用JCL 出力ログ。
  • Log4j 2: Log4j 2 フレームワークを使用してログを入力します。
  • Java Util Logging: JDK の組み込みログ モジュールを使用してログを出力します。
  • Log4j: Log4j フレームワークを使用してログを出力します。
  • #No Logging: ログは出力されません。
  • SLF4J: SLF4J ログ ファサードを使用してログを出力します。
  • Stdout: 標準出力デバイス (コンソールなど) にログを出力します。
MyBatis がログ フレームを検索する順序は、

SLF4J→JCL→Log4j2→Log4j→JUL→No Logging です。

クラスパスにログ フレームワークがない場合は、NoLoggingImpl ログ実装クラスを使用します。つまり、ログは出力されません。

動的 SQL バインディング

動的 SQL は、事前に予測できず、特定の条件に従って動的に生成する必要がある特定の条件を指します。実行時の状況 SQL ステートメントを生成します。

MyBatis には、196185dae55b7edbe154a5051db664a7f3bf5eff46860b27119c8dd4e92f1e5712b5ce0aa393f59b99f5b03a231c8f67 など。

MyBatis ソース コードには、MappedStatement オブジェクトのプロパティとして MappedStatement オブジェクトに保存される SqlSource オブジェクトがあります。 Mapperが実行されると、入力されたパラメータ情報を元にSqlSourceオブジェクトのgetBoundSql()メソッドが呼び出され、BoundSqlオブジェクトが取得され、SqlNodeオブジェクトをSQL文に変換する処理が完了します。

例: #{}プレースホルダーは「?」に置き換えられ、JDBC の PreparedStatement オブジェクトの setXXX() メソッドが呼び出されて、パラメータ プレースホルダ、および $ {} プレースホルダは、渡されたパラメータ テキストの内容に直接置き換えられます。

概要

この記事は、MyBatis ソース コード分析の全体的な経験をまとめたものです。あなたを助けてください。

以上が1週間でMyBatisのソースコードを学習した後、10,000ワードの要約を入手しましたの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はJava后端技术全栈で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。