【Mybatis入門から実戦までのチュートリアル】 第1章 Mybatis入門

1. Mybatis を始めよう

1.1 MyBatisとは

    MyBatis は、もともと Apache のオープン ソース プロジェクトである iBatis でしたが、2010 年にプロジェクトが Apache Software Foundation から Google Code に移行され、MyBatis に改名されました。2013 年 11 月に Github に移行しました。
    
    iBATIS という言葉は、「インターネット」と Java ベースの永続層フレームワークである「abatis」を組み合わせたものです。iBATIS が提供する永続層フレームワークには、SQL マップとデータ アクセス オブジェクト (DAO) が含まれます。

    ソフトウェア フレームワーク (ソフトウェア フレームワーク) は、通常、特定の業界標準を実装するため、または特定の基本的なタスクを完了するためのソフトウェア コンポーネントの仕様を指し、特定のソフトウェアを実装するために仕様で要求される基本的な機能を提供するソフトウェア製品も指します。コンポーネント仕様。フレームワークは半完成プロジェクトであり、フレームワークに基づいてプロジェクトを開発し、開発効率を向上させることができます。今のインターネット企業は効率を第一に考えており、開発サイクルが長すぎると、類似の製品がすぐに市場に出て、機会を逃してしまいます。
    
    現在、最新バージョンは MyBatis 3.5.9 で、リリース日は 2021 年 12 月 26 日です。
    
    MyBatisは優れた永続化レイヤーフレームワークで、データベースを操作するJDBCのプロセスをカプセル化しているため、開発者はSQL自体に注意を払うだけでよく、ドライバーの登録、接続の作成、ステートメントの作成、パラメーターの手動設定などの処理にエネルギーを費やす必要はありません。 、および結果セット検索などの JDBC 複雑なプロセス コード。
    
    MyBatis は、xml ファイルまたは注釈を介して実行されるさまざまなステートメントを構成し、Java オブジェクトとステートメント内の sql の動的パラメーターとの間のマッピングを通じて、最終的に実行される sql ステートメントを生成します。最後に、mybatis フレームワークは sql を実行し、結果を Java オブジェクトにマップし、戻る。

1.2 MyBatisのメリット

    簡単に学べる: 本体は小さくてシンプルです。サードパーティの依存関係がないため、最も単純なインストールでは、2 つの jar ファイルといくつかの sql マッピング ファイルの構成のみが必要です。学びやすく、使いやすい。ドキュメントとソース コードを通じて、その設計のアイデアと実装を完全に把握できます。

    柔軟性: Mybatis は、アプリケーションまたはデータベースの既存の設計に影響を与えません。SQL は xml で記述されているため、一元管理と最適化に便利です。データベースを操作するためのすべての要件は、SQL ステートメントによって満たすことができます。

    SQL とプログラム コードの分離: DAO レイヤーを提供することで、ビジネス ロジックとデータ アクセス ロジックが分離され、システム設計がより明確になり、保守が容易になり、単体テストが容易になります。SQL とコードの分離により、保守性が向上します。

    マッピング タグを提供し、オブジェクトとデータベース間の ORM フィールド関係マッピングをサポートします。

    オブジェクト・リレーショナルの構築および保守をサポートするために、オブジェクト・リレーショナル・マッピング・タグが提供されています。

    xml タグを提供し、動的 ​​SQL の記述をサポートします。

1.3 JDBC プログラミングの問題点

    実際の開発プロセスでは、通常、Mybatis や Hibernate などの従来の JDBC を置き換えるために ORM フレームワークを使用しますが、JDBC は Java がデータ アクセスを実現するための基盤であるため、それを習得することは、Java のデータ操作プロセスを理解するのに非常に役立ちます。ジャバ。

    ORM: オブジェクト リレーショナル マッピング (ORM) モードは、オブジェクト指向データベースとリレーショナル データベースの間のミスマッチを解決するためのテクノロジです。簡単に言うと、ORM は、オブジェクトとデータベース間のマッピングを記述するメタデータを使用して、プログラム内のオブジェクトをリレーショナル データベースに自動的に永続化します。

    Java の典型的な ORM ミドルウェアには、Hibernate、Mybatis、speedframework などがあります。

    ORM の技術的特徴:
        1. 開発効率の向上。ORM はデータベース内のエンティティ オブジェクトとテーブルの間でフィールドと属性を自動的にマッピングできるため、専用の巨大なデータ アクセス レイヤーは実際には必要ないかもしれません。 

        2. ORM は、SQL で直接コーディングせずにデータベースへのマッピングを提供し、操作オブジェクトのようにデータベースからデータを取得できます。 

    では、実際の開発で従来の JDBC の代わりに ORM フレームワークを使用するのはなぜでしょうか? 次に、JDBC プログラムの単純な実装を見て、次のようにその欠点を分析しましょう。

