从 java 应用程序执行批量插入数据库的不同方法
Posted
技术标签:
【中文标题】从 java 应用程序执行批量插入数据库的不同方法【英文标题】:Different ways of performing bulk insert into database from a java application 【发布时间】:2013-02-25 00:05:22 【问题描述】:我正在寻找从 Java 应用程序执行批量插入数据库(例如 SQL Server 2012)的不同方法。我需要非常有效地将大量实体插入数据库,而不需要像实体一样多地调用数据库。
我的要求是执行实体的批量插入,其中在数据库中插入实体可能涉及将数据插入到一个或多个表中。以下是我能想到的两种方式:
利用原生 JDBC 支持,动态生成一批 SQL 语句并针对数据库执行。
构造所有实体的 XML 表示,然后通过传递生成的 XML 调用存储过程。存储过程负责解析 XML 并将实体插入数据库。
我是 Java 新手,对可用框架没有足够的了解。 IMO,上述两种方法似乎非常幼稚,并且没有利用可用的框架。 请高手分享实现批量插入的不同方式及其优缺点。 我对MyBatis、Spring-MyBatis、Spring-JDBC、JDBC等持开放态度,可以高效解决问题方式。
谢谢。
【问题讨论】:
您可以尝试批量执行,如其中一个答案中发布的代码示例demo
所示,看看它是否对您来说足够快。
【参考方案1】:
你可以用JDBC自定义你的代码,没有框架支持你的要求
【讨论】:
【参考方案2】:我有一个演示,JDBC批处理 文件:demo.txt 内容
1899942 ,demo1 1899944,demo2 1899946,demo3 1899948,demo4
插入数据读取文件内容
我的代码:
public class Test2
public static void main(String[] args)
long start = System.currentTimeMillis();
String sql = "insert into mobile_place(number,place) values(?,?)";
int count=0;
PreparedStatement pstmt = null;
Connection conn = JDBCUtil.getConnection();
try
pstmt = conn.prepareStatement(sql);
InputStreamReader is = new InputStreamReader(new FileInputStream(new File("D:/CC.txt")),"utf-8");
BufferedReader br = new BufferedReader(is);
conn.setAutoCommit(false);
String s1 = null;
String s2 = null;
while(br.readLine() != null)
count++;
String str = br.readLine().toString().trim();
s1 = str.substring(0, str.indexOf(","));
s2 = str.substring(str.indexOf(",")+1,str.length());
pstmt.setString(1, s1);
pstmt.setString(2, s2);
pstmt.addBatch();
if(count%1000==0)
pstmt.executeBatch();
conn.commit();
conn.close();
conn = JDBCUtil.getConnection();
conn.setAutoCommit(false);
pstmt = conn.prepareStatement(sql);
System.out.println("insert "+count+"line");
if(count%1000!=0)
pstmt.executeBatch();
conn.commit();
long end = System.currentTimeMillis();
System.out.println("Total time spent:"+(end-start));
catch (Exception e)
e.printStackTrace();
finally
try
pstmt.close();
conn.close();
catch (SQLException e)
e.printStackTrace();
//getConnection()//get jdbc Connection
public static Connection getConnection()
try
Class.forName("com.mysql.jdbc.Driver");
catch (ClassNotFoundException e)
e.printStackTrace();
try
conn = DriverManager.getConnection(url, userName, password);
catch (SQLException e)
e.printStackTrace();
return conn;
第一次发言,希望能帮到你
我上面的demo使用PreparedStatement【读取数据调用一个PreparedStatement一次性插入】
JDBC批处理有3种方式 1.使用PreparedStatement 演示:
try
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(o_url, userName, password);
conn.setAutoCommit(false);
String sql = "INSERT adlogs(ip,website,yyyymmdd,hour,object_id) VALUES(?,?,?,?,?)";
PreparedStatement prest = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
for(int x = 0; x < size; x++)
prest.setString(1, "192.168.1.1");
prest.setString(2, "localhost");
prest.setString(3, "20081009");
prest.setInt(4, 8);
prest.setString(5, "11111111");
prest.addBatch();
prest.executeBatch();
conn.commit();
conn.close();
catch (SQLException ex)
Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);
2.使用 Statement.addBatch 方法 演示:
conn.setAutoCommit(false);
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
for(int x = 0; x < size; x++)
stmt.addBatch("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");
stmt.executeBatch();
conn.commit();
3.直接使用Statement 演示:
conn.setAutoCommit(false);
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
for(int x = 0; x < size; x++)
stmt.execute("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");
conn.commit();
使用上述方法插入100000条数据耗时: 方法 1:17.844s 方法 2:18.421s 方法3:16.359s
【讨论】:
这段代码似乎很有帮助,并且与问题相关,但我建议您编辑代码上方的行。不清楚你的意思是什么(demo1,demo2,...) JDBC批处理有2种方式 @demo:+1。如果您对 MyBatis 或 Spring 有任何经验,也请分享。【参考方案3】:高于 4.1 的 MS JDBC 版本具有 SQLServerBulkCopy 类,我认为它等同于 .Net 中可用的类,理论上它应该与 bcp 命令行实用程序一样快。 https://msdn.microsoft.com/en-us/library/mt221490%28v=sql.110%29.aspx
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。以上是关于从 java 应用程序执行批量插入数据库的不同方法的主要内容,如果未能解决你的问题,请参考以下文章