当前位置: 首页 > news >正文

SQL Server大批量数据插入

数据库连接及相关操作

public class DataBase {/*** 驱动*/private static final String DRIVER = PropertiesUtil.getString("spring.datasource.driver-class-name");/*** 数据库地址*/private static final String URL = PropertiesUtil.getString("spring.datasource.url");/*** 数据库用户名*/private static final String NAME = PropertiesUtil.getString("spring.datasource.username");/*** 数据库密码*/private static final String PASSWORD = PropertiesUtil.getString("spring.datasource.password");/*** 数据库连接,定义为全局变量,方便调用*/private Connection con;//导入驱动,静态代码块的作用为只运行一次,异常无法向上抛出,只能及时处理static {try {Class.forName(DRIVER);} catch (ClassNotFoundException e) {//打印异常相关信息e.printStackTrace();}}/*** 无参构造方法,连接数据库*/public DataBase() {try {con = DriverManager.getConnection(URL, NAME, PASSWORD);} catch (SQLException throwable) {throwable.printStackTrace();}}/*** 数据查找,返回查找的内容,向上抛异常** @param sql* @param object* @return* @throws SQLException*/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();}/*** 关闭数据库连接** @throws SQLException*/public void close() throws SQLException {con.close();}/*** 设置 AutoCommit 模式为 false** @throws SQLException*/public void setAutoCommit(boolean flag) throws SQLException {// 设置 AutoCommit 模式con.setAutoCommit(flag);}/*** 事务提交** @throws SQLException*/public void commit() throws SQLException {// 手动提交事务con.commit();}/*** 事务回滚** @throws SQLException*/public void rollback() throws SQLException {con.rollback();}
}

批量插入数据

public class BulkCopyUtil {/*** 批量插入数据** @param tableName 表名* @param list      数据集合* @throws SQLException*/public static <T> void insertBatch(String tableName, List<T> list) throws Exception {// 查询出空值用于构建 CachedRowSetImpl 对象以省去列映射的步骤DataBase dataBase = new DataBase();// 从源表中获取数据作为 ResultSetResultSet resultSet = dataBase.executeSQL("select * from " + tableName + " where 1=0");CachedRowSetImpl crs = new CachedRowSetImpl();crs.populate(resultSet);ResultSetMetaData metaData = resultSet.getMetaData();int columnCount = metaData.getColumnCount();String[] dbFieldNames = new String[columnCount];for (int i = 1; i <= columnCount; i++) {dbFieldNames[i-1] = metaData.getColumnName(i);}// 循环批量插入for (T t : list) {if (ObjectUtil.isNotEmpty(t)) {// 移动指针到“插入行”,插入行是一个虚拟行crs.moveToInsertRow();// 向 CachedRowSet 对象插入一条数据populate(crs, t, dbFieldNames);// 插入虚拟行crs.insertRow();// 移动指针到当前行crs.moveToCurrentRow();}}// 进行批量插入bulkCopyHelp(dataBase, crs, tableName, list.size());}/*** 批量插入数据** @param dataBase  数据库连接相关操作* @param crs       CachedRowSet* @param tableName 表名* @param size      拷贝列表大小*/public static void bulkCopyHelp(DataBase dataBase, CachedRowSetImpl crs, String tableName, int size) throwsSQLException {// 数据库地址String url = PropertiesUtil.getString("spring.datasource.url");// 数据库用户名String name = PropertiesUtil.getString("spring.datasource.username");// 数据库密码String password = PropertiesUtil.getString("spring.datasource.password");// 数据库连接字符串String urlStr = url + ";user=" + name + ";password=" + password;// 使用 KeepIdentity 选项和 BatchSize 设置大容量复制对象SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();copyOptions.setKeepIdentity(true);copyOptions.setBatchSize(size);// 开启数据库事务copyOptions.setUseInternalTransaction(true);// 设置超时时间copyOptions.setBulkCopyTimeout(60000);SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(urlStr);bulkCopy.setBulkCopyOptions(copyOptions);// 设置拷贝目标表名bulkCopy.setDestinationTableName(tableName);// 将 crs 写入目标try {// 设置 AutoCommit 模式为 falsedataBase.setAutoCommit(false);// 执行数据库操作bulkCopy.writeToServer(crs);// 手动提交事务dataBase.commit();} catch (SQLException e) {e.printStackTrace();// 回滚dataBase.rollback();}crs.close();bulkCopy.close();}/*** 这里主要是通过表的列名,通过反射,拿到待插入对象的属性值** @param crs* @param record* @param dbFieldNames* @param <T>* @throws Exception*/private static <T> void populate(CachedRowSetImpl crs, T record, String[] dbFieldNames) throws Exception {Class<?> clazz = record.getClass();for (String fieldName : dbFieldNames) {StringBuilder getMethodName = new StringBuilder("get");if (fieldName.contains("_")) {String[] singleWords = fieldName.split("_");for (String singleWord : singleWords) {getMethodName.append(upperFirstChar(singleWord));}} else {getMethodName.append(upperFirstChar(fieldName));}Method method = clazz.getMethod(getMethodName.toString(), null);Object value = method.invoke(record, null);updateCrs(crs, fieldName, value);}}/*** 根据数据值的类型,将值设置到rowset里--这里value是否为空,都要做crs.update操作,否则会出bug** @param crs* @param dbFieldName* @param value* @throws SQLException*/private static void updateCrs(CachedRowSetImpl crs, String dbFieldName, Object value) throws SQLException {if (value instanceof String) {crs.updateString(dbFieldName, (String) value);} else if (value instanceof Integer) {crs.updateInt(dbFieldName, (int) value);} else if (value instanceof Double) {crs.updateDouble(dbFieldName, (double) value);} else if (value instanceof Long) {crs.updateLong(dbFieldName, (long) value);} else if (value instanceof Float) {crs.updateFloat(dbFieldName, (float) value);} else if (value instanceof Timestamp) {crs.updateTimestamp(dbFieldName, (Timestamp) value);} else if (value instanceof java.util.Date) {crs.updateDate(dbFieldName, new java.sql.Date(((java.util.Date) value).getTime()));} else {crs.updateObject(dbFieldName, value);}}/*** 首字母大写* @param camelCaseStr* @return*/private static String upperFirstChar(String camelCaseStr) {return camelCaseStr.substring(0, 1).toUpperCase() + camelCaseStr.substring(1);}
}

备注(数据库连接取值)

# 配置数据源
spring:datasource:driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriverurl: jdbc:sqlserver://ip:port;DatabaseName=collectionusername: sapassword: 123456
http://www.lryc.cn/news/512261.html

相关文章:

