问题描述
select STUDENT_REGN from STUDENT where STUDENT_ROLL = :stRoll and STUDENT_ROLL_TYPE = :rType
用户最多可以给出 5 种不同的 student_roll
和 student_roll_type
组合,这些组合是唯一用来标识学生的。我想通过命名参数 jdbc 模板执行这个查询。
但问题是,对于 5 个不同的用户输入,我必须循环运行此查询 5 次。有没有一种方法可以在单个数据库调用中获取所有 5 种组合的记录以实现更好的性能?
我无法在我的代码中执行 select * 并过滤掉记录,因为该表有大量记录。 我也不允许在运行时构建动态查询。
解决方法
不容易。您可以编写 UNION,或者使用 IN
,或者使用括号和 AND
和 OR
:
select STUDENT_REGN from STUDENT where STUDENT_ROLL = :stRoll1
and STUDENT_ROLL_TYPE = :rType1
UNION
select STUDENT_REGN from STUDENT where STUDENT_ROLL = :stRoll2
and STUDENT_ROLL_TYPE = :rType2
...
有效,尽管您必须对“5 种组合”部分进行“硬编码”,并且您始终必须指定 10 个实际值(从 stRoll1
和 rType1
到 5),即使如果少于 5 个。另一种选择是您先编写一些代码来构造此查询。
可以使用类似的技巧代替 UNION:
select STUDENT_REGN from STUDENT where STUDENT_ROLL IN (:stRoll)
and STUDENT_ROLL_TYPE IN (:rType)
但是 [1] 这可能不是你想要的(任何 rType 和任何 stRoll 的任何组合都会匹配,我认为你想要所有匹配特定卷/类型组合的学生,而不是“任何卷是任何学生的学生” [2] 我不完全确定 jdbctemplate 是否能够将单个 ?
转换为多个 ?,?,?
缩放到列表输入的大小。
哪个叶子:
select STUDENT_REGN from STUDENT where
(STUDENT_ROLL = :stRoll1 and STUDENT_ROLL_TYPE = :rType1) OR
(STUDENT_ROLL = :stRoll2 and STUDENT_ROLL_TYPE = :rType2) OR
(STUDENT_ROLL = :stRoll3 and STUDENT_ROLL_TYPE = :rType3) OR
(STUDENT_ROLL = :stRoll4 and STUDENT_ROLL_TYPE = :rType4) OR
(STUDENT_ROLL = :stRoll5 and STUDENT_ROLL_TYPE = :rType5);
你也可以很容易地构造这个(记住,where false OR ...
也能工作,查询优化器不会被这个无意义的 or
减慢 - 因此给你一个简单的可以重复添加的简单字符串 (" OR (STUDENT_ROLL = :stRoll" + idx + " and STUDENT_ROLL_TYPE = :rType" + idx + ")"
)。