SQL 数据库未使用 execute/addBatch 通过 Java 填充
SQL database not populating via Java by using execute/addBatch
我目前有一个非常大的文件,其中包含几百万行条目,并希望将它们插入到数据库中。从 java 到 SQL 建立的连接有效,因为我尝试单独插入数据并且有效,但是,当我切换到使用 executeBatch
和 addBatch
时,它似乎虽然循环但没有将任何内容填充到我的数据库中。
代码如下:
import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
public class fedOrganiser6 {
private static String directory = "C:\Users\x\Desktop\Files\";
private static String file = "combined.fed";
private static String mapperValue = "";
public static void main(String[] args) throws Exception {
Connection conn = null;
try {
BufferedReader mapper = new BufferedReader(new FileReader(directory + file));
String dbURL = "jdbc:sqlserver://localhost\SQLExpress;database=TIMESTAMP_ORGANISER;integratedSecurity=true";
String user = "sa";
String pass = "password";
conn = DriverManager.getConnection(dbURL, user, pass);
if (conn != null) {
DatabaseMetaData dm = (DatabaseMetaData) conn.getMetaData();
System.out.println("Driver name: " + dm.getDriverName());
System.out.println("Driver version: " + dm.getDriverVersion());
System.out.println("Product name: " + dm.getDatabaseProductName());
System.out.println("Product version: " + dm.getDatabaseProductVersion());
System.out.println("clearing database");
conn.createStatement().executeUpdate("truncate table TimestampsStorage");
System.out.println("bulk insert into database");
System.out.println("complete");
int i = 0;
int records = 0;
String query = "INSERT INTO TimestampsStorage " + "values(" + "'" + mapperValue.toString() + "'"+ ")";
conn.prepareStatement(query);
for (mapperValue = mapper.readLine(); mapperValue != null; mapperValue = mapper.readLine()) {
i++;
records++;
System.out.println("Batching " + records + " records...");
conn.createStatement().addBatch(query);
if (i == 100000) {
conn.createStatement().executeBatch();
i = 0;
}
}
}
conn.createStatement().executeBatch();
conn.createStatement().close();
System.out.print("Done");
} catch (SQLException ex) {
ex.printStackTrace();
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
}
你正在丢弃准备好的语句
String query = "INSERT INTO TimestampsStorage VALUES (?)";
PreparedStatement statement = conn.prepareStatement(query);
for (mapperValue = mapper.readLine(); mapperValue != null; mapperValue = mapper.readLine()) {
i++;
records++;
System.out.println("Batching " + records + " records...");
statement.setString(1,mapperValue);
statement.addBatch();
if (i == 100000) {
statement.executeBatch();
i = 0;
}
createStatement()
创建一个新的语句对象,因此您执行的语句与您正在批处理的语句不同。您应该创建 PreparedStatement
一次,向其中添加几个批次,然后在同一个对象上执行:
String query = "INSERT INTO TimestampsStorage VALUES (?)";
PreparedStatement ps = conn.prepareStatement(query);
for (mapperValue = mapper.readLine();
mapperValue != null;
mapperValue = mapper.readLine()) {
i++;
records++;
System.out.println("Batching " + records + " records...");
ps.setString(1, mapperValue);
ps.addBatch();
if (i == 100000) {
ps.executeBatch();
i = 0;
}
}
我认为您对 JDBC 的批处理工作方式有点误解。
您每次调用 conn.createStatement()
时都会创建一个新的 Statement
。
相反,您需要使用 PreparedStatement
。首先,更改您的查询以在您希望值所在的位置包含 ?
。
String query = "INSERT INTO TimestampsStorage VALUES(?)";
然后,当您调用 conn.prepareStatement(query)
时,存储返回的 PreparedStatement
。
PreparedStatement ps = conn.prepareStatement(query);
此 PreparedStatement
然后将 'remember' 您的查询,您可以简单地更改您想要的值,其中 ?
在循环的每次迭代中。
ps.setString(1, mapperValue);
setString
方法将获取您的 mapperValue
并使用它来代替它在您的查询中找到的第一个 ?
(因为您传入了索引 1)。
那么,您可以调用 ps.addBatch()
.
,而不是调用 conn.createStatement().addBatch()
然后,在循环之外,您可以调用 ps.executeBatch()
。 (不需要在你的循环中调用它,所以你可以删除你的 if (i == 100000)
条件)。
最后,如果你使用的是Java 7+,你可以试试资源,这样你就不用担心关闭PreparedStatement
或Connection
在 finally 块中。
这是您的最终结果。
String query = "INSERT INTO TimestampsStorage VALUES (?)";
try (Connection con = DriverManager.getConnection(dbURL, user, pass); PreparedStatement ps = con.prepareStatement(query);) {
for (mapperValue = mapper.readLine(); mapperValue != null; mapperValue = mapper.readLine()) {
records++;
ps.setString(1, mapperValue);
ps.addBatch();
}
System.out.println("Executing batch of " + records + " records...");
ps.executeBatch();
} catch (SQLException ex) {
//handle exception
}
我目前有一个非常大的文件,其中包含几百万行条目,并希望将它们插入到数据库中。从 java 到 SQL 建立的连接有效,因为我尝试单独插入数据并且有效,但是,当我切换到使用 executeBatch
和 addBatch
时,它似乎虽然循环但没有将任何内容填充到我的数据库中。
代码如下:
import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
public class fedOrganiser6 {
private static String directory = "C:\Users\x\Desktop\Files\";
private static String file = "combined.fed";
private static String mapperValue = "";
public static void main(String[] args) throws Exception {
Connection conn = null;
try {
BufferedReader mapper = new BufferedReader(new FileReader(directory + file));
String dbURL = "jdbc:sqlserver://localhost\SQLExpress;database=TIMESTAMP_ORGANISER;integratedSecurity=true";
String user = "sa";
String pass = "password";
conn = DriverManager.getConnection(dbURL, user, pass);
if (conn != null) {
DatabaseMetaData dm = (DatabaseMetaData) conn.getMetaData();
System.out.println("Driver name: " + dm.getDriverName());
System.out.println("Driver version: " + dm.getDriverVersion());
System.out.println("Product name: " + dm.getDatabaseProductName());
System.out.println("Product version: " + dm.getDatabaseProductVersion());
System.out.println("clearing database");
conn.createStatement().executeUpdate("truncate table TimestampsStorage");
System.out.println("bulk insert into database");
System.out.println("complete");
int i = 0;
int records = 0;
String query = "INSERT INTO TimestampsStorage " + "values(" + "'" + mapperValue.toString() + "'"+ ")";
conn.prepareStatement(query);
for (mapperValue = mapper.readLine(); mapperValue != null; mapperValue = mapper.readLine()) {
i++;
records++;
System.out.println("Batching " + records + " records...");
conn.createStatement().addBatch(query);
if (i == 100000) {
conn.createStatement().executeBatch();
i = 0;
}
}
}
conn.createStatement().executeBatch();
conn.createStatement().close();
System.out.print("Done");
} catch (SQLException ex) {
ex.printStackTrace();
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
}
你正在丢弃准备好的语句
String query = "INSERT INTO TimestampsStorage VALUES (?)";
PreparedStatement statement = conn.prepareStatement(query);
for (mapperValue = mapper.readLine(); mapperValue != null; mapperValue = mapper.readLine()) {
i++;
records++;
System.out.println("Batching " + records + " records...");
statement.setString(1,mapperValue);
statement.addBatch();
if (i == 100000) {
statement.executeBatch();
i = 0;
}
createStatement()
创建一个新的语句对象,因此您执行的语句与您正在批处理的语句不同。您应该创建 PreparedStatement
一次,向其中添加几个批次,然后在同一个对象上执行:
String query = "INSERT INTO TimestampsStorage VALUES (?)";
PreparedStatement ps = conn.prepareStatement(query);
for (mapperValue = mapper.readLine();
mapperValue != null;
mapperValue = mapper.readLine()) {
i++;
records++;
System.out.println("Batching " + records + " records...");
ps.setString(1, mapperValue);
ps.addBatch();
if (i == 100000) {
ps.executeBatch();
i = 0;
}
}
我认为您对 JDBC 的批处理工作方式有点误解。
您每次调用 conn.createStatement()
时都会创建一个新的 Statement
。
相反,您需要使用 PreparedStatement
。首先,更改您的查询以在您希望值所在的位置包含 ?
。
String query = "INSERT INTO TimestampsStorage VALUES(?)";
然后,当您调用 conn.prepareStatement(query)
时,存储返回的 PreparedStatement
。
PreparedStatement ps = conn.prepareStatement(query);
此 PreparedStatement
然后将 'remember' 您的查询,您可以简单地更改您想要的值,其中 ?
在循环的每次迭代中。
ps.setString(1, mapperValue);
setString
方法将获取您的 mapperValue
并使用它来代替它在您的查询中找到的第一个 ?
(因为您传入了索引 1)。
那么,您可以调用 ps.addBatch()
.
conn.createStatement().addBatch()
然后,在循环之外,您可以调用 ps.executeBatch()
。 (不需要在你的循环中调用它,所以你可以删除你的 if (i == 100000)
条件)。
最后,如果你使用的是Java 7+,你可以试试资源,这样你就不用担心关闭PreparedStatement
或Connection
在 finally 块中。
这是您的最终结果。
String query = "INSERT INTO TimestampsStorage VALUES (?)";
try (Connection con = DriverManager.getConnection(dbURL, user, pass); PreparedStatement ps = con.prepareStatement(query);) {
for (mapperValue = mapper.readLine(); mapperValue != null; mapperValue = mapper.readLine()) {
records++;
ps.setString(1, mapperValue);
ps.addBatch();
}
System.out.println("Executing batch of " + records + " records...");
ps.executeBatch();
} catch (SQLException ex) {
//handle exception
}