  • 在 Ubuntu 下通过 Docker 部署 Caddy 服务器
  • ZooKeeper注册中心实现
  • 数仓建模:如何进行实体建模?
  • Python编程技术
  • 「Mac玩转仓颉内测版55」应用篇2 - 使用函数实现更复杂的计算
  • map参数详解
  • OSI 七层模型 | TCP/IP 四层模型
  • 高转速风扇|无刷暴力风扇方案设计
  • GPU 进阶笔记(三):华为 NPU/GPU 演进
  • 计算机网络 (13)信道复用技术
  • 数据库约束和查询
  • 网工日记:FTP两种工作模式的区别
  • NLP模型工程化部署
  • 分布式版本管理工具——git 中忽略文件的版本跟踪(初级方法及高级方法)
  • 【LangChain】Chapter4 - Question and Answer Over Documents
  • TCP/IP 协议演进中的瓶颈,权衡和突破
  • 软件测试面试八股文,查漏补缺(附文档)
  • IDEA工具使用介绍、IDEA常用设置以及如何集成Git版本控制工具
  • YOLOv10-1.1部分代码阅读笔记-transformer.py
  • 机器人革新!ModbusTCP转CCLINKIE网关揭秘
  • JWT包中的源码分析【Golang】
  • SpringBoot数据字典字段自动生成对应code和desc
  • TencentOS 2.4 final 安装mysql8.0备忘录
  • Hadoop HA安装配置(容器环境),大数据职业技能竞赛模块A平台搭建,jdk+zookeeper+hadoop HA
  • 使用javascript读取波形文件数据,并生成动态的波形图
  • 服务器系统维护与安全配置
  • 大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!
  • Spring Boot自定义注解获取当前登录用户信息
  • js创建二维空数组
  • AF3 checkpoint_blocks函数解读