2017-04-21 12 views
3

나는 이것이 간단한 문제라고 느낀다. 그러나 나에게 도움이되는 것들은 없다. 열거 형을 가지고있는 이유는 Java가 열거 형을 허용하지 않기 때문에 문자열 생성자가 있습니다. 문자열 생성자없이 AA, AB, 2C를 직접 시도했지만 오류가 발생합니다. 기존 enum에 대해서는 C ("2C")를 추가하고 있습니다. 자바 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로 매퍼가 있습니다. 지금까지 열거 형 값과 문자열 값이 동일하기 때문에이 방법이 유용했지만 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} 

testEnum가 C를 삽입 C.

삽입, 그래서 내가 #이 {testEnum.toString은()} 나을 준에 더 게터가 없음을 변경 속성 이름 toString() 오류. 나는 # {testEnum.display}와 # {testEnum.name}을 시도했지만 C가 삽입되는 반면 C는 2C를 삽입하려고합니다. 이 문제를 처리하는 더 쉬운 방법을 알고 계십니까?

모델 객체를 변경하지 않고 mybatis 매퍼에서 수행 할 수있는 방법이 있습니다.이 객체가 많은 장소에서 사용되고 있기 때문에 TestEnum보다는 String을 전달하는 모델 객체를 변경하고 싶지 않습니다. 그런 다음

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

: 당신의 도움 :)에 대한

덕분에

답변

3

당신이 필요로하는 것은 TypeHandler

우선이다, 주어진 TestEnum를 반환하기 위해 TestEnum에 표시 문자열을 정적 메소드를 추가 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를 사용해야합니다,하지만 난 extends 직접 특정 열거 형 처리기에서 EnumTypeHandler 대신 BaseTypeHandler (맥아 응답을) 것 일부 기능을 재사용 (귀하의 경우는 아니지만 다른 경우) 할 수 있으므로 일반 열거 형 동작을 처리합니다.

+0

의미가 있습니다. 설명을 위해 고마워요. –

0

Enum의 값을 삽입하려면 사용자 정의 TypeHandler을 쓸 필요가 없습니다.

MyBatis 삽입물에 getter 메소드의 이름을 지정하면됩니다.

예 :

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); 

그리고 자바 열거 :

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

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

    public String getValue() { 
     return value; 
    } 
} 

귀하의 경우에는 src = #{testEnum.display}을 SQL에 사용할 수 있습니다.