四、MyBatisのサードパーティ製ソフトウェアの統合ソースコードの解析

、春統合MyBatisの


知識ポイント

  1. コアの使用
  2. コア流解析
  3. 物事を使用します
  4. マッパーは、設定を簡素化

図1に示すように、コアの使用:

使用して統合基盤:

  1. コンフィギュレーションデータソース
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;rewriteBatchedStatements=true"></property>
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
</bean>
复制代码
  1. 設定SqlSessionFactoryBean
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
    <!--<property name="mapperLocations" value="classpath:com/cyan/mapper/*.xml"></property>-->
</bean>
复制代码
  1. 設定MapperFactoryBean
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface" value="com.cyan.mapper.UserMapper"/>
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
复制代码
  1. マッパーインタフェースを作成します(UserMapper)
@Select("select * from user where id=#{id}")
User selectUserById1(Integer id);
复制代码
  1. ビジネスメソッドを実行するためにマッパーオブジェクトを取得します。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserMapper userMapper = context.getBean(UserMapper.class);
User user = userMapper.selectUserById1(1);
System.out.println(user);
复制代码

以下のような命令のコア:

FactoryBeanのは:カスタムBeanオブジェクトを構築するために使用される豆植物は、IOC FactoryBeanの実施例に配置されたとき、FactoryBean.getObjectの最終パスはビーンID()例えば、FactoryBeanのないインスタンス自体を対応します

SqlSessionFactoryBean:、SqlSessionFactoryインスタンス、シングルトンオブジェクトを生成するアプリケーションのライフサイクル全体に働きます。次のように共通の属性は次のとおりです。

  • データソース:データソース(必須)
  • configLocation:MyBatisの-config.xmlの(オプション)コンテンツを指定し、その障害が提供されます
  • mapperLocations:mapper.xml指定されたパスは、対応する要素はMyBatisの-config.xml構成、(オプション)

MapperFactoryBeanは:通常、単一の実施形態、対応するマッパーオブジェクトを生成し、アプリケーション全体のライフサイクルに適用されます。次のように共通の属性は次のとおりです。

  • mapperInterface:マッパーインタフェース(必須)
  • sqlSessionFactory:セッションファクトリのインスタンス参照(必須)

マッパーの問題の下で安全なシングルトンの場合、スレッドがあるかどうか?

スレッドの安全性の問題を解決する方法の一つの例をマッパー今、何のセキュリティスレッドは存在しません、同期されSQLSESSIONとネイティブMyBatisの中マッパーオブジェクトでの寿命を使用しますか?

図2に示すように、コア・フロー分析

SQLセッション一体化構造:

絵

初期化プロセス

  1. セッションテンプレートを作成しますSqlSessionTemplate
> org.mybatis.spring.mapper.MapperFactoryBean#getObject()
> org.mybatis.spring.support.SqlSessionDaoSupport#getSqlSession()
> org.mybatis.spring.support.SqlSessionDaoSupport#setSqlSessionFactory()
> org.mybatis.spring.support.SqlSessionDaoSupport#createSqlSessionTemplate()
> org.mybatis.spring.SqlSessionTemplate#SqlSessionTemplate()
> org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor()
复制代码
  1. インタフェースの作成
> org.mybatis.spring.mapper.MapperFactoryBean#getObject()
> org.mybatis.spring.SqlSessionTemplate#getMapper()
> org.apache.ibatis.session.Configuration#getMapper()
> org.apache.ibatis.binding.MapperRegistry#getMapper()
> org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.session.SqlSession)
复制代码
  1. クエリを実行
> com.cyan.test#selectUserByid()
> org.apache.ibatis.binding.MapperProxy#invoke()
> org.mybatis.spring.SqlSessionTemplate#selectOne()
> org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor#SqlSessionInterceptor()
> org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor#invoke()
> org.mybatis.spring.SqlSessionUtils#getSqlSession()
> org.apache.ibatis.session.SqlSessionFactory#openSession()

> org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne()
复制代码

