【发布时间】:2025-12-19 00:25:01
【问题描述】:
美好的一天!我希望有人能够指出我正确的方向,或者能够指出什么 我可能做错了。
我对使用 Java 和 MySQL 还很陌生;更具体地说,使用 Java 在 MySQL 中进行数据库操作。
我用Java编写了附加的原型来解决以下问题:
给定一个表“邮寄”:
CREATE TABLE `mailing` (
ind INT AUTO_INCREMENT,
`addr` VARCHAR(255) NOT NULL,
PRIMARY KEY (ind)
);
邮件表最初是空的。每天都会添加新地址。预计该表将存储至少 10,000,000 个电子邮件地址和 100,000 个域。
编写一个程序来更新另一个表,该表按其域名保存每日电子邮件地址计数。
使用此表按过去 30 天与总数相比的百分比增长来报告排名前 50 的域。
** 注意 **
- 不应修改原始邮件表。
我几乎有一个解决方案,但我的解决方案产生了一个我无法解释的意外结果。以点的形式,这就是我正在做的事情:
- 如果 TempResult 表不存在,则创建一个。 TempResult 表在形式上与上面显示的原始“邮件”表相同。
- 接下来,我通过设置差异对“mailing”和“TempResult”执行查询,将“mailing”中发现的差异插入到 'TempResult'。
- 然后我对“TempResult”执行查询,解析提取域的每个电子邮件地址,并将结果插入到数组列表中。
- 解析完成后,我将每个唯一元素插入到哈希映射中,并增加 value 属性,从而计算出现次数。
-
下一步是遍历哈希映射,并将每个映射插入到数据库中的“结果”表中。结果表格式如下,仅在以前不存在时才创建。
CREATE TABLE `Result` ( ind INT AUTO_INCREMENT, `domain` VARCHAR(255), dailyCount INT, theDate DATE, primary key (ind) ); 最后,我执行查询以生成所需的最终输出。
这是我的问题。当我使用示例数据运行该程序时,“TempResult”和“Result”都不存在,程序正确执行,我得到了我期望的输出数据。但是,当我使用相同的数据再次运行它时,我的“结果”表显示重复记录和错误计数。当我执行 INSERT INTO 'Result' 时,我已将问题缩小到代码块,但我看不出我做错了什么。有人可以指出我哪里出错了吗?
提前谢谢你......如果这是一个菜鸟的错误,请原谅我。
迈克
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.*;
import java.time.*;
import java.util.*;
public class Test
{
public static void main(String[] args) throws Exception
{
String ConnectionURL = "jdbc:mysql://www.xxxxxxxx.ca:3306/Emails?autoReconnect=true&useSSL=false";
String user = "xxxxxxxxxxxx";
String password = "xxxxxxxxxxxxxxxx";
String driver = "com.mysql.jdbc.Driver";
Connection conn = null;
List<String> addresses = new ArrayList<String>();
//establish connection to DB
try
{
// The newInstance() call is a work around for some
// broken Java implementations
Class.forName(driver).newInstance();
}
catch (Exception ex)
{
// handle the error
System.out.println(ex.getMessage());
}
//connect to DB and perform queries
try
{
//get connection to the database 'Emails'
conn = DriverManager.getConnection(ConnectionURL, user, password);
conn.setAutoCommit(false);
//check to see if TempResult Table exists.
DatabaseMetaData metaOne = conn.getMetaData();
ResultSet metaDataOne = metaOne.getTables(null, null, "TempResult", null);
//Create temporary result table TempResult if not exists
if (!metaDataOne.next())
{
String queryOne = "CREATE TABLE TempResult (ind INT AUTO_INCREMENT, addr VARCHAR(255), PRIMARY KEY ( ind ))";
PreparedStatement statementOne = conn.prepareStatement(queryOne);
statementOne.executeUpdate();
conn.commit();
}
//Insert set difference between mailing and TempResult into TempResult
String queryTwo = "INSERT INTO TempResult (SELECT * FROM mailing e WHERE NOT EXISTS (SELECT * FROM TempResult t WHERE e.ind = t.ind))";
PreparedStatement statementTwo = conn.prepareStatement(queryTwo);
statementTwo.executeUpdate();
conn.commit();
//now read into memory table TempResult into an arraylist
//parse each email to obtain the domain of each email only
Statement queryThree = conn.createStatement();
ResultSet result = queryThree.executeQuery("SELECT addr FROM TempResult");
while (result.next())
{
String delimiter = "[@]";
String elements[] = result.getString("addr").split(delimiter);
addresses.add(elements[1]);
//System.out.println(result.getString("addr"));
}
queryThree.close();
result.close();
//now map the arraylist to a HashMap to create a 'dictionary' with counts on the domains.
int occurance;
int temp;
HashMap<String, Integer> domains = new HashMap<String, Integer>();
for (String a : addresses)
{
if(domains.containsKey(a))
{
temp = domains.get(a);
occurance = temp + 1;
domains.replace(a, occurance);
}
else
{
occurance = 1;
domains.put(a, occurance);
}
}
/* //for testing only
for (HashMap.Entry<String, Integer> entry : domains.entrySet())
{
System.out.println(entry.getKey() + " " + entry.getValue());
} */
//check to see if Result Table exists.
DatabaseMetaData metaTwo = conn.getMetaData();
ResultSet metaDataTwo = metaTwo.getTables(null, null, "Result", null);
//Create Result table if not exists
if (!metaDataTwo.next())
{
String queryFour = "CREATE TABLE Result (ind INT AUTO_INCREMENT, domain VARCHAR(255), dailyCount INT, theDate DATE, PRIMARY KEY ( ind ))";
PreparedStatement statementFour = conn.prepareStatement(queryFour);
statementFour.executeUpdate();
conn.commit();
}
//insert hashmap into Result table.
String queryFive = "INSERT INTO Result (ind, domain, dailyCount, theDate) VALUES (NULL, ?, ?, CURDATE())";
PreparedStatement statementFive = conn.prepareStatement(queryFive);
for (HashMap.Entry<String, Integer> entry : domains.entrySet())
{
statementFive.setString(1, entry.getKey());
statementFive.setInt(2, entry.getValue());
statementFive.executeUpdate();
conn.commit();
}
//Read Result table into memory and display to system console
Statement display = conn.createStatement();
String query = "SELECT domain, " +
" dailyCount / " +
" (SELECT " +
" SUM(dailyCount) " +
" FROM Result) " +
" * 100 " +
" AS PercentGrowth " +
" FROM Result " +
" WHERE theDate " +
" > DATE_SUB(CURDATE(), " +
" INTERVAL 1 MONTH) " +
" ORDER BY PercentGrowth " +
" DESC LIMIT 50 ";
ResultSet finalResult = display.executeQuery(query);
while (finalResult.next())
{
System.out.println(finalResult.getString("domain") + " " + finalResult.getString("PercentGrowth"));
}
finalResult.close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
finally
{
//close the connection to the database
conn.close();
}
}
}
【问题讨论】: