這是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();
}
感想:由於大牛對小白關照細節不到位,所以決定寫篇詳細的給你們,節省大家的時間。不喜勿噴
