MyBatisのと共に使用されるプロセッサのタイプ:エントリからのMyBatisの(XIV)

Liuzengホイ先生は最近、「マスターへのエントリからMyBatisの、」本を読んであなたを助けるために、光栄として書籍、やりがいので、ブログ形式で自分出力の学習プロセスは、間違っている場合、私を修正してください!

MyBatisの中でプロセッサの種類に主にこのブログの使い方。

1.明確な需要

初期の設計では、有効なフィールドsys_roleテーブルは、2つの可能な0が無効に表した値、有効ための1、そして我々はIntergerタイプを使用しているエンティティクラスがあります。

/**
 * 有效标志
 */
private Integer enabled;

public Integer getEnabled() {
    return enabled;
}

public void setEnabled(Integer enabled) {
    this.enabled = enabled;
}

あなたは情報の役割を追加または更新する場合、我々は確かに価値が有効フィールドを確認したいので、コードの最初の部分は次のようになります、0または1でなければなりません。

if (sysRole.getEnabled() == 0 || sysRole.getEnabled() == 1) {
     sysRoleMapper.updateById(sysRole);

     sysRole = sysRoleMapper.selectById(2L);
     Assert.assertEquals(0, sysRole.getEnabled());
} else {
     throw new Exception("无效的enabled值");
}

ポスト維持に資する非友好的に見える、といないだけでなく、このハードコーディングされた方法は、メンテナンスプログラマ不機嫌場合、ハハ、あなたを呼び出します。

だから我々は、有効なフィールドをチェックするためにハードコードされた、ユーザーフレンドリーなエンコード値を拒否している需要有効です。

2. MyBatisのによって提供される列挙型プロセッサを使用

我々は通常、このシナリオを解決するために列挙を使用しています。

まず、新しいcom.zwwhnly.mybatisaction.typeパッケージ、そしてパッケージに有効列挙を作成します。

package com.zwwhnly.mybatisaction.type;

public enum Enabled {
    /**
     * 禁用
     */
    disabled,
    
    /**
     * 启用
     */
    enabled;
}

無効に対応するインデックスが0であり、対応するインデックスを可能にしました。

そして、SysRoleクラスはInteger型の本来のフィールドを変更することが可能となります。

/**
 * 有效标志
 */
private Enabled enabled;

public Enabled getEnabled() {
    return enabled;
}

public void setEnabled(Enabled enabled) {
    this.enabled = enabled;
}

この時点で、ハードコードされた元のコードをに変更することができます。

if (sysRole.getEnabled() == Enabled.disabled || sysRole.getEnabled() == Enabled.enabled) {
    sysRoleMapper.updateById(sysRole);

    sysRole = sysRoleMapper.selectById(2L);
    Assert.assertEquals(Enabled.disabled, sysRole.getEnabled());
} else {
    throw new Exception("无效的enabled值");
}

上記のコードはハードコードされた問題に対する最適なソリューションですが、今回は新たな問題を提起するものの:

データベースクエリまたはアップデートとして、追加するときときクエリデータ、データベースの列挙値のint型に変換する必要がある、有効列挙型を認識しない、データベースが有効粉々にint型の値であることが必要です入力してください。

この問題では、我々は次の試験方法SysRoleMapperTestテストクラスを追加します。

