Arraylist 中的数据重复
Data duplicates in Arraylist
我想用从我的数据库中选择的数据填充我的 ArrayList,但它复制了我不明白的所有行。
Connection conn = DriverManager.getConnection(url, userid, password);
String strSql = "SELECT * FROM events, eventStats" ;
PreparedStatement Stmt = conn.prepareStatement(strSql);
ResultSet rs = Stmt.executeQuery(strSql);
while(rs.next()){
Events user = new Events();
user.seteName(rs.getString(2));
user.setePlace(rs.getString(4));
user.seteDate(rs.getString(5));
user.seteInscrit(String.valueOf(rs.getInt(8)));
user.seteTotal(String.valueOf(rs.getFloat(10)));
data.add(user);
}
感谢您的帮助!
您实际上并没有看到严格意义上的 'duplicate' 行。
您看到的是 笛卡尔积,它是一个 table 中的每一行都连接到 每一行 在另一个 table 中。你得到这个是因为你在你的 SQL 语句中有一个笛卡尔连接(或者 cross-join 如果你愿意):
SELECT * FROM events, eventStats
-- ^^^^^^^^^^^^^^^^^^
这意味着对于 events
table 中的每一行,您将获得与 eventStats
table 中的行数相等的结果数。将所有这些加在一起,看起来很多重复项实际上是来自两个 table 的所有行的潜在大量独特组合集中在一起。
有 select 种场景需要笛卡尔连接,但它通常是错误查询的指示器,如果其中一种 tables特别大1
为避免这种情况,您需要指定每个 table 中的哪一列用于将两个 table 连接在一起,或者通过显式连接:
SELECT *
FROM events v
[INNER|LEFT OUTER|RIGHT OUTER] JOIN eventStats s
ON v.SomeColumn = s.SomeMatchingColumn
或隐含的:
SELECT *
FROM events v, eventStats s
WHERE v.SomeColumn = s.SomeMatchingColumn
如果没有看到 table 结构,很难告诉您更多信息,但这两个 table 之间可能存在外键关系,这就是您要加入的列上。
1 笛卡尔连接的行数 return 等于 tables 参与连接。例如,假设 events
table 包含 50,000 行,eventStats
table 也有 50,000 行,每个 event
一个。通过对这些 table 进行笛卡尔连接,您的查询将 return 达到惊人的 2,500,000,000,是的,即 2.5 亿 ,数据行。现在想象将所有这些读入 ArrayList
... 除了你不能,因为 Java 数组不能变得那么大!在您读取所有数据之前,您的应用程序将崩溃并显示 java.lang.OutOfMemoryError: Requested array size exceeds VM limit
或 java.lang.OutOfMemoryError: Java heap space
。
我想用从我的数据库中选择的数据填充我的 ArrayList,但它复制了我不明白的所有行。
Connection conn = DriverManager.getConnection(url, userid, password);
String strSql = "SELECT * FROM events, eventStats" ;
PreparedStatement Stmt = conn.prepareStatement(strSql);
ResultSet rs = Stmt.executeQuery(strSql);
while(rs.next()){
Events user = new Events();
user.seteName(rs.getString(2));
user.setePlace(rs.getString(4));
user.seteDate(rs.getString(5));
user.seteInscrit(String.valueOf(rs.getInt(8)));
user.seteTotal(String.valueOf(rs.getFloat(10)));
data.add(user);
}
感谢您的帮助!
您实际上并没有看到严格意义上的 'duplicate' 行。
您看到的是 笛卡尔积,它是一个 table 中的每一行都连接到 每一行 在另一个 table 中。你得到这个是因为你在你的 SQL 语句中有一个笛卡尔连接(或者 cross-join 如果你愿意):
SELECT * FROM events, eventStats
-- ^^^^^^^^^^^^^^^^^^
这意味着对于 events
table 中的每一行,您将获得与 eventStats
table 中的行数相等的结果数。将所有这些加在一起,看起来很多重复项实际上是来自两个 table 的所有行的潜在大量独特组合集中在一起。
有 select 种场景需要笛卡尔连接,但它通常是错误查询的指示器,如果其中一种 tables特别大1
为避免这种情况,您需要指定每个 table 中的哪一列用于将两个 table 连接在一起,或者通过显式连接:
SELECT *
FROM events v
[INNER|LEFT OUTER|RIGHT OUTER] JOIN eventStats s
ON v.SomeColumn = s.SomeMatchingColumn
或隐含的:
SELECT *
FROM events v, eventStats s
WHERE v.SomeColumn = s.SomeMatchingColumn
如果没有看到 table 结构,很难告诉您更多信息,但这两个 table 之间可能存在外键关系,这就是您要加入的列上。
1 笛卡尔连接的行数 return 等于 tables 参与连接。例如,假设 events
table 包含 50,000 行,eventStats
table 也有 50,000 行,每个 event
一个。通过对这些 table 进行笛卡尔连接,您的查询将 return 达到惊人的 2,500,000,000,是的,即 2.5 亿 ,数据行。现在想象将所有这些读入 ArrayList
... 除了你不能,因为 Java 数组不能变得那么大!在您读取所有数据之前,您的应用程序将崩溃并显示 java.lang.OutOfMemoryError: Requested array size exceeds VM limit
或 java.lang.OutOfMemoryError: Java heap space
。