说我有两张桌子 :
ID ATTRIBUTE
------ -----------
1 'FOO'
2 'BAR'
4 'BIZZ'
ID ATTRIBUTE2
------ -----------
1 'FOO2'
2 'BAR2'
3 'BIZZ2'
现在我想获取所有这些属性。
我看到它的方式,我有两种方法,我可以查询两个表,一次查询一个ID,或者我可以查询两个表中的所有ID并通过结果集来提取属性。
选项1:
List<MyObj> myObjs = new ArrayList<MyObj>();
for (int i = 1; i<5; i++)
{
String sql1 = "select attribute from table1 where id = ?";
String sql2 = "select attribute2 from table2 where id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, i);
PreparedStatement ps2 = conn.prepareStatement(sql2);
ps2.setInt(1,i);
ResultSet rs1 = ps.executeQuery();
ResultSet rs2 = ps2.executeQuery();
myObjs.add(new MyObj(i, rs1.getString("attribute1"), rs2.getString("attribute2"));
//No null handling but.
}
选项2:
String sql1 = "select id, attribute from table1 where id in (?)";
String sql2 = "select id, attribute2 from table2 where id in (?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setArray(1, new ArrayList<Integer>(1,2,3,4,5);
PreparedStatement ps2 = conn.prepareStatement(sql2);
ps2.setArray(1, new ArrayList<Integer>(1,2,3,4,5);
ResultSet rs1 = ps.executeQuery();
ResultSet rs2 = ps2.executeQuery();
Hashmap<Integer,MyObj> myObjs = new HashMap<Integer, MyObj>();
while (rs.next())
{
myOjbs.add(rs.getInt("id")), new MyObj(rs.getInt("id"), rs.getString("attribute")));
}
while (rs2.next())
{
myObjs.get(rs2.getInt("id")).setAttribute2(rs2.getString("attribute2"))
}
选项1对于处理可能缺少其中一个属性的情况似乎要简单得多。但是,重复的SQL调用可能会重复数百万次。选项2具有较少的SQL调用,但需要处理列表可能不同步的情况。
问题是 - 这些解决方案中的一个显然是错误的吗?
答案 0 :(得分:1)
选项1假定两个查询在每次执行时都会返回结果。选项2假定第二个查询返回的每一行都对应于第一个查询返回的一行。这些都不是一个完全安全的假设。处理查询结果时,您的Java代码至少应检查这些条件,以便在必要时处理此类问题和/或优雅地拯救。
话虽如此,选项2可能比选项1更有效,但即使选项2似乎也缺少利用数据库功能的机会。为什么不通过一个查询返回所有数据?这可能是这样的:
select t1.id, t1.attribute, t2.attribute2
from table1 t1 join table2 t2 on t2.id = t1.id
where t1.id in (?)
通过确保返回的每一行都有attribute1
和attribute2
来解决我指出的一些问题。它不会为没有两者的id
返回任何行。如果您想诊断某些id
缺少一个属性或另一个属性的情况,那么用该外部联接的一种替换该查询中的(内部)联接将产生结果,该结果通知仅有的情况为特定id
提供了两个属性之一。
另请注意,您无法使用union [all]
执行此作业,因为这样您无法区分attribute1
值与attribute2
值,您的Java代码显示这些值你想做什么。
答案 1 :(得分:0)
如果要获取id,属性对,请使用一个查询:
select id, attribute from table1 where id in (?)
union all
select id, attribute2 from table2 where id in (?)
虽然性能问题的最佳答案是“使用您的数据在您的系统上试一试,看看会发生什么”,但有一些指导原则。更少的查询通常会更好,因为将数据输入和输出数据库会产生开销。