1.3.1 JDBC プログラム

@Override
public void insertUser(User user) {
    Connection conn = DBUtil.getConnection();
    PreparedStatement stmt = null;
    String sql = "insert into sys_user(NAME,ACCT,PWD,CRTIME,UPTIME) values(?,?,?,now(),now())";
    try {
        stmt = conn.prepareStatement(sql);
        stmt.setString(1, user.getName());
        stmt.setString(2, user.getAcct());
        stmt.setString(3, user.getPwd());
        stmt.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        DBUtil.closeAll(conn, stmt, null);
    }
}

1.3.2 JDBC プログラミング手順

    1. データベース ドライバをロードします。

    2. データベース接続 Connection を作成して取得します。

    3. SQL ステートメントを実行する PreparedStatement オブジェクトを作成します。

    4. SQL ステートメントにプレースホルダ パラメータを設定します。

    5. PreparedStatement を使用して Sql を実行し、結果セットを取得します。

    6. SQL 実行結果を分析および処理します。

    7. リソース (Connection、Preparedstatement、ResultSet) を解放します。

1.3.3 JDBC の問題は次のように要約されます。

以上の手順をまとめると、以下のようになります。

    1.データベース接続は、使用時に作成され、使用されていないときにすぐに解放されるため、データベースが頻繁に操作され、リソースが浪費され、パフォーマンスに影響します; 最適化のアイデア: データベース接続プールを使用してデータベースを管理し
        ますオブジェクト;

    2. sql は Java プログラムにハードコードされています. sql を変更する場合, Java コードを再コンパイルする必要があります. これは後の段階でのシステムのメンテナンスに役立ちません. 最適化のアイデア: xml で sql ステートメントを構成します
        . SQL を変更しても、ソース コードを再コンパイルする必要はありません。

    3. PreparedStatement へのパラメーターの設定も Java プログラムにハードコーディングされているため、後のメンテナンスに役立ちません。
        最適化のアイデア: すべての SQL ステートメント、プレースホルダー、およびパラメーターは xml で構成され、ソース コードを再コンパイルする必要はありません。変更のため;

    4. 結果セットから結果セット データをトラバースする場合、後のシステムのメンテナンスに役立たないハード コーディングもあります;
        最適化のアイデア: クエリ結果セットを Java オブジェクトに自動的にマップします。

    上記の問題に対して、JDBC を最適化するための多くのソリューション、つまり、後に登場した Mybatis や Hibernate などの ORM 永続層フレームワークが自然に登場したため、実際の開発では ORM フレームワークが好まれます。
    
    このコンセプトで、Mybatis について学び始めます...

    注: ハードコーディングとは、外部からデータを取得したり、実行時にデータを生成したりするのではなく、プログラムまたはその他の実行可能オブジェクトのソース コードに直接データを埋め込むソフトウェア開発手法です。通常、ハードコーディングされたデータは、ソース コードを編集して実行可能ファイルを再コンパイルすることによってのみ変更できます。

