MyBatis 传参分析

传入参数

MyBatis 容许两种方式的使用:经过定义接口,或经过 SqlSession 调用命名空间。这二者的传参方式不一样,前者通过 MyBatis 处理后变为后者。后者更直接,当须要传入多个参数时要本身构建 Mapjava

当使用接口时,会执行如下步骤:sql

Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.<E>selectList(command.getName(), param);

Object convertArgsToSqlCommandParam (Object[] args) 有如下规则:json

  • 传入 null 或空数组,返回 null;
  • 没有使用 @Param 注解,且数组里只有一个对象,返回该对象;
  • 不然返回 Map<String, Object>

第三种状况下,Map<String, Object> 的数据首先根据 paramsargs 里取。params 是一个 Map<Integer, String>,存储了形参的顺序和名字,名字的规则是:数组

  • @Param 注解,使用注解的 value
  • 不然,使用形参顺序

例如:ide

List<Entity> select(@Param("group") String groupName, Long offset, Integer limits);

对应的 params(使用 json 格式以便观察):code

{
    "0": "group",
    "1": "1",
    "2": "2",
}

注意到只要不带 @Param 注解,就须要使用下标了。xml

这尚未结束,为了方便容许使用下标,MyBatis 还按 params 顺序设置了另外一组值,使得输出的结果相似于:对象

{
    "group": "xxx",
    "1": 0,
    "2": 20,
    "param0": "xxx",
    "param1": 0,
    "param2": 20,
}

固然了,若是你手动指定的参数名刚好为 param<Index> 以致于跟这条规则重复了,那么 MyBatis 会跳过已经存在的键。接口

无论是 selectOne 仍是 selectMap 方法,都是经过 selectList 执行查询的,无论是 insert 仍是 delete 方法,都是经过 update 方法执行的。get

selectListupdate 中,对全部参数的都进行了统一的处理。

对于集合,默认使用 DefaultSqlSession::wrapCollection 处理:

private Object wrapCollection(final Object object) {
    if (object instanceof Collection) {
        StrictMap<Object> map = new StrictMap<Object>();
        map.put("collection", object);
        if (object instanceof List) {
            map.put("list", object);
        }
        return map;      
    } else if (object != null && object.getClass().isArray()) {
        StrictMap<Object> map = new StrictMap<Object>();
        map.put("array", object);
        return map;
    }
    return object;
}

使用参数

  • 标准处理(如 #{value}#{object.value}
  • 使用 OGNL 方式获取值(如 ${orderby}
  • 使用在条件语句中(如 <if test="object.value != null">

这里咱们注意到可使用复杂类型,因而咱们能够写出很是灵活的动态 SQL,好比:

<update id="update">
    UPDATE `Sample`
    <set>
        <if test="set.name != null">
            `name`=#{set.name},
        </if>
        <if test="set.value != null">
            `value`=#{set.value},
        </if>
    </set>
    <trim prefix=" WHERE " prefixOverrides="AND">
        <if test="where.id != null">
            AND `id`=#{where.id}
        </if>
        <if test="where.name != null">
            AND `name`=#{where.name}
        </if>
    </trim>
    ;
</update>
相关文章
相关标签/搜索