31°

Java使用SQLServerBulKCopy实现批量插入SQLSqerver数据库

这是的帖子说的(由于不够详细,我现在提供给详细的,上手即用):

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";
</span><span style="color: #008000;">//</span><span style="color: #008000;">数据库地址</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> String url = "jdbc:sqlserver://127.0.0.1:1433;SelectMethod=cursor;DatabaseName=数据库名字;"<span style="color: #000000;">;

</span><span style="color: #008000;">//</span><span style="color: #008000;">数据库用户名</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> String name = "sa"<span style="color: #000000;">;

</span><span style="color: #008000;">//</span><span style="color: #008000;">数据库密码</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> String password = "123456"<span style="color: #000000;">;

</span><span style="color: #008000;">//</span><span style="color: #008000;">数据库连接,定义为全局变量,方便调用</span>
<span style="color: #0000ff;">private</span><span style="color: #000000;"> Connection con;

</span><span style="color: #008000;">//</span><span style="color: #008000;">导入驱动,静态代码块的作用为只运行一次,异常无法向上抛出,只能及时处理</span>
<span style="color: #0000ff;">static</span><span style="color: #000000;">{
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;">{
        Class.forName(driver);
    }</span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (ClassNotFoundException e) {
        </span><span style="color: #008000;">//</span><span style="color: #008000;">打印异常相关信息</span>

e.printStackTrace(); } }

</span><span style="color: #008000;">//</span><span style="color: #008000;">无参构造方法,连接数据库</span>
<span style="color: #0000ff;">public</span><span style="color: #000000;"> BaseDao () {
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        con</span>=<span style="color: #000000;">DriverManager.getConnection(url,name,password);
    } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (SQLException throwables) {
        throwables.printStackTrace();
    }
}

</span><span style="color: #008000;">//</span><span style="color: #008000;">数据查找,返回查找的内容,向上抛异常</span>
<span style="color: #0000ff;">public</span> ResultSet executeSQL (String sql,Object...object) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException{
    PreparedStatement ps</span>=<span style="color: #000000;">con.prepareStatement(sql);

    </span><span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=0;i&lt;object.length;i++<span style="color: #000000;">){
        </span><span style="color: #008000;">//</span><span style="color: #008000;">ps传入参数的下标是从1开始</span>
        ps.setObject(i+1<span style="color: #000000;">,object[i]);
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;">返回结果集</span>
    <span style="color: #0000ff;">return</span><span style="color: #000000;"> ps.executeQuery();
}

</span><span style="color: #008000;">//</span><span style="color: #008000;">数据的增删改,返回数据执行行数</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> executeUpdate(String sql,Object...object) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException {
    PreparedStatement ps</span>=<span style="color: #000000;">con.prepareStatement(sql);
    </span><span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=0;i&lt;object.length;i++<span style="color: #000000;">){
        ps.setObject(i</span>+1<span style="color: #000000;">,object[i]);
    }
    </span><span style="color: #008000;">//</span><span style="color: #008000;">返回int类型执行行数</span>
    <span style="color: #0000ff;">return</span><span style="color: #000000;"> ps.executeUpdate();
}

</span><span style="color: #008000;">//</span><span style="color: #008000;">关闭数据库连接</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> close() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException{
    con.close();
}

}

下面的代码,大家可以也封装成工具类:

public static void main(String[] args) {
    String url = "jdbc:sqlserver://127.0.0.1:1433;SelectMethod=cursor;DatabaseName=ry"
                + ";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();
}

 

感想:由于大牛对小白关照细节不到位,所以决定写篇详细的给你们,节省大家的时间。

 

本文转载自博客园,原文链接:https://www.cnblogs.com/qydmw/p/13162897.html

全部评论: 0

    我有话说: