ネイティブ Java は Mybatis を使用してデータベース インターフェイス アノテーション フォームを操作します。これは SpringBoot に似ており、SqlSession 接続のツール クラスを管理する必要はありません。

こんにちは、シェンディです



https://sdpro.top/blog/html/article/1044.html



要件の説明

SpringBootを使ったMybatisの統合は古くから行われており、Springを持たないがデータベースを操作するプログラムを書く場合、より効率的でシンプルなインターフェース+アノテーションの形を考えることになります。

@AutowirtedSpring では、インターフェイス マッピングを記述するだけでよく、その後、アノテーションを使用して、使用する必要がある場所に自動的にロードされ、直接使用できます。

Springを使わない場合、Mybatisを利用するためにSqlSessionFactoryを使用してSqlSessionを取得し、操作を処理し、操作後にSqlSessionを閉じる必要があり、非常に面倒です。

SqlSession.getMapper はインターフェイスインスタンスを常時使用できると思っていましたが、接続が切断されるとインスタンスが使用できなくなり、エラーが報告されることがわかったので、要件を満たすようにメソッドを変更しました


以下は、Mybatis の使用プロセスの紹介です (インターフェース + アノテーション フォーム、XML フォームは記載されていません)



依存関係のインポート

2 つの jar パッケージが必要です。1 つは jdbc ドライバーです。たとえば、mysql はオンラインで見つかる mysql-connector-java.jar を使用します。

mybatis の jar パッケージも使用します。mybatis の github から直接ダウンロードできます。

Maven の使用は、SpringBoot での依存関係の導入に似ています。インポートされた依存関係は Baidu で見つけることができます。jdbc と mybatis を導入する必要があります。



Mybatis設定ファイルの書き込み

形式は xml です。Mybatis の公式ドキュメントを参照できます。中国語です。ファイル名は任意で、通常は config.xml または mybatis-config.xml です。

Mybatis XML 設定ファイルの公式ドキュメント


設定ファイルをどこに置きますか。通常は src ディレクトリに置きます。この設定ファイルを見つける必要があるため、Mybatis はクラスを提供します。

MyBatis には、クラスパスまたは他の場所からリソース ファイルを簡単にロードできるようにするユーティリティ メソッドが含まれる Resources と呼ばれるユーティリティ クラスが含まれています。

プログラムがこのファイルを見つけることができる限り (Mybatis が提供する Resources クラスはあまり使いやすいとは思えません。このファイルは src ディレクトリにしか見つからず、src 下のサブディレクトリは見つかりません...)



私の構成をここに投稿しました。変更を確認できます

<?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>
	<!-- 这里的default指向的是使用的是哪个配置(id) 可以有多个 environment 指向多个数据库 -->
	<environments default="devMySql">
		<environment id="devMySql">
			<!-- 基于jdbc -->
			<transactionManager type="JDBC" />
			<!-- 数据源 配置一些数据库配置 type="POOLED" 使用MyBatis自带的连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.cj.jdbc.Driver" />
                <!-- 数据库 -->
				<property name="url" value="jdbc:mysql://localhost:3306/数据库?serverTimezone=UTC&amp;allowMultiQueries=true" />
				<property name="username" value="数据库用户名" />
				<property name="password" value="数据库密码" />
			</dataSource>
		</environment>
	</environments>
	<!-- 使用注解的方式 -->
	<mappers>
		<mapper class='shendi.TestMapper'/>
	</mappers>
</configuration>


XML から SqlSessionFactory を構築する

すべての MyBatis ベースのアプリケーションは、SqlSessionFactory のインスタンスを中心としています。SqlSessionFactory のインスタンスは、SqlSessionFactoryBuilder を通じて取得できます。SqlSessionFactoryBuilder は、XML 構成ファイルまたは事前構成された構成インスタンスから SqlSessionFactory インスタンスを構築できます。

SqlSessionFactoryには上記設定ファイルの情報が含まれており、後ほど使用するSqlSessionはこのクラスインスタンスから取得されます。

これは接続プールとして理解でき、SqlSession は接続です。


施工方法は以下の通りです(公式例)

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

上記のリソースは構成ファイルのパスを表します (実際に試行するとエラーが表示されます)

構成ファイルを src フォルダーに置くと、 resource は構成ファイルのファイル名を直接指定できます。



マッパーインターフェースを書く

SQL文には3つの方法があり、1つはxmlの方法、もう1つは直接インターフェース+アノテーションの方法、もう1つはインターフェース+xmlの方法です。

もちろん、私にとっては、直接インターフェイス + アノテーションの方法が使いやすく、シンプルで効率的です。


インターフェイスを作成し、それを注釈で関数上にマークするだけで、関数は対応する SQL 操作を表すことができます。一般的に使用される追加、削除、変更、およびクエリ

  • @入れる
  • @消去
  • @アップデート
  • @選択する

コードはここに直接掲載されています。結局のところ、ID に基づいてユーザーをクエリするなど、非常に単純です。

public interface TestMapper {
    
    
    @Select("SELECT * FROM user WHERE id=${id} LIMIT 1")
    HashMap<String,String> userById(int id);
}

上記は単なる例であり、HashMap 方法の代わりに Bean 方法を使用して戻り値を取得することもできます。

if判定、forループ、再帰クエリ(@Results)などでも

詳細については、他の記事を参照してください。この記事の焦点はここではありません



