Reputation: 47
I need help with a batch operation for select queries in NamedParameterJdbcTemplate
. I have a List
of employees having id
and name
, against which I need the unique list of employee's project codes and ultimately it will add to the final list of all projects from all employees.
My source code:
//input = List<Employee> employee
String sql = "Select project_name from employee where id = :id and name = :name";
RowMapper<String> rowMapper = (rs, rowNum) ->
{
String s = rs.getString("project_name");
return s;
};
MapSqlParameterSource params;
List<String> finalProjectList = new ArrayList<String>();
List<String> employeeProjectList = null;
for(Employee e : employee)
{
params = new MapSqlParameterSource();
employeeProjectList = new ArrayList<String>();
params.addvalue("id",e.getId());
params.addvalue("name",e.getName());
employeeProjectList = namedParameterJdbcTemplate.query(sql, params, rowMapper);
finalProjectList.addAll(employeeProjectList);
}
Note: Please answer for select queries without IN clause and not for update or insert operations. I am aware that for updates and inserts there is a batchUpdate method provided by NamedParameterJdbcTemplate
.
Upvotes: 0
Views: 1395
Reputation: 81862
Unfortunately you don't really tell us what your problem is. But there are a couple of things that seem problematic.
finalProjectList.addAll(finalProjectList)
is just a fancy NOOP, since finalProjectList
is empty and will stay that way. Should this be finalProjectList.addAll(employeeProjectList)
?
You are running the same statement multiple times in a tight loop. It's probably more efficient to turn that in a single statement or at least way less then you have currently. This can be done by combining multiple copies of the select statement using UNION
or if you know they are distinct UNION ALL
. Of course you'll have to change the parameter names, so they are unique.
Alternatively you could use an IN-clause. I know you explicitly asked for solutions without IN, but you have that above and you didn't give a reason, so I'm going to ignore that constraint for this section. The challenge is that you have two arguments to filter on. That in itself seems strange, since one of the parameters is called id
which suggests it should be unique. The following solution assumes that there is a character that you can guarantee that it doesn't appear in id
. I use _
and an example. Then the following statement should do the trick:
SELECT project_name
FROM employee
WHERE id IN :ids
AND CONCAT(id, name) IN :idnames
The query parameter ids
and idnames
would then need to be set to a collection of id
values a the concatenation id + "_" + name
. The first IN
will limit the number of rows to be processed by the second IN and hopefully use an index, while the second can't use an index but does the correct filtering.
Since you are only selecting a single column you may use queryForList
or queryForObject
and drop the RowMapper
.
Upvotes: 1