clickhouse通过jdbc实现批量数据导入代码示例

2023-11-16

通过mybatis也可以实现批量写入clickhouse,但是效率太低,每秒大概只能写入300条数据,对于动辄上千万的数据或者更多数据,效率就太低了。而采用jdbc驱动的方式进行批量写入,每秒大约写入数据量达到10000条,效率得到大幅度的提升,只是这种方式,需要编写的代码会更多,需要处理的细节也更多。

1. 添加依赖

<!--clickhouse-->
<dependency>
	<groupId>com.clickhouse</groupId>
	<artifactId>clickhouse-jdbc</artifactId>
	<version>0.3.2-patch8</version>
</dependency>

2. 获取连接

public Connection getClickHouseConnection(){
        
	String url = "jdbc:clickhouse://192.168.17.81:8123/default";

	Properties props = new Properties();
	props.setProperty("user", username);
	props.setProperty("password", "123456");	

	try {
		
		ClickHouseDataSource dataSource = new ClickHouseDataSource(url, props);
		Connection conn = dataSource.getConnection();
		return conn;
	}catch (Exception e)
	{
		e.printStackTrace();
	}

	return null;	
}



// 关闭连接
public void closeClickHouseConnection(Connection connection)
{
	if (connection != null) {
		try {
			connection.close();
		} catch (SQLException e) {
			//ignore
		}
	}
}

3. 准备预编译sql

private String buildBatchSql()
{
	String baseSql = "INSERT INTO plat_data_center_bill(bill_id, bank_merchno, bank_sub_merchno, ...) ";
	baseSql = baseSql + "VALUES(";

	baseSql = baseSql + "?,?,?,?,?,?,?,?,?,?";
	baseSql = baseSql + ",?,?,?,?,?,?,?,?,?,?";        

	baseSql = baseSql + ")";

	return baseSql;
}

注意这里的字段对应的值采用问号替换,一个字段就是一个问号。

4. 批量写入数据

private void batchInsertClickHouse(Connection connection, List<PlatDataCenterBill> dataList)
{        
	String batchSql = buildBatchSql();

	PreparedStatement prepareStatement = null;
	try {
		 connection.setAutoCommit(true);
		// 执行conn.setAutoCommit(false);会报Transactions are not supported异常
		// 所以不能执行conn.commit();
		// 只能执行pst.executeBatch();由clickhouse进行后台提交。测试时插入数据条数是正确的
		prepareStatement = connection.prepareStatement(batchSql);
		for (PlatDataCenterBill bill : dataList) {
			prepareStatement.setLong(1, bill.getBillId());

			setPrepareString(prepareStatement, 2, bill.getBankMerchno());

			setPrepareString(prepareStatement,2, bill.getBankMerchno());
			setPrepareString(prepareStatement,3, bill.getBankSubMerchno());
			setPrepareString(prepareStatement,4, bill.getBankMerchname());
			prepareStatement.setObject(5, bill.getBankDeptid());

			setPrepareString(prepareStatement,6, bill.getBankDeptances());
			setPrepareString(prepareStatement,7, bill.getBankDeptname());
			setPrepareString(prepareStatement,8, bill.getAppId());
			setPrepareString(prepareStatement,9, bill.getExternalMerchno());
			setPrepareString(prepareStatement,10, bill.getExternalMerchname());

			...		

			prepareStatement.addBatch();
		}
		prepareStatement.executeBatch();
		prepareStatement.clearBatch();
		
	} catch (Exception e) {
		e.printStackTrace();
		throw new ServiceException("批量写入异常");
	} finally {
		if (prepareStatement != null) {
			try {
				prepareStatement.close();
			} catch (SQLException e) {
				//ignore
			}
		}    

	}
}

这里需要注意的是需要对每个字段的值进行设置,即使字段值为空值,也需要设置,另外还需要注意,日期时间类型,需要使用Timestamp进行设置。

prepareStatement.setObject(48, new Timestamp(sqlCreateTime.getTime()));

 5. 为了判断空值,使用统一的方法

public void setPrepareString(PreparedStatement pst, int idx, String value) throws SQLException {

	if(value != null) {
		pst.setString(idx, value);
	}
	else  {
		pst.setString(idx, "");
	}
}

