jdbcTemplate中向in语句传参

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

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

首先创建实体类Employee:

1 public class Employee {
2     private Long id;
3     private String name;
4     private String dept;
5     // omit toString, getters and setters
6 }

使用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方式进行参数的匹配。

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 6。

查询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;
}

欢迎拍砖。

原文地址:https://www.cnblogs.com/east7/p/9762742.html

时间: 2024-08-05 16:58:55

jdbcTemplate中向in语句传参的相关文章

vue中组件间的传参

1.父传子 父组件准备一个数据,通过自定义属性给子组件赋值,进行传递 在子组件中通过 props 属性来接收参数 <body> <div id="app"> <son passdata="msg"></son> </div> </body> <script> Vue.component('son', { template: '<div>父组件的数据为:{{ passdat

mybatis-sql语句传参

MyBatis中的映射语句有一个parameterType属性来制定输入参数的类型.但是parameterType属性只可以写一个参数,所以如果我们想给映射语句传入多个参数的话,我们可以将所有的输入参数放到HashMap中,将HashMap传递给映射语句. 其实就是把多个参数存到Map中,把Map当做一个参数再传给sql语句,mybaits收到后再解析Map集合拿到每一个参数. 例如: <select id="searchCourses" parameterType="

函数中对象名的传参形式

1. function setNumber($this,g,d,url){ var gid = $this.parent().attr("data-id"); var eids = $("#hidden").text(); var params = {}; params[g] = gid; //传参 params[d] = eidsl;//传参 if(eids==""){ layer.alert("勾选项为空,请选择"); r

Asp.Net中ObjectDataSource控件传参绑定数据

最近在实习,在上头交付的任务中,由于需要使用Asp.Net的ListView控件,因此必然得就使用了ObjectDataSource控件,由于在使用过程中,需要网页中的参数发送到后台后,运行该参数进行查询数据.这过程必然就牵涉到将参数传送给ObjectDataSource控件,然后在进行查询后的数据绑定.下面我们来看下这个过程是如何实现的: 1.创建一个WebForm页面,拖入ListView控件和ObjectDataSource控件 2.配置ObjectDataSource数据源按照以下步骤进

iOS中html打开APP传参

1.在项目info.plist中添加URL Types以供html调用 2.html代码 <html> <head lang="en"> <meta charset="UTF-8"> <title>支付页面</title> </head> <script type="text/javascript"> var url = location.search; //获取

C/C++语言中的函数参数传参三种对比

学了很长时间C/C++有时指针方面还是有点乱. 希望大神发现如果下面有不对的地方请指出.我发现之所以我乱就是因为中文表述不准确的问题,比如 ,地址值和地址 #include <iostream> #include <string> using namespace std; void swap1(string* str1,string* str2){// 1.对象指针作为函数参数 //影响实参 cout<<&str1<<" "<

java 在方法中新建线程,传参和加锁详解

在实际开发中,往往在基本两三种创建线程的方法之外,还用到一个简单的创建线程调用方法的情况,代码如下: public void deleteRedisData(RedisKey redisKey){ new Thread(new Runnable() { @Override public void run() { deleteRedisByRedisKey(redisKey); } }).start(); } protected synchronized void deleteRedisByRed

elementUi中的计数器ele-mumber中的change事件传参及事件调用

业务场景是需要在点击业务工作量的时候设置任务工作量这一项的评分不能大于任务质量及任务时限的权重之和除以二 上代码 JS逻辑代码 因出现弹出层提示后设置输入框的值如果大于sum的值,设置输入的值为sum,但是出现了让input输入的值只能变成sum一次,之后再输入值也不改变,属性值没有响应式了 故用setTimeout定时器等页面全部加载完成后调用定时器,设置输入框的值等于sum 原文地址:https://www.cnblogs.com/jiajialove/p/10739719.html

Mybatis 中在传参时,${} 和#{} 的区别

介绍 MyBatis中使用parameterType向SQL语句传参,parameterType后的类型可以是基本类型int,String,HashMap和java自定义类型. 在SQL中引用这些参数的时候,可以使用两种方式#{parameterName}或者${parameterName}. #{} #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号. 例如:order by #{parameterName} //或取Map中的value#{Key}也是一样操作. 假设传入参数是“