1.4 MyBatis アーキテクチャ

    1. MyBatis の設定:
        mybatis-config.xml (名前は固定ではありません)、このファイルは、MyBatis のグローバル (コア) 設定ファイルとして使用され、MyBatis の動作環境およびその他の情報を設定します。
        mapper.xml ファイルは Sql マッピング ファイルであり、データベースを操作するための Sql ステートメントがファイル内に構成されます。このファイルは mybatis-config.xml にロードする必要があります。

    2. MyBatis 環境などの構成情報から、SqlSessionFactory、つまりセッション ファクトリを構築します。

    3. SqlSession はセッション ファクトリ、つまりセッションによって作成され、データベースの操作は SqlSession を通じて実行する必要があります。

    4. MyBatis の最下層は、データベースを操作するための Executor インターフェイスをカスタマイズします. Executor インターフェイスには、基本的な Executor とキャッシュの Executor の 2 つの実装があります。

    5. MappedStatement は、MyBatis の基本的なカプセル化オブジェクトでもあります.Mybatis は、SQL 構成情報を MappedStatement オブジェクト (受信パラメーター マッピング構成、実行された SQL ステートメント、および結果マッピング構成を含む) にロードし、メモリに格納します。mapper.xml ファイル内の Sql は MappedStatement オブジェクトに対応し、Sql の ID は MappedStatement の ID です。

    6. MappedStatement は、HashMap、基本型、文字列型、およびエンティティ クラス型を含む、Sql 実行の入力パラメータを定義します. Executor は、Sql を実行する前に、MappedStatement を介して入力 Java オブジェクトを Sql にマップします. 入力パラメータ マッピングは、JDBC プログラミングです. PreparedStatement は、パラメータを設定します. .

    7. MappedStatement は、HashMap、基本型、文字列型、およびエンティティ クラス型を含む Sql 実行の出力結果を定義します. Executor は、MappedStatement を介して SQL を実行した後、出力結果を Java オブジェクトにマップします. 出力結果のマッピング プロセスは、JDBC プログラミングと同等です.結果を解析するプロセス。

原理分析:

    1. 構成のロード: 構成は 2 つの場所から取得されます。1 つは構成ファイル、もう 1 つは Java コードの注釈であり、SQL 構成情報は各 MappedStatement オブジェクトにロードされます (受信パラメーター マッピング構成と実行された SQL を含む)。 statement 、結果マッピング構成)、メモリに保存されます。

    2. SQL 解析: API インターフェイス層が呼び出し要求を受信すると、着信 SQL の ID と着信オブジェクト (Map、JavaBean、または基本データ型のいずれか) を受け取り、Mybatis は対応する MappedStatement を検索します。次に、受信したパラメーター オブジェクトに従って MappedStatement が解析され、解析後に実行される最終的な SQL ステートメントとパラメーターを取得できます。

    3. SQL の実行: 最終的な SQL とパラメータをデータベースに渡して実行し、データベースの操作結果を取得します。

    4. 結果マッピング: マッピング構成に従ってデータベースを操作した結果を変換します。これは、HashMap、JavaBean、または基本データ型に変換でき、最終結果を返します。

1.5 MyBatis プロジェクトのビルド

1.5.1 Java プロジェクトの作成

    MyBatis は、データベースを操作する際に使用する永続層フレームワークです。JavaWEB プロジェクトを作成する必要はありません。Maven Java プロジェクトを作成するだけです。

1.5.2 MyBatis フレームワーク jar パッケージのインポート

    Mybaits のコードは github.com によって管理されており、ダウンロード アドレス: https://github.com/mybatis/mybatis-3/releases

mybatis ディレクトリ構造:

    lib -> mybatis アクセサリ ツールキット

    ライセンス -> ライセンス

    mybatis-3.4.6.jar -> mybatis コア パッケージ
    
    mybatis-3.4.6.pdf -> mybatis マニュアル

    通知 -> 法的通知

方法 1: jar パッケージをインポートする

    mybatis-3.4.6.jar はコア jar パッケージであり、インポートする必要があります。
    
    lib ディレクトリの jar パッケージはオプションのツールキットです. 通常、mybatis のログ出力コンポーネントとして log4j を導入します.

    mysql または oracle データベースのドライバー パッケージをインポートする必要があります。  

方法 2: Maven 依存関係の構成

<dependencies>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>
    <!-- oracle:大家在引入oracle依赖的时候肯定出错 -->
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0.1.0</version>
    </dependency>
    <!--  mysql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>
    <!-- log4j Mybatis的日志输出组件 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

    Oracle はエラー解決に依存しています: https://blog.csdn.net/qq_38000902/article/details/82759268

    Oracle インストール ディレクトリに ojdbc6.jar があります: D:\Tools\product\11.2.0\dbhome_1\jdbc\lib (私のパス)

    Mybatis はデフォルトで出力ログ情報として log4j を使用しており、log4j 関連ファイルをインポートすることもできます。

1.5.3 グローバル設定ファイルを MyBatis に書き込む

    src/main/resources ディレクトリに mybatis-config.xml を作成し、関数: データ ソース、トランザクションなどの MyBatis の動作環境を構成します。

    注: src/main の下にリソース ディレクトリがない場合は、手動で作成してリソース ルートにします。

