spring jdbc包提供了JdbcTemplate和它的两个兄弟SimpleJdbcTemplate和NamedParameterJdbcTemplate,我们先从JdbcTemplate入手,

引入问题,领略一下类NamedParameterJdbcTemplate在处理where中包含in时的便利和优雅。

首先创建实体类Employee:

 public class Employee {
private Long id;
private String name;
private String dept;
// omit toString, getters and setters
}

使用JdbcTemplate访问一批数据

比较熟悉的使用方法如下:

public List<Employee> queryByFundid(int fundId) {
String sql = "select * from employee where id = ?";
Map<String, Object> args = new HashMap<>();
args.put("id", 32);
return jdbcTemplate.queryForList(sql, args , Employee.class );
}

但是,当查询多个部门,也就是使用in的时候,这种方法就不好用了,只支持Integer.class String.class 这种单数据类型的入参。如果用List匹配问号,你会发现出现这种的SQL:

select * from employee where id in ([1,32])

执行时一定会报错。解决方案——直接在Java拼凑入参,如:

String ids = "3,32";
String sql = "select * from employee where id in (" + ids +")";

如果入参是字符串,要用两个''号引起来,这样跟数据库查询方式相同。示例中的入参是int类型,就没有使用单引号。但是,推荐使用NamedParameterJdbcTemplate类,然后通过: ids方式进行参数的匹配。

使用NamedParameterJdbcTemplate访问一批数据

public List<Employee> queryByFundid(int fundId) {
String sql = "select * from employee where id in (:ids) and dept = :dept"; Map<String, Object> args = new HashMap<>();
args.put("dept", "Tech");
List<Integer> ids = new ArrayList<>();
ids.add(3);
ids.add(32);
args.put("ids", ids);
NamedParameterJdbcTemplate givenParamJdbcTemp = new NamedParameterJdbcTemplate(jdbcTemplate);
List<Employee> data = givenParamJdbcTemp.queryForList(sql, args, Employee.class);
return data;
}

如果运行以上程序,会采坑,抛出异常:org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorrect column count: expected 1, actual 3。

抛出此异常的原因是方法queryForList 不支持多列,但是,API(spring-jdbc-4.3.17.RELEASE.jar)并未说明。请看queryForList 在JdbcTemplate的实现:

public <T> List<T> queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType)
throws DataAccessException {
return query(sql, paramSource, new SingleColumnRowMapper<T>(elementType));
} /**
* Create a new {@code SingleColumnRowMapper}.
* <p>Consider using the {@link #newInstance} factory method instead,
* which allows for specifying the required type once only.
* @param requiredType the type that each result object is expected to match
*/
public SingleColumnRowMapper(Class<T> requiredType) {
setRequiredType(requiredType);
}

查询API发现,需要换一种思路,代码如下:

public List<Employee> queryByFundid(int fundId) {
String sql = select * from employee where id in (:ids) and dept = :dept Map<String, Object> args = new HashMap<>();
args.put("dept", "Tech");
List<Integer> ids = new ArrayList<>();
ids.add(3);
ids.add(32);
args.put("ids", ids);
NamedParameterJdbcTemplate givenParamJdbcTemp = new NamedParameterJdbcTemplate(jdbcTemplate);
List<Employee> data = givenParamJdbcTemp.jdbc.query(sql, args, new RowMapper<Employee>() {
@Override
public Employee mapRow(ResultSet rs, int index) throws SQLException {
Employee emp = new Employee();
emp.setId(rs.getLong("id"));
emp.setName(rs.getString("name"));
emp.setDept(rs.getString("dept"));
return emp;
}
});
    return data;
}

欢迎拍砖。

