2017-04-21 16 views
3

私はこれが単純な問題だと感じますが、私が仕事をしてくれたものはありません。私は列挙型を持っています。なぜなら、Javaは列挙型のコンストラクタを持っていないからです。列挙型のコンストラクタなしで直接AA、AB、2Cを試しましたが、エラーが発生します。既存のenumではC( "2C")を追加しています。Java MyBatis列挙型文字列値

public enum TestEnum{ 
     AA("AA"), AB("AB"), C("2C"); 
     private String display; 
    private TestEnum(String display) { 
      this.display = display; 
     } 
    public String toString() { 
      return display; 
     } 
    public String getDisplay() { 
      return display; 
     } 
    public void setDisplay(String display) { 
      this.display = display; 
     } 
    public String getName() { 
      return display; 
     } 

は今、私は、これは、既存され、マッパーへのparamの一つがTestEnumでマージを行うMyBatisのマッパーを持っています。これまでは、enumの値と文字列の値が同じであるため、これはうまくいきましたが、C( "2C")を追加しました。今はmybaitsを使用してテーブルに図2Cを挿入するが、それは常に

merge into text t 
     using (select #{id} as id from dual) d on (d.id = t.id) 
     when matched then 
     update set 
     appId = #{applId}, 
     src = #{testEnum} 

C.

挿入testEnumはCを挿入するので、私は私は何のゲッターが存在しないを与えた#{testEnum.toString()}にそれを変更しましたプロパティ名のtoString()エラーです。私は#{testEnum.display}と#{testEnum.name}を試しましたが、2人ともCを挿入していましたが、2人も挿入します。あなたはこれを扱う簡単な方法を知っていますか?

このオブジェクトが多くの場所で使用されているため、TestEnumではなくStringを渡すようにモデルオブジェクトを変更したくありません。これはモデルオブジェクトを変更せずにmybatisマッパーで行うことができますか?あなたの助けのための

感謝:)あなたが必要なもの

答えて

3

TypeHandler

まずあり、TestEnum与えられた表示文字列を返すためにあなたのTestEnumに静的メソッドを追加します。次に

public static TestEnum fromDisplay(String display){ 
    for (TestEnum v : TestEnum.values()){ 
     if (v.getDisplay().equals(display)){ 
      return v; 
     } 
    } 
    return null; 
} 

をTypeHandlerを作成するために使用してください:

import java.sql.CallableStatement; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 

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

public class TestEnumTypeHandler extends BaseTypeHandler<TestEnum> { 

    @Override 
    public void setNonNullParameter(PreparedStatement ps, int i, TestEnum parameter, JdbcType jdbcType) 
      throws SQLException { 
     ps.setString(i, parameter.getDisplay()); 
    } 

    @Override 
    public TestEnum getNullableResult(ResultSet rs, String columnName) throws SQLException { 
     return TestEnum.fromDisplay(rs.getString(columnName)); 
    } 

    @Override 
    public TestEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException { 
     return TestEnum.fromDisplay(rs.getString(columnIndex)); 
    } 

    @Override 
    public TestEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { 
     return TestEnum.fromDisplay(cs.getString(columnIndex)); 
    } 
} 
最後に

、あなたのMyBatisのXMLの中であなたのTypeHandlerを登録します。また

<typeHandlers> 
    <typeHandler handler="blah.blah.TestEnumTypeHandler "/> 
</typeHandlers> 
+0

驚くばかりです。ありがとうございます –

2

を回答@Maltする:

何をしようとしていることname()値デフォルトのセットで、それはMyBatisのEnumTypeHandlerの作品ない理由をfinalでマークされ、方法のように、あなたはそれをオーバーライドすることはできません。

EnumTypeHandler.class(ライン38〜44):

@Override 
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException { 
    if (jdbcType == null) { 
     ps.setString(i, parameter.name()); 
    } else { 
     ps.setObject(i, parameter.name(), jdbcType.TYPE_CODE); // see r3589 
    } 
    } 

それ以外の場合は、列挙型の名前も使用するvalueOf(type, name)メソッドから列挙型が作成されます。

@Override 
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException { 
    String s = rs.getString(columnIndex); 
    return s == null ? null : Enum.valueOf(type, s); 
    } 

    @Override 
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { 
    String s = cs.getString(columnIndex); 
    return s == null ? null : Enum.valueOf(type, s); 
    } 

だから、間違いなく、あなたは可能性があるため、具体的な行動を持っているあなたの列挙型を処理するためにtypeHandlerの特定を使用するが、私は直接、特定の列挙型ハンドラでEnumTypeHandlerextendsなり、代わりにBaseTypeHandler(モルト答え)が必要いくつかの機能を再利用します(あなたの場合ではなく、おそらく他の機能で)。そのため、一般的な列挙型の動作を処理します。

+0

意味があります説明のためにありがとう –

0

Enumの値を挿入する場合は、カスタムTypeHandlerを書く必要はありません。

あなたが行う必要があるのは、MyBatisの挿入にゲッターメソッドの名前を指定することだけです。

例:

SQL:

CREATE TABLE demo 
(
    id BIGINT, 
    value VARCHAR(10), 
    status CHAR(1) 
); 

MyBatisのマッパー:

@Update("UPDATE demo SET status = #{status.value} WHERE id= #{uuid}") 
    long updateStatus(@Param("status") Status status, @Param("uuid") String uuid); 

とJavaの列挙:

public enum Status { 
    ACTIVE("A"), 
    INACTIVE("I"); 

    Status(final String value) { 
     this.value = value; 
    } 

    public String getValue() { 
     return value; 
    } 
} 

あなたの場合、src = #{testEnum.display}をSQLに使用できます。

関連する問題