@Test
public void testUpdateById() {
    SqlSession sqlSession = getSqlSession();

    try {
        SysRoleMapper sysRoleMapper = sqlSession.getMapper(SysRoleMapper.class);

        // 先查询出id=2的角色,然后修改角色的enabled值为disabled
        SysRole sysRole = sysRoleMapper.selectById(2L);
        Assert.assertEquals(Enabled.enabled, sysRole.getEnabled());

        // 修改角色的enabled为disabled
        sysRole.setEnabled(Enabled.disabled);

        if (sysRole.getEnabled() == Enabled.disabled || sysRole.getEnabled() == Enabled.enabled) {
            sysRoleMapper.updateById(sysRole);

            sysRole = sysRoleMapper.selectById(2L);
            Assert.assertEquals(Enabled.disabled, sysRole.getEnabled());
        } else {
            throw new Exception("无效的enabled值");
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        sqlSession.close();
    }
}

次のように例外をスローするテストコード、見つかっを実行します。

データベースを照会エラー。原因:org.apache.ibatis.executor.result.ResultMapException:エラーは、結果セットから「有効」列を取得しよう。原因:java.lang.IllegalArgumentExceptionが:いいえ列挙型定数com.zwwhnly.mybatisaction.type.Enabled.1

これらの両方を変換するTypeHandler(タイプのプロセッサ)を使用して、MyBatisのJava型とデータベース・タイプを扱う場合があるからです。

MyBatisのは、Java JDBCデータベースタイプと種類一般的に使用されるタイプの実装TypeHandlerインタフェースを提供します。

起動時にMyBatisのはorg.apache.ibatis.type.EnumTypeHandler列挙型を処理するには、デフォルトのプロセッサを使用して、プロセッサのすべてに対応するJDBCタイプをロードすると、プロセッサは、列挙型文字列型に変換します額面の使用は、有効列挙のために、それは「無効」と「有効」の文字列です。

データベース有効なフィールドの型はintですので、int型の値が1つの変換のクエリ情報での役割を有効型に与えられています。

それでは、どのようにこの問題を解決するには?

MyBatisのは、他の列挙処理を提供する:org.apache.ibatis.type.EnumOrdinalTypeHandler、プロセッサは、列挙インデックスを使用して、エラーを変換する問題を解決することができ、ここで処理されます。

このプロセッサを使用すると、次のような構成で前のリソース/ MyBatisの-config.xmlが追加する必要があります。

<typeHandlers>
    <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
                 javaType="com.zwwhnly.mybatisaction.type.Enabled"/>
</typeHandlers>

再びテストコードを実行し、テストは次のログを出力し、渡します。

DEBUG [メイン] - ==>準備:SELECT ID、ROLE_NAMEは、sys_roleからcreate_by、CREATE_TIMEを有効にWHERE ID =?

DEBUG [メイン] - ==>パラメータ:2(ロング)

TRACE [メイン] - <==列:ID、ROLE_NAME、有効、create_by、CREATE_TIME

TRACE [メイン] - <==行:2、普通のユーザ、1、1、2019-06-2718:21:12.0

DEBUG [メイン] - <==合計:1

DEBUG [メイン] - ==>準備:?UPDATE sys_role SETのROLE_NAMEを=、=有効、create_by = ?, CREATE_TIME =?WHERE ID =?

DEBUG [メイン] - ==>パラメータ:通常のユーザー(文字列)、0(整数)、1(長く)、2019年6月27日18:21:12.0(タイムスタンプ)、2(ロング)

DEBUG [メイン] - <==更新:1

ログから分かるように、ロール情報を照会する場合、MyBatisのは、文字情報を更新する際に、MyBatisのが0に変換Enabled.disabledます、Enabled.enabledに1を変換します。

プロセッサの3.カスタムタイプ

有効なフィールドの列挙値は、この時点でリテラルも列挙インデックス値でもないと仮定するorg.apache.ibatis.type.EnumTypeHandlerと、org.apache.ibatis.type.EnumOrdinalTypeHandler我々のニーズを満たすことができない、私たちは、この場合にはプロセッサの自分のタイプを実装する必要があります。

列挙されたすべての修正の最初のクラスの有効コード:

package com.zwwhnly.mybatisaction.type;

public enum Enabled {

    /**
     * 启用
     */
    enabled(1),

    /**
     * 禁用
     */
    disabled(0);

    private final int value;

    private Enabled(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

com.zwwhnly.mybatisaction.typeパッケージで、新しいプロセッサタイプEnabledTypeHandler:

package com.zwwhnly.mybatisaction.type;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * Enabled类型处理器
 */
public class EnabledTypeHandler implements TypeHandler<Enabled> {
    private final Map<Integer, Enabled> enabledMap = new HashMap<Integer, Enabled>();

    public EnabledTypeHandler() {
        for (Enabled enabled : Enabled.values()) {
            enabledMap.put(enabled.getValue(), enabled);
        }
    }

    @Override
    public void setParameter(PreparedStatement preparedStatement, int i, Enabled enabled, JdbcType jdbcType) throws SQLException {
        preparedStatement.setInt(i, enabled.getValue());
    }

    @Override
    public Enabled getResult(ResultSet resultSet, String s) throws SQLException {
        Integer value = resultSet.getInt(s);
        return enabledMap.get(value);
    }

    @Override
    public Enabled getResult(ResultSet resultSet, int i) throws SQLException {
        Integer value = resultSet.getInt(i);
        return enabledMap.get(value);
    }

    @Override
    public Enabled getResult(CallableStatement callableStatement, int i) throws SQLException {
        Integer value = callableStatement.getInt(i);
        return enabledMap.get(value);
    }
}

カスタム型TypeHandlerプロセッサは、インタフェース、4つの方法、列挙型および横断有効フィールドなし参照コンストラクタenabledMap割り当てられた値を書き換えるためのインターフェースを実装します。

あなたにはMyBatisの-config.xmlに/リソースを次のようにも追加され、プロセッサのカスタム型を使用します:

<typeHandlers>
    <!--其他配置-->
    <typeHandler handler="com.zwwhnly.mybatisaction.type.EnabledTypeHandler"
                 javaType="com.zwwhnly.mybatisaction.type.Enabled"/>
</typeHandlers>

テストコードを実行し、ログを投稿ここでは繰り返されていないため、上記の出力ログを出力します。

前記基準源と

ソースアドレス:https://github.com/zwwhnly/mybatis-action.git、ダウンロードして歓迎。

Liuzengホイ「マスターへのエントリからMyBatisの。」

5.最後に

少し宣伝を再生し、マイクロチャンネルスキャンコード番号の公衆に焦点を歓迎:私たちは一緒に進行するように、Javaテクノロジ乾燥品を共有するために定期的に「上海は見知らぬ人です」。

おすすめ

転載: www.cnblogs.com/zwwhnly/p/11238131.html