すべてのSQLSESSIONの一つは、新しいセッションを作成し、キャッシュは、右の効果がかかりますか?

前のレッスンによって、私たちは学んだ:条件のキャッシュは、同じセッションでなければならないので、春と統合以下によるキャッシュが有効になりません。春の事がない限り、それはセッションに再作成されません。

3、物事の使用

MyBatisの設定のための春のものではない、設定するには、いくつかの一般的なものは以下のとおりです。

<context:annotation-config/>

<context:component-scan base-package="com.cyan.service.**"/>

<!--添加事物配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--开启事物注解-->
<tx:annotation-driven/>
复制代码

物事は注意してください追加します。

@Transactional
public User selectUserById(Integer id) {
    userMapper.selectUserById(id);
    return userMapper.selectUserById(id);
}
复制代码

テストを実行する2つのクエリを作成するためにselectUserById()メソッドを呼び出すときはSQLSESSIONを繰り返さないことがわかりました。しかしselectUserById方法まで、共通の終わり。

物事とSQLSESSION統合の原則:

原則フロントそれはいくつかのクエリ処理の話に来るとき。たびにSQL操作がgetSqlSessionことで、セッションの前に取得されます行います。メインのロジックは次のとおりです。物事の現在のスレッドの存在があれば、と相関セッションがあり、次のクエリのためにそれらにThreadLocal新しいを作成するために存在していないセッションは、関連するセッションに保存されます、ThreadLocalのから取りました。トランザクションを実行しない現在のスレッドがSQLSESSIONのSQLを作成した場合、ThreadLocalのそれらに保存されません。

関連アイテム:

> org.mybatis.spring.SqlSessionUtils#getSqlSession()
> org.springframework.transaction.support.TransactionSynchronizationManager#getResource()
> org.springframework.transaction.support.TransactionSynchronizationManager#doGetResource()

> org.mybatis.spring.SqlSessionUtils#sessionHolder()
> org.apache.ibatis.session.SqlSessionFactory#openSession()
> org.mybatis.spring.SqlSessionUtils#registerSessionHolder()
> org.springframework.transaction.support.TransactionSynchronizationManager#isSynchronizationActive()
> org.springframework.transaction.support.TransactionSynchronizationManager#bindResource()
复制代码

図4に示すように、概略構成マッパー

各マッパインターフェイスが設定されている場合MapperFactoryBeanかなり面倒を走査することによって自動的に配置されていてもよいです

<mybatis:scan base-package="com.cyan.mapper"></mybatis:scan>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.cyan.mapper"></property>
</bean>
复制代码

同様の走査機構を有するばね豆アノテーションのように注釈を追加する必要がスキャナ設定

<context:annotation-config/>
复制代码

第二に、動的SQL


知識ポイント

  1. ダイナミックコマンド
  2. カスタムテンプレートインタプリタ

1、動的コマンド

  • もし
  • (と、それ以外)を選択します
  • トリム(ここで、設定)
  • foreachの

、例を示します。

<select id="selectByUser" parameterType="com.cyan.pojo.User" resultType="com.cyan.pojo.User">
    select * from user
    <trim prefix="where" prefixOverrides="and|or">
        <if test="id !=null and id != ''">
            and id = #{id}
        </if>
        <if test="name !=null and name != ''">
            and name = #{name}
        </if>
    </trim>
</select>
复制代码

プロパティ説明をトリム:

  • 接頭辞=「」//接頭辞
  • 単語を置き換えるために//接頭辞| prefixOverrides =「かと」
  • 接尾辞=「」//サフィックスを追加
  • 単語を置き換えるためにsuffixOverrides =「」//サフィックス

要素説明:

自動的にパッケージとは、最後の文字がマルチ彼女と終了するSQL削除場所の前に追加されます|や文字、次の構成に相当します:

<trim prefix="where" prefixOverrides="and|or" suffixOverrides="and|or">

<select id="selectByUser" parameterType="com.cyan.pojo.User" resultType="com.cyan.pojo.User">
    select * from user
    <where>
        <if test="id !=null and id != ''">
            and id = #{id}
        </if>
        <if test="name !=null and name != ''">
            and name = #{name}
        </if>
    </where>