Java のコンパイル処理中にパラメータ名が arg0、arg1 などに変更され、元の名前が失われることに注意してください。Mybatis はリフレクションを通じてパラメータを見つけます。解決策は 2 つあります。

1. @Param アノテーションをパラメータに追加して名前を指定します

@Select("SELECT * FROM user WHERE id=${id} LIMIT 1")
HashMap<String,String> userById(@Param("id") int id);

2. コンパイル時にパラメータを指定する

javac -parameters このようにコンパイルしますが、もちろんコマンドラインを直接使用することはできず、通常は Eclipse や IDEA などの IDE を使用します。

  • アイディア
    • [設定] - [ビルド]、[実行]、[デプロイメント] - [コンパイラ] - [Java コンパイラ] をクリックします。
    • 追加のコマンドラインパラメータを入力します-parameters
  • 日食
    • ウィンドウ - 設定 - Java - コンパイラ
    • 勾配オプション メソッドパラメータに関するストア情報(リフレクション経由で使用可能)

私は2番目のほうが好きです



構成マップ

Mapperでは設定が必要ですが、初期設定ファイルに書かれている部分には、

<!-- 使用注解的方式 -->
<mappers>
    <mapper class='shendi.TestMapper'/>
</mappers>

このうち、class はクラスパス、TestMapper はマッピングクラスを表し、マッパーが複数ある場合は複数のマッパーを設定するだけです。


公式Webサイトにも、パッケージ全体のインターフェースをマッピングクラスとして使用できるものがありましたが、エラーを報告するために使用しています...

<mappers>
	<package name="shendi"/>
</mappers>


使用

構成、SQL、ファクトリ、すべてOKです。最後のステップは使用することです。単純すぎるため、コードを直接ここに示します。

// 拿到工厂
String resource = "config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(inputStream);

// 通过工厂获取SqlSession(连接)
SqlSession ss = ssf.openSession();
// 通过SqlSession获取接口映射实例
TestMapper tm = ss.getMapper(TestMapper.class);
// 直接使用接口就可以了
HashMap<String,String> user = tm.userById(1);
// 最后关闭SqlSession连接
ss.close();

SqlSessionを閉じるとgetMapperで取得したインターフェースインスタンスは使用できなくなり、直接エラーが報告されるためクラスメンバーとして保存することができません。

SpringBootに慣れている私にとっては面倒すぎる SpringBootインターフェースMapperのインスタンスは一つしかなく、接続の取得と接続のクローズを気にする必要がないので、ツールクラスをカプセル化しました



ツールクラス(接続を気にする必要がなく、使いやすい)

動的プロキシを使用して実装されたコア コードは、次の図に示されています。

ここに画像の説明を挿入


まず使い方を説明しますと、先ほどと同様に 1 行のコードだけでユーザー情報を取得できます。

HashMap<String,String> user = MapperUtil.TEST.userById(1);


ツールクラスの完全なコードは次のとおりです。

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
 * 所有的映射对象.
 * <br>
 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
 */
public class MapperUtil {
    
    

	public static final SqlSessionFactory SSF;
	
    // 映射类,全局放出去供调用
	public static final TestMapper TEST;
	
	static {
    
    
		SqlSessionFactory ssf = null;
        // 这个地方是找配置文件,用的自己写的,可以根据自己需求改掉
		try (FileInputStream fi = new FileInputStream(PathFactory.getPath(PathFactory.PROJECT, "/files/mybatis/config.xml"))) {
    
    
			ssf = new SqlSessionFactoryBuilder().build(fi);
		} catch (IOException e) {
    
    
			e.printStackTrace();
            // 日志,根据自己需求改掉
			Log.printErr("SqlSessionFactory创建失败,程序终止: %s", e.getMessage());
			System.exit(0);
		}
		SSF = ssf;
		ssf = null;
		
        // 拿到接口实例,后面多一个接口就照着多加一行就可以了
		TEST = getMapper(TestMapper.class);
	}
	
    // 动态代理,将接口实例的每个函数都代理了,执行前拿到SqlSession,执行完关闭SqlSession
	private static <T> T getMapper(Class<T> clazz) {
    
    
		@SuppressWarnings("unchecked")
		T obj = (T) Proxy.newProxyInstance(MapperUtil.class.getClassLoader(), new Class[] {
    
    clazz}, new InvocationHandler() {
    
    
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
				try (SqlSession ss = SSF.openSession()) {
    
    
					T mapper = ss.getMapper(clazz);
					
					Object result = method.invoke(mapper, args);
					
					return result;
				}
			}
		});
		
		return obj;
	}
	
}


補足(重要)

Mybatis の追加、削除、変更を有効にする (トランザクション) には手動で SqlSession.commit を呼び出す必要があるため、上記のツールを少し変更する必要があります。

コミットしない場合、エラーは報告されませんが、データベースにはデータがありません。

以下に変更します

private static <T> T getMapper(Class<T> clazz) {
    
    
    @SuppressWarnings("unchecked")
    T obj = (T) Proxy.newProxyInstance(MapperUtil.class.getClassLoader(), new Class[] {
    
    clazz}, new InvocationHandler() {
    
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
            SqlSession ss = SSF.openSession();
            try {
    
    
                T mapper = ss.getMapper(clazz);

                Object result = method.invoke(mapper, args);

                return result;
            } finally {
    
    
                ss.commit();
                ss.close();
            }
        }
    });

    return obj;
}

具体的には、コミットを単独でパッケージ化できる場所



終わり

おすすめ

転載: blog.csdn.net/qq_41806966/article/details/130191256