2011-07-05 1 views

답변

5

예. resultType 특성을 map으로 설정하면 테이블 데이터가 열 이름과 값의 HashMap에 배치됩니다. 쿼리가 둘 이상의 행을 반환하면 매핑 된 행이 List에 저장됩니다. 단일 열을 선택하려면 해당 값 (String, int 등) 또는 목록으로 가져올 수 있습니다.

<select id="test1" resultType="map">select * from user</select> 
<select id="test2" resultType="map" parameterType="int"> 
    select * from user where id=#{value}</select> 
<select id="test3" resultType="string">select name from user</select> 
... 
// returns a list of maps 
List test = sqlSession.selectList("test1"); 

// returns a single map 
Object map = sqlSession.selectOne("test2", 0); 

// returns a list of strings 
List names = sqlSession.selectList("test3"); 

이것은 MyBatis 3에 적용됩니다. 나는 당신이 iBatis 2에서 비슷한 것을 할 수 있다고 생각합니다.

+0

첫 번째와 세 번째는 차이가'이름을 가정하는 VARCHAR입니다 name' 선택'* 선택'와 사이에 같은 ... – Rudy

+0

보인다. * 일 필요는 없지만, 1 열 이상 필요하다면 resultType은 map (또는 Pojo)이어야합니다. 1 열만 선택하는 경우 열 유형이 무엇이든 resultType을 설정하십시오. – AngerClown

0

예, 런타임을 통해 API를 통해 매핑을 작성하고 엔티티 클래스 대신지도를 사용할 수 있어야합니다.

0

다음 접근법이 유용 할 수 있습니다. 일부 외부 종류에 따라

public interface IAutoRepository { 
    /** 
    * The automatically generated insertPKs sql statements. 
    * Parts of the query can be set manually in the sql (insert-select query). 
    * 
    * @param items  the {@link WhereStmt} statements 
    * @return the inserted rows count 
    */ 
    @Transactional 
    <T extends WhereStmt> Integer insertPKs(@Param("items") List<T> items); 

    /** 
    * Returns the value based on the {@link Parameter} class 
    * 
    * @param param  the {@link Parameter} instance 
    * @return the searched value in a {@link java.util.Map} form 
    */ 
    @MapKey("VAL") 
    <T extends Parameter> Map<String, Map<String, ?>> getDistinctValues(@Param("param") T param); 
} 

(예를 들어, 단일 열 또는 날짜 범위 또는 어떠한 범위) 템플릿 Common.xml에서 다음 쿼리를 정의 할 수 있습니다 : 말, 당신은 같은 몇 가지 일반적인 선택 인터페이스가

<sql id="includeDistinctValues"> 
SELECT 
    <choose> 
     <when test='param.type.name() == "set"'> 
      DISTINCT ${param.column} AS val 
     </when> 
     <when test='param.type.name() == "date" or param.type.name() == "range"'> 
      <some uid>    AS val, 
      MIN(${param.minColumn}) AS min, 
      MAX(${param.maxColumn}) AS max 
     </when> 
    </choose> 
FROM ${entityTable} 
</sql> 

mybatis에서받는 것은 java.util.Map입니다. setParameter를 다음과 같이 표현 될 수

public enum StmtType { 
    set((valMap) -> { 
     final Set<String> distinctValues = valMap 
       .values() 
       .stream() 
       .map(val -> (String) val.get("VAL")) 
       //use in date/range case 
       //final Date minDate = (Date) val.get("MIN"); 
       //final Date maxDate = (Date) val.get("MAX"); 
       .collect(Collectors.toSet()); 
     return distinctValues; 
    }, 
      (values, params) -> { 
       final SetParameter parameter = (SetParameter) params.getParams(); 
       return new WhereSetStmt<>(parameter.getColumn(), values, params.getIncludeEmptyValues()); 
      }); 
    @Getter 
    private Function<Map<String, Map<String, ?>>, ? extends Iterable> toValue; 
    @Getter 
    private BiFunction<Collection, DataParam, ? extends WhereStmt> toWhereStmt; 

