ご存知のとおり、MyBatis
は JDBC
をカプセル化した製品です。 、MyBatis のソース コードについて話す前に、まず JDBC
を理解する必要があります。
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如果用到我们项目中基本上都会存在以下几个问题:
针对上面这些问题,于是一大堆持久化框架应运而生。
做持久层的框架有很多,有orm
系和utils
系列。
orm
シリーズの代表的なものには、hibernate
、eclipseLink
、topLink
; シリーズの代表的なものには、
MyBatis、
dbUtils、
jdbcTemplate などが含まれます。
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包: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 ('1', 'tian', '19', '1');
创建该数据库表的实体类:
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&characterEncoding=utf8&autoReconnect=true&useSSL=false&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## を取得します。データベース #インスタンス。
インターフェイスを前に定義しました。ここでは、SqlSession
の getMapper()
メソッドを呼び出して動的プロキシ オブジェクトを作成する必要があります。 UserMapper
プロキシ インスタンスのメソッドを呼び出して、データベースとの対話を完了できます。 上記のケースについて、
の全体的な実行プロセスとコア コンポーネントを整理してみましょう。
は、MyBatis
の主な構成情報を記述するために使用されます。 、その他 コンポーネントが構成情報を取得する必要がある場合、Configuration
オブジェクトを通じて直接取得できます。さらに、MyBatis は、アプリケーションの起動時に、Mapper 構成情報、タイプ エイリアス、TypeHandler
などを Configuration
コンポーネントに登録します。他のコンポーネントがこの情報を必要とする場合、次のサイトからダウンロードすることもできます。 Configuration
オブジェクトから取得されます。
MappedStatement は、Mapper XML## への参照である Mapper 内の SQL 構成情報を記述するために使用されます。 # 構成ファイル
SqlSession は、MyBatis が提供するユーザー指向の API であり、対話する際のセッション オブジェクトを表します。データベース。データベースの追加、削除、変更、およびクエリ機能を完了するために使用されます。
SqlSession は Executor コンポーネントの外観であり、わかりやすく使いやすいデータベース操作インターフェイスを外部に提供することを目的としています。
Executor
は、MyBatis の SQL エグゼキュータです。MyBatis のデータベースに対するすべての追加、削除、変更、クエリ操作を実行します。 Executor によって実行されます。 コンポーネントは完成します。
StatementHandler
は、Statement などの JDBC Statement
オブジェクトに対する操作をカプセル化します。パラメータを設定し、Statement インターフェイスによって提供されるメソッドを呼び出してデータベースと対話します。
MyBatis
フレームワークで使用されるステートメント タイプが CallableStatement
および # の場合## PreparedStatement が使用される場合、
ParameterHandler は Statement オブジェクトのパラメーター プレースホルダーの値を設定するために使用されます。
ResultSetHandlerSQL 型 SELECT ステートメントの実行時に、JDBC での ResultSet オブジェクトの操作をカプセル化します。 ResultSetHandler は、クエリ結果を Java オブジェクトに変換するために使用されます。
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 型に変換し、値をパラメーター プレースホルダーに割り当てます。
getXXX()
メソッドを呼び出して取得する必要があります。フィールドの値 このとき、JDBC 型を Java 型に変換します。
は、TypeHandler
と、Java 型と JDBC 型の間の対応する関係を提供します:
コンポーネントを使用しました。実際、SqlSession
は、より使いやすいデータベース操作インターフェイスをユーザーに提供することを目的とした Executor コンポーネントの外観であり、デザイン パターンにおける外観パターンの典型的な適用例です。 実際に SQL 操作を実行するのは Executor コンポーネントです。Executor は SQL エグゼキュータとして理解できます。
コンポーネントを使用して 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 オブジェクトに変換します。
レベル 1 キャッシュ と
第 2 レベル キャッシュで構成されており、どちらのレベルのキャッシュも Cache インターフェイスを使用した実装クラスです。したがって、次の章では、最初にいくつかのキャッシュ実装クラスのソース コードを紹介し、次に 1 レベル キャッシュと 2 レベル キャッシュの実装を分析します。
一次キャッシュは Executor に実装されています。 MyBatis の Executor コンポーネントには、SimpleExecutor
、ReuseExecutor
、および BatchExecutor
という 3 つの異なる実装があります。これらのクラスはすべて BaseExecutor
から継承されます。BaseExecutor クラスの query() メソッドでは、クエリ結果が最初にキャッシュから取得されます。そうでない場合は、結果がデータベースから取得され、次にクエリ結果が取得されます。キャッシュされます。 MyBatis の第 2 レベル キャッシュは、デコレータ モードを通じて実装されます。第 2 レベル キャッシュが、cacheEnabled パラメータを通じて有効になっている場合、MyBatis フレームワークは CachingExecutor を使用して、SimpleExecutor
、ReuseExecutor
、または BatchExecutor
は装飾されており、クエリ操作が実行されるとクエリ結果がキャッシュされ、更新操作が実行されると 2 次キャッシュが更新されます。この章では最後に、MyBatis
が Redis を二次キャッシュとして統合する方法を紹介します。
さらに、MyBatis は Ehcache
、OSCache
などもサポートしています。この機能は一般的には使用されません。
ほとんどのフレームワークはプラグインをサポートしています。ユーザーはプラグインを作成することで機能を拡張できます。Mybatis も例外ではありません。 。
MyBatis は、Mapper 実行時の SQL の実行動作を変更できる拡張メカニズムを提供します。この拡張メカニズムはインターセプターを通じて実装され、ユーザー定義のインターセプターは MyBatis プラグインとも呼ばれます。
MyBatis フレームワークは、4 つのコンポーネントのメソッドのインターセプトをサポートしています: Executor
、ParameterHandler
、ResultSetHandler
、StatementHandler
。 MyBatis プラグインの実装原理を理解した上で、ページングクエリプラグインや低速 SQL 統計プラグインを実装し、必要な機能が MyBatis フレームワークで満たせない場合は、カスタムプラグインによる実装を検討できます。 -ins。
古典的な実装: PageHelper。
MyBatis は、さまざまなログ フレームワークに対応する Log インターフェイスの実装を提供します。Log インターフェイスの実装クラスは次のとおりです。以下の図に示します。実装クラスからわかるように、MyBatis は以下に詳述する 7 つの異なるログ実装をサポートしています。
一般的に使用されるものの簡単な説明:
SLF4J→JCL→Log4j2→Log4j→JUL→No Logging です。
クラスパスにログ フレームワークがない場合は、NoLoggingImpl ログ実装クラスを使用します。つまり、ログは出力されません。
動的 SQL は、事前に予測できず、特定の条件に従って動的に生成する必要がある特定の条件を指します。実行時の状況 SQL ステートメントを生成します。
MyBatis には、<where>
、<if>
、<choose|when など、豊富な動的 SQL タグがあります。 |otherwise> ;
、<foreach>
など。
MyBatis ソース コードには、MappedStatement オブジェクトのプロパティとして MappedStatement オブジェクトに保存される SqlSource オブジェクトがあります。 Mapperが実行されると、入力されたパラメータ情報を元にSqlSourceオブジェクトのgetBoundSql()メソッドが呼び出され、BoundSqlオブジェクトが取得され、SqlNodeオブジェクトをSQL文に変換する処理が完了します。
例: #{}
プレースホルダーは「?」に置き換えられ、JDBC の PreparedStatement オブジェクトの setXXX() メソッドが呼び出されて、パラメータ プレースホルダ、および $ {} プレースホルダは、渡されたパラメータ テキストの内容に直接置き換えられます。
この記事は、MyBatis ソース コード分析の全体的な経験をまとめたものです。あなたを助けてください。
以上が1週間でMyBatisのソースコードを学習した後、10,000ワードの要約を入手しましたの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。