Ibatis/MyBatis를 사용하여 동적으로 선택/업데이트/삭제할 수있는 방법이 있습니까?Ibatis/MyBatis는 Pojo/Mapper를 만들 필요없이 동적으로 선택합니다.
"동적으로"라고 말하면 POJO/DataMapper를 전혀 작성하고 싶지 않다는 의미입니다.
모든 URL 예제를 환영합니다.
Ibatis/MyBatis를 사용하여 동적으로 선택/업데이트/삭제할 수있는 방법이 있습니까?Ibatis/MyBatis는 Pojo/Mapper를 만들 필요없이 동적으로 선택합니다.
"동적으로"라고 말하면 POJO/DataMapper를 전혀 작성하고 싶지 않다는 의미입니다.
모든 URL 예제를 환영합니다.
예. 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에서 비슷한 것을 할 수 있다고 생각합니다.
예, 런타임을 통해 API를 통해 매핑을 작성하고 엔티티 클래스 대신지도를 사용할 수 있어야합니다.
다음 접근법이 유용 할 수 있습니다. 일부 외부 종류에 따라
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>
첫 번째와 세 번째는 차이가'이름을 가정하는 VARCHAR입니다 name' 선택'* 선택'와 사이에 같은 ... – Rudy
보인다. * 일 필요는 없지만, 1 열 이상 필요하다면 resultType은 map (또는 Pojo)이어야합니다. 1 열만 선택하는 경우 열 유형이 무엇이든 resultType을 설정하십시오. – AngerClown