    StmtType(
      Function<Map<String, Map<String, ?>>, ? extends Iterable> toValue, 
      BiFunction<Collection, DataParam, ? extends WhereStmt> toWhereStmt 
    ) { 
     this.toValue = toValue; 
     this.toWhereStmt = toWhereStmt; 
    } 
} 

:

public abstract class WhereStmt { 
    /** 
    * Type of the statement 
    */ 
    private final StmtType type; 
    /** 
    * Shall empty values be included. 
    */ 
    private final boolean includeEmptyValues; 
} 

@Getter 
public class WhereSetStmt<T> extends WhereStmt { 
    /** 
    * The column for `column` IN (...) statement 
    */ 
    private String column; 
    /** 
    * Values for `column` IN (...) statement 
    */ 
    private Collection<T> values; 

    public WhereSetStmt(String column, Collection<T> values, boolean includeEmptyValues) { 
     super(StmtType.set, includeEmptyValues); 
     this.column = column; 
     this.values = values; 
    } 
} 

@Getter 
@AllArgsConstructor 
public final class DataParam<P extends Parameter> { 
    /** 
    * Whether to include nullable values. 
    */ 
    private final Boolean includeEmptyValues; 
    /** 
    * Represents database required information for later processing and sql statements generation. 
    */ 
    private final P params; 
} 

: 또한

@Getter 
public class SetParameter extends Parameter { 
    /** 
    * Column in sql query, 
    */ 
    private final String column; 
    public SetParameter(String column) { 
     super(StmtType.set); 
     this.column = column; 
    } 
} 

, 당신은 같은 일부 WhereStmt를 정의 할 수 있습니다 그럼 당신은 어떤 종류처럼 사용할 수 있습니다 마지막으로 mybatis generic Common.xml에서 다음과 같이 사용할 수 있습니다.

<sql id="includeInsertPkSelect"> 
    SELECT DISTINCT(${id}) 
    FROM ${entityTable} 
</sql> 

<sql id="includeInsertPkWhere"> 
    <if test="items != null and items.size() > 0"> 
     AND 
     <foreach collection="items" item="item" index="i" separator="AND"> 
      <choose> 
       <when test='item.type.name() == "set" and (item.values != null and item.values.size() > 0 or item.includeEmptyValues)'> 
        (
        <if test="item.values != null and item.values.size() > 0"> 
         ${item.column} IN 
         <foreach item="value" collection="item.values" separator="," open="(" 
           close=")"> 
          #{value} 
         </foreach> 
         <if test="item.includeEmptyValues"> 
          OR 
         </if> 
        </if> 
        <if test="item.includeEmptyValues"> 
         ${item.column} IS null 
        </if> 
        ) 
       </when> 

       <when test='item.type.name() == "date"'> 
        (
        COALESCE(${item.column}, SYSDATE + 1000000) 
        BETWEEN #{item.from} AND #{item.to} 
        <if test="item.includeEmptyValues"> 
         OR ${item.column} IS NULL 
        </if> 
        ) 
       </when> 
       <when test='item.type.name() == "range"'> 
        (
        COALESCE(${item.column}, 1000000000) 
        BETWEEN #{item.from} AND #{item.to} 
        <if test="item.includeEmptyValues"> 
         OR ${item.column} IS NULL 
        </if> 
        ) 
       </when> 
      </choose> 
     </foreach> 
    </if> 
</sql> 
템플릿으로

와 결합 SQL 문은 다음과 같이 말합니다

<insert id='insertPKs'> 
    INSERT INTO requiredTable 
    <include refid="Common.includeInsertPkSelect"> 
     <property name="id" value="entityId"/> 
     <property name="entityTable" value="entityTable"/> 
    </include> 
    <include refid="Common.includeInsertPkWhere"> 
     <property name="id" value="entityId"/> 
     <property name="entityTable" value="entityTable"/> 
    </include> 
</insert>