<?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 文件的根节点 -->
<configuration>
    <!--
      properties 用于引入外部的properties配置文件
      resource:引入类路径下的文件
      url:引入磁盘或网路
     -->
    <properties/>

    <!-- environments:多个配置环境;通过default属性可以对多个环境快速切换 -->
    <!-- environments default属性的值必须和某个environment的id值一致 -->
    <!-- 和spring整合后 environments配置将废除,了解即可 -->
    <environments default="mysql">
        <environment id="oracle">
            <!-- 配置事务:使用jdbc的事务管理 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源:连接数据库的信息
                type: 表示连接是否使用连接池,POOLED表示mybatis中自带的连接池
    JNDI、POOLED、UNPOOLED
             -->
            <dataSource type="POOLED">
                <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
                <property name="username" value="scott"/>
                <property name="password" value="tiger"/>
            </dataSource>
        </environment>
        <environment id="mysql">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?characterEncoding=utf8&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

MyBatis 構成ファイルが次のエラーを報告します。

    DTD 制約を導入するために xml 構成ファイルを作成するときに、URI が登録されていないことを示すこのエラーが表示される場合があります (設定 | 言語とフレームワーク | スキーマと DTD)。このとき、ショートカット キーを使用して外部リソースの取得または外部リソース オプションを無視します。

    または、問題のあるパスを設定 -> 言語とフレームワーク -> スキーマと dtds に直接追加します。

1.5.4 データベース SQL

CREATE TABLE `dept`  (
  `deptno` int PRIMARY KEY AUTO_INCREMENT,
  `dname` varchar(20),
  `loc` varchar(40)
);

INSERT INTO `dept` VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO `dept` VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO `dept` VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO `dept` VALUES (40, 'OPERATIONS', 'BOSTON');

CREATE TABLE `emp`  (
  `empno` int PRIMARY KEY AUTO_INCREMENT,
  `ename` varchar(20),
  `job` varchar(20),
  `mgr` int,
  `hiredate` date,
  `sal` double,
  `comm` double,
  `deptno` int,
  CONSTRAINT `FK_EMP_DEPTNO` FOREIGN KEY (`deptno`) REFERENCES `dept` (`deptno`)
);

INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 1300, NULL, 20);
INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 2100, 300, 30);
INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1750, 500, 30);
INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 3475, NULL, 20);
INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1750, 1400, 30);
INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 3350, NULL, 30);
INSERT INTO `emp` VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2950, NULL, 10);
INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3500, NULL, 20);
INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5500, NULL, 10);
INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 2000, 0, 30);
INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1600, NULL, 20);
INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '0198-12-31', 1450, NULL, 30);
INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3500, NULL, 20);
INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1800, NULL, 10);

1.5.5 エンティティークラスの作成

    エンティティ クラスは SQL マッピング用の Mybatis として使用されます. エンティティ クラスは通常データベース テーブルに対応します. Emp.java は次のとおりです:

    注: エンティティ クラスはデータベース テーブルに対応するために使用されます。すべての参照型を使用することをお勧めします。

package com.newcapec.entity;

import java.util.Date;

public class Emp {

    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public Double getComm() {
        return comm;
    }

    public void setComm(Double comm) {
        this.comm = comm;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    @Override
    public String toString() {
        return "Emp{" +
            "empno=" + empno +
            ", ename='" + ename + '\'' +
            ", job='" + job + '\'' +
            ", mgr=" + mgr +
            ", hiredate=" + hiredate +
            ", sal=" + sal +
            ", comm=" + comm +
            ", deptno=" + deptno +
            '}';
    }
}

1.5.6 マッピングファイルの書き込み

