有没有办法使用Ibatis / MyBatis动态选择/更新/删除?
当我说“动态”时,这意味着我根本不想创建任何POJO / DataMapper。
欢迎任何网址示例。
答案 0 :(得分:8)
是的,只需将resultType
属性设置为map
,表格数据将放入列名称的HashMap中。如果查询返回多于1行,则映射的行将放入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中做类似的事情。
答案 1 :(得分:2)
以下方法可能很有用。 比如说,你有一些通用的选择界面,比如:
add_filter( 'authenticate', 'chk_active_user',100,2);
function chk_active_user ($user,$username)
{
$user_data = $user->data;
$user_id = $user_data->ID;
$user_sts = get_user_meta($user_id,"user_active_status",true);
if ($user_sts==="no")
{
return new WP_Error( 'disabled_account','this account is disabled');
}
else
{
return $user;
}
return $user;
}
根据某些外部类型(例如,单列或日期范围或范围),您可以在模板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
你从mybatis收到的是java.util.Map。然后你就可以使用它了:
<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>
其中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;
}
}
此外,您可以定义一些WhereStmt,如:
@Getter
public class SetParameter extends Parameter {
/**
* Column in sql query,
*/
private final String column;
public SetParameter(String column) {
super(StmtType.set);
this.column = column;
}
}
最后,在mybatis generic 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;
}
中,你可以使用它:
Common.xml
并将sql语句组合为模板,例如:
<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>
答案 2 :(得分:0)
是的,应该可以通过API在运行时构建映射,并使用Maps而不是实体类。
答案 3 :(得分:0)
是的,您可以不使用POJO进行选择/更新/删除。 在myBatis中,您可以使用Mapper XML编写查询,并设置将从SQL语句返回的resultType并将其存储在对象中。
例如,
<mapper namespace = "data">
<select id = "fetch" resultType = "java.util.HashMap">
select * from table_name
</select>
</mapper>
您可以使用“地图列表”存储这些结果。
List<Map<String,Object>> results = session.selectList("data.fetch");