JdbcTemplate中向in语句传参
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语句传参的更多相关文章
- js中使用进行字符串传参
在js中拼接html标签传参时,如果方法参数是字符串需要加上引号,这里需要进行字符转义 <a href='javascript:addMenuUI("+"\"&qu ...
- python中导入一个需要传参的模块
最近跑实验,遇到了一个问题:由于实验数据集比较多,每次跑完一个数据集就需要手动更改文件路径,再将文件传到服务器,再运行实验,这样的话效率很低,必须要专门看着这个实验,啥时候跑完就手动修改运行下一个实验 ...
- requests中get和post传参
get请求 get(url, params=None, **kwargs) requests实现get请求传参的两种方式 方式一: import requests url = 'http://www. ...
- vue中组件间的传参
1.父传子 父组件准备一个数据,通过自定义属性给子组件赋值,进行传递 在子组件中通过 props 属性来接收参数 <body> <div id="app"> ...
- 使用python读取配置文件并从mysql数据库中获取数据进行传参(基于Httprunner)
最近在使用httprunner进行接口测试,在传参时,用到了三种方法:(1)从csv文件中获取:(2)在config中声名然后进行引用:(3)从函数中获取.在测试过程中,往往有些参数是需要从数据库中获 ...
- mybatis-sql语句传参
MyBatis中的映射语句有一个parameterType属性来制定输入参数的类型.但是parameterType属性只可以写一个参数,所以如果我们想给映射语句传入多个参数的话,我们可以将所有的输入参 ...
- vue-router中query和params传参(接收参数)以及$router、$route的区别
query传参: this.$router.push({ path:'/...' query:{ id:id } }) 接收参数:this.$route.query.id params传值: 传参: ...
- vue中this.$router.push() 传参
1 params 传参 注意⚠️:patams传参 ,路径不能使用path 只能使用name,不然获取不到传的数据 this.$router.push({name: 'dispatch', para ...
- ZZW_shell脚本中的调用MYSQL传参及注意的问题
[oracle@ip9140 db_pcc]$ cat zzw_cc.sh #!/bin/bash z_user='pcc_csuser22'z_pass='pcc_csuser22'z_db='db ...
随机推荐
- CSS初始化示例代码
CSS初始化示例代码 /* css reset www.admin10000.com */ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code, ...
- Y460 安装ubuntu 12.04系统黑屏,登录界面黑屏
ubuntu 12.04系统黑屏,登录界面黑屏,但是命令行界面可以登录,也可以正常使用,当时在装CVS,装完重启就这样了,可能是因为前一天装更新时,突然断电导致图形界面损坏,参考他人方法,终于修复,总 ...
- Linux 目录结构_004
前言 Linux文件系统层次标准,英文全称Filesystem Hierarchy Standard,英文简称FHS. 由于利用Linux来开发产品的团队和个人实在太多了,如果每个人都以自己的想法来配 ...
- 【转帖】oracle数据类型和对应的java类型
原文地址:http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/java.102/B19275-03/datacc.ht ...
- [Full-stack] 跨平台大框架 - RN
前言 React-Redux的大全栈代码复用理论有点意思,给出一个具体的例子:[React] 15 - Redux: practice IM 因为与react内容天然地部分重合,故这里将重点放在了对c ...
- [React] 15 - Redux: practice IM
本篇属于私人笔记. client 引导部分 一.assets: 音频,图片,字体 ├── assets │ ├── audios │ ├── fonts │ └── images 二.main&quo ...
- 05原型模式Prototype
一.什么是原型模式 Prototype模式是一种对象创建型模式,它采 取复制原型对象的方法来创建对象的实例.使用 Prototype模式创建的实例,具有与原型一样的 数据. 二.原型模式的特点 1. ...
- gitlab 服务器的搭建与使用全过程(一)
公司之前用的是vpn,然后老大说让我搞一个git.于是,我开始了git的研究之路.... 概念:(说实话,看了还是有些不太理解) git 是一种版本控制系统,是一个命令,是一种工具 g ...
- Orleans学习总结(五)--监控篇
上篇说完了Orleans学习总结(四)--集群配置篇,这次我们来说下监控 Orleans有一个强大的社区,为Orleans开发着各种各样的扩展工具,我们用的是OrleansDashboard.Dash ...
- C - 食物链
来源poj1182 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是 ...