</select>
复制代码

,,要素説明:

Javaでswitch文と同様に

<select id="selectUserByNameOrId" resultType="com.cyan.pojo.User">
    select * from user
    <where>
        <choose>
            <when test="id != null">
                and id = #{id}
            </when>
            <when test="name != null and name != ''">
                and name = #{name}
            </when>
            <otherwise>
                and id in (1,2,3)
            </otherwise>
        </choose>
    </where>
</select>
复制代码

要素説明:

自動的に彼女のラップSQLの複数を終了し、削除するために設定された終了前に設定文字「」文字が追加されます。

<update id="updateUserById" parameterType="com.cyan.pojo.User">
    update user
    <set>
        <if test="name != null and name != ''">
            name = #{name},
        </if>
        <if test="updateTime != null">
            update_time = #{updateTime}
        </if>
    </set>
    where id = #{id}
</update>
复制代码

要素説明:

機能foreach要素は、それはあなたが体の変数の要素に使用することができ、コレクション、アイテムのコレクション(項目)およびインデックス(指数)のステートメントを指定することができ、非常に強力です。また、あなたは、文字列の先頭と末尾を指定することができますし、反復の結果との間に、セパレータを配置します。この要素は、スマートなので、誤って余分な区切り文字を追加しません。

<select id="selectUserListByIds" resultType="com.cyan.pojo.User">
    select * from user
    <where>
        <if test="ids != null">
            id in
            <foreach collection="ids" item="item" index="index" open="(" close=")" separator=",">
                #{item}
            </foreach>
        </if>
    </where>
</select>
复制代码

要素説明:

同じ複数のSQLマッパーステートメントの同じセクションは、複数の要素によって参照される要素宣言により行うことができる場合

<sql id="files">
    id,name,create_time,update_time
</sql>

<select id="selectUserById2" resultType="com.cyan.pojo.User" parameterType="int">
    select
    <include refid="files"></include>
    from user where id = #{id}
</select>
复制代码

変数:

要素を宣言することによって、いくつかの追加の論理演算を必要とし、その動作スクリプト属性値を追加することができ、次の例では、自動的にlikeName%のセミコロンに追加され、その後、#{likeName}のようなセミコロン%で使用することができ操作。

<select id="selectByUser" parameterType="com.cyan.pojo.User" resultType="com.cyan.pojo.User">
    <bind name="likename" value="'%'+_parameter.getName()+'%'"></bind>
    select * from user
    <trim prefix="where" prefixOverrides="and|or">
        <if test="id !=null and id != ''">
            and id = #{id}
        </if>
        <if test="name !=null and name != ''">
            and name like #{likename}
        </if>
    </trim>
</select>
复制代码

組み込み変数:

  • _databaseidデータベース識別子ID
  • 現在の治療パラメータ変動_PARAMETER

2、カスタムテンプレートインタプリタ

場合は、上記のロジックや他の事業者が提供する言語XMLLanguageDriverのMyBatisの独自の解釈されている場合、加えて我々はまた、動的なスクリプトを記述するためにMyBatisの-速度やMyBatisの-FreeMarkerのおよび他の外部インタプリタを使用することができ、トリム。

MyBatisの-FreeMarkerの使用:

ジャーパッケージの紹介:

<dependency>
    <groupId>org.mybatis.scripting</groupId>
    <artifactId>mybatis-freemarker</artifactId>
    <version>1.2.0</version>
</dependency>
复制代码

SQLステートメントを追加します。

<select id="selectUserListByIds" resultType="com.cyan.pojo.User"
            lang="org.mybatis.scripting.freemarker.FreeMarkerLanguageDriver">
    select * from user
    where  id in (${ids?join(',')})
</select>
复制代码

インターフェースメソッドの追加

List<User> selectUserListByIds(@Param("ids") List<Integer> ids);
复制代码

おすすめ

転載: juejin.im/post/5da30cb4f265da5b5e2d9c5c