6. 相关的依赖

import com.clickhouse.jdbc.ClickHouseDataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

7. 循环批量写数据

Connection connection = getClickHouseConnection();


List<PlatDataCenterBill> platBills = pdcBillService.selectPlatDataCenterBillList(pdcbill);

int iCount = 0;

ArrayList<PlatDataCenterBill> billList = new ArrayList<PlatDataCenterBill>();

for(PlatDataCenterBill bill : platBills)
{
	billList.add(bill);
	iCount = iCount + 1;

	if(iCount % 10000 == 0)
	{		
		System.out.println(billList.size());
		batchInsertClickHouse(connection, billList);

		billList.clear();
	}
}

// 剩余部分数据批量写入
if(billList.size() > 0)
{	
	batchInsertClickHouse(connection, billList);
	billList.clear();
}


// 这里关闭连接才是正确的
closeClickHouseConnection(connection);

以上就是批量导入数据的大致处理过程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

clickhouse通过jdbc实现批量数据导入代码示例 的相关文章

  • 在java代码中创建postgresql表

    我有一个与 postgreSQL 数据库连接的 java 代码 现在 我希望当它连接到数据库时 我还将创建数据库表 但我的问题是 它不会创建数据库 我不知道问题是什么 这是我的代码 Statement st null ResultSet r
  • java中高效的输入流到字符串方法

    因此 我在 Java 中的 诚然非常简单 应用程序上运行探查器 令我惊讶的是 仅次于需要在时间上发出 HTTP 请求的方法的是我的方法 inputStreamToString方法 目前它的定义如下 public static String
  • Spring Data Jpa OneToMany 同时保存子实体和父实体?

    这是我的父实体 注意 为了简洁起见 删除了 getter setter lombok 注释 Entity public class Board Id GeneratedValue strategy GenerationType IDENTI
  • 无法在 Intellij 中运行主类[重复]

    这个问题在这里已经有答案了 我有以下项目结构 ProjectRoot src Main examples libs My src文件夹被标记为sources在 Intellij 中 现在 当我想运行 Main 类时 出现以下错误 Excep
  • 清空变量不会使方法引用无效[重复]

    这个问题在这里已经有答案了 为什么代码不抛出NullPointerException当我使用与变量绑定的方法引用时dog我后来分配了null to 我正在使用 Java 8 import java util function Functio
  • 使用 https 的 Web 服务身份验证给出错误

    我编写了一个简单的 Web 服务 并使用摘要和 HTTPS 身份验证来保护它 我已经使用 Java 中的 keytool 生成了我的证书 当我通过创建 war 文件在 Tomcat 中部署 Web 服务时 axis 的欢迎页面正确显示 但是
  • Google 表格使用 API 密钥而不是 client_secret.json

    In the QuickStart java示例Java 快速入门 https developers google com sheets api quickstart java他们使用OAuth client ID识别该应用程序 这会弹出一
  • 是否可以创建 Java RAM 磁盘以与 java.io.* API 一起使用?

    我正在使用一个第三方库 它基本上创建一个输出目录 其中包含不同类型的文件和子目录 我希望能够编写单元测试来确认输出正确 我希望能够将库与 RAM 磁盘一起使用 这样库所做的任何事情都不会以任何方式接触实际的磁盘板 这个想法是让测试运行和清理
  • 如何检查单词是否在wordNet中

    我开始了解wordNet直到我知道我找到了synonymous对于一个特定的词 现在我有一个文件 我想使用标记化该文本n gram例如 String s I like to wear tee shirt 使用后n gram这将是 I lik
  • JFrame 在连续运行代码时冻结

    我在使用时遇到问题JFrame 它会冻结 连续运行代码 下面是我的代码 点击时btnRun 我调用了该函数MainLoop ActionListener btnRun Click new ActionListener Override pu
  • java彩色滚动条搜索结果

    我将如何在 Java 中自定义滚动条 以便我可以进行像 chrome 一样的搜索 也就是说在结果所在的位置放置彩色条纹 我不想要一个库 因为我更喜欢自己编写代码 另外 我不想失去我拥有的 L F 欢迎举例 实际上 它将查看一个大的文本文件或
  • 扩展多个类

    我知道 Java 不支持多重继承 因为不允许扩展多个类 我只是想知道我的问题是否有解决方法 我有一个名为CustomAction需要扩展两个抽象类 BaseAction and QuoteBaseAction 我无法更改这些抽象类中的任何一
  • java绕中心旋转矩形

    我想围绕其中心点旋转一个矩形 它应该保留在应该绘制的位置并在该空间中旋转 这是我的代码 AffineTransform transform new AffineTransform transform rotate Math toRadian
  • 为休息服务实施 JUnit 测试

    我必须为我的休息服务实现一些 JUnit 测试 例如 这是我的休息服务之一 Path dni fe public class HelloWorld POST Path home Consumes MediaType APPLICATION
  • 如何获取 JDBC 中 UPDATE 查询影响的所有行?

    我有一项任务需要使用更新记录PreparedStatement 一旦记录被更新 我们知道更新查询返回计数 即受影响的行数 但是 我想要的不是计数 而是受更新查询影响的行作为响应 或者至少是受影响的行的 id 值列表 这是我的更新查询 UPD
  • Spring Security 角色层次结构不适用于 Thymeleaf sec:authorize

    我正在使用 Spring Security 3 2 5 RELEASE 和 ThymeLeaf 2 1 4 RELEASE 我已经在安全上下文中定义了角色层次结构 在我的视图层中我正在使用sec authorize属性来定义菜单项 我希望看
  • 在 Eclipse RCP 应用程序中禁用插件贡献

    我经常遇到这个问题 但尚未找到解决方案 每当我编写一个新的基于 Eclipse RCP 的应用程序并包含来自 Eclipse 平台的插件时 我都会 继承 其中一些插件的 UI 贡献 大多数贡献 菜单项 键盘快捷键 属性页 都很有用 但有时我
  • 在 Kotlin 中声明静态属性?

    My Java code public class Common public static ModelPengguna currentModelPengguna public class Common companion object v
  • 如何在一次操作中使用 Thymeleaf 检查 null 和空条件?

    有什么方法可以检查 Thymeleaf 中的 null 和empty 条件吗 方法一 1 variable1 variable2 variable3 2 variable null 3 variable 如果我们结合两个条件 例如 vari
  • Spring MVC:通用 DAO 和服务类

    我正在 Spring MVC 中编写网页 我使用 Generic DAO 编写了所有 DAO 现在我想重写我的服务类 我该如何写 通用服务 我的 DAO 如下 DAO package net example com dao import j