    src/main/resources の下にマッパー ディレクトリを作成し、このディレクトリに SQL マッピング ファイル Emp.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">
<!--
    namespace: 命名空间,作用是mapper文件进行分类管理,用于隔离sql语句。
    注意:如果使用mapper代理的方式进行开发,namespace有特殊的作用。
-->
<mapper namespace="emp">
    <!-- 在映射文件中编写sql语句 -->
    <!-- 通过员工编号查询员工信息 -->
    <!--
        通过<select>标签编写查询语句
        id: 映射文件中SQL语句的唯一标识
             mybatis会将SQL语句封装到MappedStatement对象中,所以此处的id也可以标识MappedStatement对象的id
             注意:同一个mapper文件中id不能重复,而且id在mapper代理模式下有着重要作用
        parameterType: 输入参数的类型
            sql语句的占位符:#{}
            #{empno}:其中empno表示接收输入的参数值,参数名称为empno
			但是如果参数的类型为简单类型(基本数据类型、包装类、字符串类型),参数名称可以任意指定
		resultType: 输出参数的类型
			需要指定输出数据为Java中的数据类型(实体类的全限定名)
    -->
    <select id="selectById" parameterType="java.lang.Integer" resultType="com.newcapec.entity.Emp">
        select empno,ename,job,hiredate,mgr,sal,comm,deptno from emp where empno=#{empno}
    </select>
</mapper>

1.5.7 マッピングファイルのロード

    MyBatis のグローバル設定ファイルにマッピング ファイルの場所を追加します。

<!-- 加载映射文件的位置 -->
<mappers>
    <mapper resource="mapper/Emp.xml"/>
</mappers>

1.5.8 log4j 構成

    Mybatis ログ出力: log4j.properties 構成ファイル。

#井号表示注释,配置内容为键值对格式,每行只能有一个键值对,键值对之间以=连接
#指定logger
#设定log4j的日志级别和输出的目的地
#INFO日志级别 ,Console和logfile输出的目的地
#等级 OFF,ERROR,WARN,INFO,DEBUG,TRACE,ALL
log4j.rootLogger=DEBUG,Console

#指定appender
#设定Logger的Console,其中Console为自定义名称,类型为控制台输出
log4j.appender.Console=org.apache.log4j.ConsoleAppender

#设定Logger的logfile,其中logfile为自定义名称,类型为文件
#org.apache.log4j.FileAppender文件
#org.apache.log4j.RollingFileAppender文件大小到达指定尺寸后产生一个新的文件
#org.apache.log4j.DailyRollingFileAppender每天产生一个日志文件
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
#设定文件的输出路径
log4j.appender.logfile.File=d:/log/test.log
#设定文件最大尺寸  单位可以使KB,MB,GB
log4j.appender.logfile.MaxFileSize=2048KB

#输出格式
#设定appender布局Layout
#   %d 输出日志的日期和时间,指定格式:%d{yyyy-MM-dd HH:mm:ss SSS}
#   %p 输出的日志级别
#   %c 输出所属类的全类名
#   %M 方法名
#   %m 输出代码中指定消息
#   %n 一个换行符
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d %p %c.%M() --%m%n
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p %c.%M() --%m%n

1.5.9 テストプログラムの作成

    Junit 単体テストを使用することをお勧めします。

package com.newcapec;

import com.newcapec.entity.Emp;
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.Test;

import java.io.IOException;
import java.io.InputStream;

/**
 * 测试程序
 */
public class MybatisTest {

    @Test
    public void test() throws IOException {
        //1.创建读取全局配置文件的流
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

        //2.通过配置文件流创建会话工厂
        SqlSessionFactory factory = builder.build(in);

        //3.通过会话工厂创建会话对象(SqlSession)
        SqlSession session = factory.openSession();

        //4.通过会话对象操作数据
        /**
         * 查询单条记录
         * selectOne(String statementId, Object param)
         * 参数1:映射文件中的statementId,命名空间名.statementId
         * 参数2:向sql语句中传入的数据,注意:传入的数据类型必须与映射文件中配置的parameterType保持一致
         * 返回值:就是映射文件中配置的resultType的类型
         * 查询多条记录
         * selectList()
         */
        Emp emp = session.selectOne("emp.selectById", 7369);
        System.out.println(emp);
        //5.关闭资源
        session.close();
    }
}

1.6 追加・削除・修正・確認の基本操作

    次の機能を実現する:
        すべての従業員情報を照会する

        スタッフを追加

        スタッフの更新

        従業員を削除

        従業員名に基づくあいまいクエリ

1.6.1 クエリ操作

マッパーファイル:

<!--
	查询到数据返回多条记录,每一条封装在一个实体类对象中,所有的实体类对象封装在List集合中
	resultType:指定的并不是集合的类型,而是单条数据所对应实体类类型
	resultType="java.util.List" 错误的配置方式
-->
<select id="select" resultType="com.newcapec.entity.Emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno desc
</select>

Java コード:

public class CURDTest {