JdbcTemplate中向in语句传参的更多相关文章

  1. js中使用进行字符串传参

    在js中拼接html标签传参时,如果方法参数是字符串需要加上引号,这里需要进行字符转义 <a href='javascript:addMenuUI("+"\"&qu ...

  2. python中导入一个需要传参的模块

    最近跑实验,遇到了一个问题:由于实验数据集比较多,每次跑完一个数据集就需要手动更改文件路径,再将文件传到服务器,再运行实验,这样的话效率很低,必须要专门看着这个实验,啥时候跑完就手动修改运行下一个实验 ...

  3. requests中get和post传参

    get请求 get(url, params=None, **kwargs) requests实现get请求传参的两种方式 方式一: import requests url = 'http://www. ...

  4. vue中组件间的传参

    1.父传子 父组件准备一个数据,通过自定义属性给子组件赋值,进行传递 在子组件中通过 props 属性来接收参数 <body> <div id="app"> ...

  5. 使用python读取配置文件并从mysql数据库中获取数据进行传参(基于Httprunner)

    最近在使用httprunner进行接口测试,在传参时,用到了三种方法:(1)从csv文件中获取:(2)在config中声名然后进行引用:(3)从函数中获取.在测试过程中,往往有些参数是需要从数据库中获 ...

  6. mybatis-sql语句传参

    MyBatis中的映射语句有一个parameterType属性来制定输入参数的类型.但是parameterType属性只可以写一个参数,所以如果我们想给映射语句传入多个参数的话,我们可以将所有的输入参 ...

  7. vue-router中query和params传参(接收参数)以及$router、$route的区别

    query传参: this.$router.push({ path:'/...' query:{ id:id } }) 接收参数:this.$route.query.id params传值: 传参: ...

  8. vue中this.$router.push() 传参

    1  params 传参 注意⚠️:patams传参 ,路径不能使用path 只能使用name,不然获取不到传的数据 this.$router.push({name: 'dispatch', para ...

  9. ZZW_shell脚本中的调用MYSQL传参及注意的问题

    [oracle@ip9140 db_pcc]$ cat zzw_cc.sh #!/bin/bash z_user='pcc_csuser22'z_pass='pcc_csuser22'z_db='db ...

随机推荐

  1. Loadrunner C/S关联函数(LSP)AND(LSSS)使用-案例

    LSP就是lrs_save_param()函数 LSSS就是lrs_save_searched_string()函数 一下我们用一个例子去说明他们的使用. C/S机制和B/S不一样,特别是有一个dat ...

  2. Android KK 找不到<cutils/properties.h>

    一直通过property来控制android系统的号码匹配位数,之前的项目都工作的好好的,但到了KK时,在sqlite库中引用property的相关方法,却一直编译error... 折腾了好久,发现从 ...

  3. greendao引起的NoClassDefFoundError异常解决

    在使用Android studio导入eclipse工程师报错,因为原工程引用了greendao的第三方工程包 java.lang.NoClassDefFoundError: org.greenrob ...

  4. Tomcat 7.0安装与配置

    下载后解压缩到C盘,重命名为Tomcat-7.0.67,目录最好不要有空格: 以下为Tomcat 7的配置: 首先,右键计算机–>属性–>高级系统设置–>环境变量:  下载好压缩包后 ...

  5. OpenGL 太阳系行星拾取例子(GL_SELECT) VS2008 + glut实现

    太阳系:Solar System 以太阳(Sun)为中心,由内到外分别是: 水星(Mercury) 金星(Venus) 地球(Earth) 火星(Mars) 木星(Jupiter) 土星(Saturn ...

  6. [Model] ResNet

    ResNet引入了残差网络结构(residual network),通过残差网络,可以把网络层弄的很深,据说现在达到了1000多层,最终的网络分类的效果也是非常好 Ref: http://blog.c ...

  7. [Full-stack] 异步即时通信 - Async

    故事背景 socket.io, node.js, koa为首的一些通信框架和后端技术点. 之后有必要过一遍<NodeJS 设计模式>. 基础概念 一.短轮询.长轮询(comet).长连接( ...

  8. sklearn中的回归器性能评估方法

    explained_variance_score() mean_absolute_error() mean_squared_error() r2_score() 以上四个函数的相同点: 这些函数都有一 ...

  9. js函数作用域

    函数 1.函数没有用return返回函数时,返回默认参数undefined 结果 return返回得话 就是里面得数值 结果 JS执行过程是上到下,下面的a元素覆盖了上面的a元素 function d ...

  10. 利用python对微信自动进行消息推送

    from wxpy import * #该库主要是用来模拟与对接微信操作的 import requests from datetime import datetime import time impo ...