這是CodingSir的帖子說的(由於不夠詳細,我現在提供給詳細的,上手即用):
Microsoft SQL Server 的bcp命令可以快速將大型文件復制插入到數據庫中,C#提供了SqlBulkCopy方法實現該功能,而在java中可以通過SQLServerBulkCopy類實現類似的功能,且相對於insert、update等命令來說,這個類的效率要高的多。(對比常用的JDBC的Batch方法也高的多)。
SQLServerBulkCopy類只能用於對SQL Sever數據庫的插入,但是數據來源可以不是SQL Sever數據庫。
舊版的Microsoft SQL Server JDBC 驅動並沒有提供這個類,需要下載Microsoft SQL Server JDBC 驅動程序 6.0版本:https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=11774
MS官方的說明文檔和下載架包在這個地址:https://docs.microsoft.com/en-us/sql/connect/jdbc/using-bulk-copy-with-the-jdbc-driver
SQLServerBulKCopy類向數據庫插入數據支持三種類型封裝的數據:Java本身提供的ResultSet、RowSet和JDBC提供的ISQLServerBulkRecord接口實現類。下面提供一種實現:
BaseDao代碼:
public class BaseDao { //驅動 private static String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; //數據庫地址 private static String url = "jdbc:sqlserver://127.0.0.1:1433;SelectMethod=cursor;DatabaseName=數據庫名字;"; //數據庫用戶名 private static String name = "sa"; //數據庫密碼 private static String password = "123456"; //數據庫連接,定義為全局變量,方便調用 private Connection con; //導入驅動,靜態代碼塊的作用為只運行一次,異常無法向上拋出,只能及時處理 static{ try{ Class.forName(driver); }catch (ClassNotFoundException e) { //打印異常相關信息 e.printStackTrace(); } } //無參構造方法,連接數據庫 public BaseDao () { try { con=DriverManager.getConnection(url,name,password); } catch (SQLException throwables) { throwables.printStackTrace(); } } //數據查找,返回查找的內容,向上拋異常 public ResultSet executeSQL (String sql,Object...object) throws SQLException{ PreparedStatement ps=con.prepareStatement(sql); for(int i=0;i<object.length;i++){ //ps傳入參數的下標是從1開始 ps.setObject(i+1,object[i]); } //返回結果集 return ps.executeQuery(); } //數據的增刪改,返回數據執行行數 public int executeUpdate(String sql,Object...object) throws SQLException { PreparedStatement ps=con.prepareStatement(sql); for(int i=0;i<object.length;i++){ ps.setObject(i+1,object[i]); } //返回int類型執行行數 return ps.executeUpdate(); } //關閉數據庫連接 public void close() throws SQLException{ con.close(); } }
下面的代碼,大家可以也封裝成工具類:
public static void main(String[] args) {
String url = "jdbc:sqlserver://127.0.0.1:1433;SelectMethod=cursor;DatabaseName=數據庫名字" + ";user=sa;password=123456"; //查詢出空值用於構建CachedRowSetImpl對象以省去列映射的步驟 BaseDao baseDao=new BaseDao(); ResultSet rs = baseDao.executeSQL("select * from curr where 1=0"); CachedRowSetImpl crs = new CachedRowSetImpl(); crs.populate(rs);
//既然是批量插入肯定是需要循環
for(int i=0;i<執行的次數;i++){ //移動指針到“插入行”,插入行是一個虛擬行 crs.moveToInsertRow(); //更新虛擬行的數據(實體類要新增的字段,大家根據自己的實體類的字段來修改)
//數據庫字段 ,填寫的值 crs.updateString("monetary_code", "014");//string類型的值 crs.updateString("curr_code", "CNY"); crs.updateString("name", "人民幣");
//別的類型的值,自己看api,基本上都是crs.update***這樣的 //crs.updateInt("curr_code", 2);//int類型的值
//插入虛擬行 crs.insertRow(); //移動指針到當前行 crs.moveToCurrentRow();
}
//進行批量插入 SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions(); copyOptions.setKeepIdentity(true); copyOptions.setBatchSize(8000); copyOptions.setUseInternalTransaction(true); SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(url); bulkCopy.setBulkCopyOptions(copyOptions); bulkCopy.setDestinationTableName("curr"); bulkCopy.writeToServer(crs); crs.close(); bulkCopy.close();
}
感想:由於大牛對小白關照細節不到位,所以決定寫篇詳細的給你們,節省大家的時間。不喜勿噴