    @Test
    public void testSelect() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();

        /**
         * 查询多条记录
         * selectList(statement-sql语句的id, parameter-参数)
         * 表示将单条记录都存储输出映射对象中,每条记录的映射对象存放在List集合中
         */
        List<Emp> list = session.selectList("emp.select");
        for (Emp emp : list) {
            System.out.println(emp);
        }
        session.close();
    }
}

1.6.2 新しい操作

マッパーファイル:

<!--
	添加操作使用insert标签
	增删改操作没有resultType,只有查询有resultType;
	因为增删改操作返回值都是int类型,所以我们不需要指明

	注意:给占位符赋值,#{}中编写的内容为实体类型参数中的成员变量名称
		#{empno}    Mybatis会从传递过来的参数对象里面得到emono字段的值
-->
<insert id="insert" parameterType="com.newcapec.entity.Emp">
    insert into emp(ename,job,mgr,hiredate,sal,comm,deptno)
    values(#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
</insert>

Java コード:

@Test
public void testInsert() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    SqlSession session = factory.openSession();

    Emp emp = new Emp();
    emp.setEname("TOM");
    emp.setJob("CLARK");
    emp.setMgr(1);
    emp.setHiredate(new Date());
    emp.setSal(6500.0);
    emp.setComm(1200.0);

    System.out.println("新增之前的主键值为:" + emp.getEmpno());
    
    int result = session.insert("emp.insert", emp);
    
    System.out.println("影响数据库的条数为:" + result);
    /**
     * mybatis中的事务是jdbc的事务机制,mybatis里面默认是手动提交
     */
    session.commit();
    
    System.out.println("新增之后的主键值为:" + emp.getEmpno());

    session.close();
}

挿入されたデータの主キーは次を返します。

  • select last_insert_id() は、挿入されたばかりのレコードの主キー値を取得することを意味します。これは、自己増加する主キーを持つデータベースに適用されます。

  • デュアルから seq_demo.nextval を選択します。これは、次のシーケンスによって生成された値を取得することを意味します。これは、シーケンスを持つデータベースに適しています。

  • keyProperty: parameterType で指定されたオブジェクトの属性の主キー値にクエリを設定します。

  • order: selectKey タグ内の Sql ステートメントの実行順序 (insert ステートメントを基準とする)。

  • resultType: selectKey タグで Sql ステートメントの結果の型を指定します。

Oracle データベース:

