MyBatis 不定个数参数查询

本贴最后更新于 2449 天前,其中的信息可能已经时异事殊

概述

某些情况下,比如要查询某几个 key 的 value 时,需要用 where id in () 进行查询,传入的参数不确定个数时,MyBatis 的可以进行特别的配置。

基于 XML 文件配置

利用 XML 的 foreach 标签,可以很简易的配置。传入的参数名可以为一个 List,利用 foreach 拼接成 SQL。如:

<select id="testSearch" resultType="String"> 
    select value from t_test where id in 
    <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> 
        #{item} 
    </foreach> 
</select> 

测试代码:

List<String> ids = new ArrayList<String>(); 
ids.add("test1"); 
ids.add("test7"); 
ids.add("test3"); 
List<String> testBeans = testMapper.testSearch(ids); 

基于注解 Annotation 配置

使用注解配置的 Mapper 需要使用 SelectProvider 来构造 SQL。Mapper 示例如下:

import org.apache.ibatis.annotations.SelectProvider;

@SelectProvider(type = TestSelectProviderSQL.class, method = "testSearch")
List<String> testSearch(String... ids);

TestSelectProviderSQL 类就是用来提示查询所用的 SQL,代码如下:

import org.apache.ibatis.jdbc.SQL;
import java.util.Map;
public class TestSelectProviderSQL {
    public String testSearch(Map<String, Object> params) {
        final StringBuffer whereSb = new StringBuffer();
        whereSb.append(" id in (");

        String[] values = ((String[]) params.get("array"));
        for (int i = 0, size = values.length; i < size; i++) {
            if (i == 0) {
                whereSb.append("#{values" + i + "}");
                params.put("values" + i, values[i]);
            } else {
                whereSb.append(",#{values" + i + "}");
                params.put("values" + i, values[i]);
            }
        }
        whereSb.append(")");

        return new SQL() {
            {
                SELECT("value");
                FROM("t_test");
                WHERE(whereSb.toString());
            }
        }.toString();
    }
}

testSearch 参数通过一个 Map 注入,在 Mapper 中传入的参数为一个变长参数,Mapper 对应接收的参数在 key=array 中是一个 String 数组。依次取出数组的各个值进行拼接就可以了。调用的测试示例如下:

List<String> testBeans = testMapper.testSearch("test1","test7","test3"); 

如果 Mapper 中使用普通的参数,如 List<String> testSearch(String id1, String id2); 则在 SelectProvider 类中的 Map 数组接收到的值为如下表:

key value
0 id1的值
1 id2的值
params1 id1的值
params2 id2的值

使用 params.get(0) 或者 params.get("params1") 皆可以取出传入的值。需要注意的是,Map 的大小是传入参数个数的两倍。

附:排序

我们都知道,这样 where id in () 查出来的顺序和传入的 ID 顺序是不会一一对应的。对于查询结果的可靠性,我们需要按传入参数 ids 的顺序返回需要的值。对于 SQL 语句可使用如下:

select value from t_test where id in ('test1','test7','test3')
order by field(id,'test1','test7','test3')

这里取基于 Annotation 方式的方法对程序进行简单改造,示例如下:

import org.apache.ibatis.jdbc.SQL;
import java.util.Map;
public class TestSelectProviderSQL {
    public String testSearch(Map<String, Object> params) {
        final StringBuffer whereSb = new StringBuffer();
        final StringBuffer orderSb = new StringBuffer();
        whereSb.append(" id in (");
        orderSb.append("field(`key`");

        String[] values = ((String[]) params.get("array"));
        for (int i = 0, size = values.length; i < size; i++) {
            if (i == 0) {
                whereSb.append("#{values" + i + "}");
                params.put("values" + i, values[i]);
            } else {
                whereSb.append(",#{values" + i + "}");
                params.put("values" + i, values[i]);
            }
        }
        whereSb.append(")");
        orderSb.append(")");

        return new SQL() {
            {
                SELECT("value");
                FROM("t_test");
                WHERE(whereSb.toString());
                ORDER_BY(orderSb.toString());
            }
        }.toString();
    }
}

参考

  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 431 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3167 引用 • 8207 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...