随机推荐

  • 记一次ES线上异常

    记一次ES线上异常解决过程 周六线上es报警es not green 由于没有带笔记本回家并且考虑到集群容量本身就很紧张以及最近的读写压力确实很大 并没有多余的机器可以加入集群 觉得应该不会是什么大问题 就没有太多在意 周末去上班打开电脑一
  • 如何调用百度接口来实现全国的撒点效果(在这里把百度接口的文档荡到本地了)

  • LogisticRegression用户流失预测模型初探【推荐】

    什么是逻辑回归 Logistic回归与多重线性回归实际上有很多相同之处 最大的区别就在于它们的因变量不同 其他的基本都差不多 正是因为如此 这两种回归可以归于同一个家族 即广义线性模型 generalizedlinear model 这一家
  • 「c++小学期」实验题目及代码

    面向对象编程的C 和平时做题用的C 还是有差距的 实验的题目都是小题目 就都做一下吧 实验一 简单C 程序设计 1 猜价格游戏 编写C 程序完成以下功能 1 假定有一件商品 程序用随机数指定该商品的价格 1 1000的整数 2 提示用户猜价
  • 【AI with ML】第 8 章 :使用 TensorFlow 创建文本

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • styled-components设置组件属性

    问题 最近在试着用react做一个音乐播放器 在这之前其实并不了解styled components 但由于使用css in js并且想实现hover效果 百度各种解决方案后发现了styled components这个好东西 如果你看到了这
  • RGMII接口(KSZ9031)

    概述 RGMII的时序是时钟双沿采样 在默认的RGMII时序中 时钟 RXC TXC 边沿与数据边沿 TXD RXD TX CTL RX CTL 的对齐 因此 FPGA想要正确收发数据 需要对TXC或RXC进行适当的延迟 由于最高时钟为12
  • 二手房交易差额款需要一次交清?

    在签订购房合同的时候 房东要求添加条款 在房产过户当日收取差额款 差额款应该一次性给他 还是可以按比例付 拿到房产证后付清 他给我写收条的时候 我应该注意什么 找法网小编为您详细介绍 网友咨询 我通过本地的老牌中介买房的 在签订购房合同的时
  • 时间序列数据特征提取TsFresh

    文章目录 1 源码和数据地址 2 TsFresh安装 3 代码部分说明 3 1 数据下载 3 2 从文件读取数据 4 特征拓展 4 1 默认参数 4 2 ComprehensiveFCParameters参数 4 3 EfficientFC
  • 电子工程师的自我修养 - OD输出

    开漏输出 Open Drain Output OD门 漏极开路 Open Drain 电路特点 利用外部电路的驱动能力 减少IC内部的驱动 可以将多个开漏输出的pin连接到一条线上 通过一个上拉电阻 在不增加任何器件的情况下 形成 线与 关
  • 使用myisamchK 命令修复数据

    使用myisamchk 命令修复表 myisam使用程序可以用来获得有关你的数据库表的统计信息 检查 修复 优化他们 命令格式 myisamchk option tables frm 常用的检查选项 information i 打印所检察标
  • 韦东山 IMX6ULL和正点原子_「正点原子NANO STM32开发板资料连载」第三章 MDK5 软件入门1...

    1 实验平台 ALIENTEK NANO STM32F411 V1开发板 2 摘自 正点原子STM32F4 开发指南 HAL 库版 关注官方微信号公众号 获取更多资料 正点原子 第三章 MDK5 软件入门 本章将向大家介绍 MDK5 软件和
  • Blazor组件自做四 : 使用JS隔离封装signature_pad签名组件

    运行截图 演示地址 响应式 感谢szimek写的棒棒的signature pad js项目 来源 https github com szimek signature pad 正式开始 1 在文件夹wwwroot lib 添加signatur
  • python3+requests+unittest实战系列【一】

    1 环境准备 python3 pycharm编辑器 2 框架目录展示 该套代码只是简单入门 有兴趣的可以不断后期完善 1 run py主运行文件 运行之后可以生成相应的测试报告 并以邮件形式发送 2 report文件夹存放测试结果报告 3
  • Python解偏微分方程

    2 u x
  • 能力强的项目经理是怎么催活儿的?(内附项目管理软件推荐)

    从确定做某个项目开始 项目经理就仿佛进入到了一个不断 催 的阶段 项目经理 催字符 恨不得贴到每个任务的负责人头上 仿佛项目经理除了开会就是催活儿 浪费大量精力和时间 今天分享的项目经理 催活儿指南 从计划 反馈以及隐形激励三个方面来梳理项
  • Linux 下的两个特殊的文件 -- /dev/null 和 /dev/zero 简介及对比

    1 概论 来自维基的解释 dev null 在类Unix系统中 dev null 或称空设备 是一个特殊的设备文件 它丢弃一切写入其中的数据 但报告写入操作成功 读取它则会立即得到一个EOF 在程序员行话 尤其是Unix行话中 dev nu
  • 链表类模板list

    描述 设计如下样式的链表类模板list 并对其进行简单使用 template
  • DataGridView数据显示和编辑控件的基本属性

    DataGridView是C Windows Forms中的一个数据显示和编辑控件 它具有许多有用的属性来控制其外观和行为 以下是DataGridView的一些基本属性 DataSource 设置或获取DataGridView绑定的数据源
  • clickhouse通过jdbc实现批量数据导入代码示例

    通过mybatis也可以实现批量写入clickhouse 但是效率太低 每秒大概只能写入300条数据 对于动辄上千万的数据或者更多数据 效率就太低了 而采用jdbc驱动的方式进行批量写入 每秒大约写入数据量达到10000条 效率得到大幅度的