<insert id="insert" parameterType="com.newcapec.entity.Emp">
    <selectKey resultType="java.lang.Integer" keyProperty="empno" order="BEFORE">
        select seq_demo.nextval from dual
    </selectKey>
    insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno)
    values(#{empno},#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
</insert>

MySQL データベース:

<insert id="insert" parameterType="com.newcapec.entity.Emp">
    <selectKey resultType="java.lang.Integer" keyProperty="empno" order="AFTER">
        select last_insert_id()
    </selectKey>
    insert into emp(ename,job,mgr,hiredate,sal,comm,deptno)
    values(#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
</insert>

主キーの自己インクリメント データベース (MySQL) の場合は、次のものも使用できます。

  • useGeneratedKeys: 主キーの戻り値を有効にするかどうか。false はデフォルトでは有効になっていません。

  • keyProperty: エンティティ クラスのどのメンバ変数が、取得された主キー値に格納されます。

<insert id="insert" parameterType="com.newcapec.entity.Emp" useGeneratedKeys="true" keyProperty="empno">
    insert into emp(ename,job,mgr,hiredate,sal,comm,deptno)
    values(#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
</insert>

1.6.3 モディファイ操作

マッパーファイル:

<update id="update" parameterType="com.newcapec.entity.Emp">
    update emp set ename=#{ename},job=#{job},mgr=#{mgr},hiredate=#{hiredate},sal=#{sal},comm=#{comm},deptno=#{deptno} where empno=#{empno}
</update>

Java コード:

@Test
public void testUpdate() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    SqlSession session = factory.openSession();

    Emp emp = new Emp();
    emp.setEmpno(7936);
    emp.setEname("JERRY");
    emp.setJob("MANAGER");
    emp.setMgr(7698);
    emp.setHiredate(new Date(new Date().getTime() + 1000*60*60*24));
    emp.setSal(7800.0);
    emp.setComm(800.0);

    int result = session.update("emp.update", emp);
    System.out.println("影响数据库的条数为:" + result);
    
    session.commit();

    session.close();
}

1.6.4 削除操作

マッパーファイル:

<delete id="delete" parameterType="java.lang.Integer">
    delete from emp where empno=#{empno}
</delete>

Java コード:

@Test
public void testDelete() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    SqlSession session = factory.openSession();

    int result = session.delete("emp.delete", 7935);
    System.out.println("影响数据库的条数为:" + result);

    session.commit();

    session.close();
}

1.6.5 あいまいクエリ

マッパーファイル:

<!--
	条件查询:模糊查询
    1、#{}占位符,防止sql注入
    需要在Java中将传入数据的前后拼接%符号
    where ename like #{ename}
    
	2、使用字符串拼接函数
    where ename like concat('%',#{ename},'%')

    3、${}拼接符号,实现sql的拼接
    where ename like '%${value}%'
    注意:${}不是占位符,如果输入参数为简单类型,${}中的内容必须为value
-->
<select id="selectByEname1" parameterType="java.lang.String" resultType="com.newcapec.entity.Emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
    where ename like #{ename}
</select>

Java コード:

@Test
public void testSelectByEname() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    SqlSession session = factory.openSession();
    String ename = "S";
    List<Emp> list = session.selectList("emp.selectByEname1", "%"+ename+"%");
    for (Emp emp : list) {
        System.out.println(emp);
    }
    session.close();
}

マッパーファイル:

<select id="selectByEname2" parameterType="java.lang.String" resultType="com.newcapec.entity.Emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
    where ename like concat('%',#{ename},'%')
</select>

Java コード:

@Test
public void testSelectByEname2() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    SqlSession session = factory.openSession();
    String ename = "S";
    List<Emp> list = session.selectList("emp.selectByEname2", ename);
    for (Emp emp : list) {
        System.out.println(emp);
    }
    session.close();
}

マッパーファイル:

<select id="selectByEname3" parameterType="java.lang.String" resultType="com.newcapec.entity.Emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
    where ename like '%${value}%'
</select>

Java コード:

@Test
public void testSelectByEname3() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    SqlSession session = factory.openSession();
    String ename = "S";
    List<Emp> list = session.selectList("emp.selectByEname3", ename);
    for (Emp emp : list) {
        System.out.println(emp);
    }
    session.close();
}

1.6.6 まとめ

parameterType と resultType:

    parameterType: 入力パラメータ タイプを指定します。MyBatis は ognl を介して入力オブジェクトからパラメータ値を取得し、Sql に設定します。

    resultType: 出力結果のタイプを指定します。MyBatis は、Sql クエリ結果のレコード データの行を、resultType で指定されたタイプのオブジェクトにマップします。

#{} と ${}:

    #{} はプレースホルダー シンボルを表し、#{} は入力パラメーターを受け取り、型は単純型、エンティティ クラス型、HashMap にすることができます; #{} は単純型を受け取り、#{} は値または他の名前として記述できます; #
    {
    } Entity クラスのオブジェクト値を受け取り、OGNL を介してオブジェクトの属性値を読み取り、attribute.attribute.attribute... を介してオブジェクトの属性値を取得します; ${} は、Sql インジェクションを参照するスプライシング シンボルを表すため
  
    、 ${ } の使用は推奨されません。
    ${} は入力パラメータを受け取ります。型は単純型、エンティティ クラス型、HashMap にすることができます。
    ${} は単純型を受け取ります。${} は値としてのみ書き込むことができます。
    ${} はエンティティを受け取ります。 class object value, OGNL を介して読み取られる オブジェクトの属性値。attribute.attribute.attribute... を介してオブジェクトの属性値を取得します。

selectOne和selectList:

    selectOne は、マッピングのためにレコードをクエリすることを意味します。selectOne
    を使用する場合は、selectList を使用できます (リスト内のオブジェクトは 1 つだけです)。selectList は、マッピングのために
    
    リスト (複数のレコード) をクエリすることを意味します。selectList
    を使用して複数のレコードをクエリする場合は、 selectOne を使用できません;
    selectOne を使用してエラーを報告する場合:  

1.7 MyBatis と Hibernate の違い

    Hibernate: 標準の ORM フレームワーク (オブジェクト リレーショナル マッピング) です。
        エントリのしきい値が高く、Sql を記述するプログラムが不要、SQL ステートメントが自動的に生成される、SQL ステートメントの最適化と変更が困難、アプリケーション シナリオ: 需要の変化がほとんどない中小規模のプロジェクトに適用可能
        、 : バックグラウンド管理システム、erp、crm、oa...;

    MyBatis: Sql 自体に焦点を当てるため、プログラマは Sql ステートメントを自分で作成する必要があります. Sql の変更と最適化はより便利です. MyBatis は
        不完全な ORM フレームワークです. プログラマは Sql を自分で記述しますが, MyBatis はマッピング (入力マッピング, 出力マッピング) も実装できます. ;
        アプリケーションシナリオ: 次のような適用可能で要求の厳しいプロジェクト: インターネット プロジェクト  

    企業は技術を選択し、技術選択の原則として低コストと高収益を取り、プロジェクトチームの技術力に応じて選択します。

    Mybatis は hibernate とは異なり、完全な ORM フレームワークではありません。MyBatis ではプログラマーが Sql ステートメントを自分で作成する必要があるためです。 sql を実行し、最後に sql 実行の結果をマップして Java オブジェクトを生成します。

    Mybatis は学習閾値が低く、習得が容易です. プログラマーはネイティブ sql を直接記述できます.これにより、sql 実行パフォーマンスを厳密に制御でき、柔軟性が高くなります. リレーショナル データ モデルの要件が高くないソフトウェア開発に非常に適しています.この種のソフトウェアは要件が頻繁に変更されるため、要件が変更されるとすぐに結果を出力する必要があります。ただし、柔軟性の前提として、mybatis はデータベースに依存できないため、複数のデータベースをサポートするソフトウェアを実装する必要がある場合は、複数の SQL マッピング ファイルのセットをカスタマイズする必要があり、負荷が高くなります。

    Hibernate は強力なオブジェクト/リレーショナル マッピング機能と優れたデータベース非依存性を備えています. Hibernate を使用して、リレーショナル モデルの要件が高いソフトウェア (要件が固定されたカスタマイズされたソフトウェアなど) を開発する場合、多くのコードを節約し、効率を向上させることができます。ただし、Hibernate は学習の敷居が高く、習熟度の敷居が高く、O/R マッピングの設計方法、パフォーマンスとオブジェクト モデルのトレードオフの方法、Hibernate の使いこなしには、豊富な経験と能力が必要です。

    つまり、限られたリソース環境で、従業員のニーズに合わせて保守性と拡張性に優れたソフトウェア アーキテクチャを作成できれば、それは優れたアーキテクチャなので、最適なフレームワークが適しているだけです。

1.8 Mybatis は JDBC プログラミングの問題を解決します

    1. データベース リンクの頻繁な作成と解放は、システム リソースの浪費を引き起こし、システム パフォーマンスに影響を与えます. データベース リンク プールを使用すると、この問題を解決できます.
        解決策: mybatis-config.xml でデータ リンク プールを構成し、接続プールを使用してデータベース リンクを管理します。

    2. SQL ステートメントがコード内に記述されているため、コードの保守が難しくなっている SQL の実際のアプリケーションは大きく変わる可能性があり、SQL の変更には Java コードの変更が必要です。
        解決策: XXXXmapper.xml ファイルで Sql ステートメントを構成し、それを Java コードから分離します。

    3. SQL 文の where 条件は必ずしも一定ではなく、多かれ少なかれ存在する可能性があり、プレースホルダはパラメータに 1 つずつ対応する必要があるため、SQL 文にパラメータを渡すのが面倒です。
        解決策: Mybatis は自動的に Java オブジェクトを sql ステートメントにマップし、ステートメントの parameterType を介して入力パラメーターの型を定義します。

    4. 結果セットを解析するのは面倒. sql の変更は解析コードの変更につながります, 解析する前に走査する必要があります. データベースレコードを pojo オブジェクトに解析する方が便利です.
        解決策: Mybatis は自動的に SQL 実行結果を Java オブジェクトにマップし、ステートメントの resultType を介して出力結果のタイプを定義します。

おすすめ

転載: blog.csdn.net/ligonglanyuan/article/details/124272162