如何在ClickHouse JDBC库中导入CSV文件?
在ClickHouse JDBC库中高效导入CSV的方法
你当前使用的ClickHouse JDBC依赖为:
<dependency> <groupId>com.clickhouse</groupId> <artifactId>clickhouse-jdbc</artifactId> <version>0.3.2-patch11</version> </dependency>
之前通过PreparedStatement传入CSV字符串的方式虽然可行,但确实有更高效、更贴合库设计的CSV导入方案,以下是几种推荐的实现方式:
方法1:使用ClickHouseStatement的流导入API
这是处理大体积CSV最推荐的方式,无需将整个文件加载到内存,直接通过流传输数据:
String url = "jdbc:ch://localhost"; ClickHouseDataSource dataSource = new ClickHouseDataSource(url, new Properties()); try (ClickHouseConnection conn = dataSource.getConnection("default", "password"); ClickHouseStatement stmt = conn.createStatement()) { // 读取本地CSV文件流,也可以是网络流等其他来源 try (InputStream csvStream = new FileInputStream("/path/to/your/data.csv")) { // 执行带FORMAT CSV的插入语句,通过sendStream传入流数据 stmt.sendStream("INSERT INTO your_table FORMAT CSV", csvStream); } } catch (SQLException | IOException e) { e.printStackTrace(); }
方法2:通过ClickHousePreparedStatement绑定流参数
如果需要用预编译语句的形式,可通过绑定流参数替代直接传入字符串,同样适合大文件场景:
String url = "jdbc:ch://localhost"; ClickHouseDataSource dataSource = new ClickHouseDataSource(url, new Properties()); try (ClickHouseConnection conn = dataSource.getConnection("default", "password"); ClickHousePreparedStatement ps = (ClickHousePreparedStatement) conn.prepareStatement( "INSERT INTO your_table FORMAT CSV < ?")) { // 绑定字符流(CSV为文本格式时使用) try (Reader csvReader = new FileReader("/path/to/your/data.csv")) { ps.setCharacterStream(1, csvReader); ps.executeUpdate(); } } catch (SQLException | IOException e) { e.printStackTrace(); }
方法3:结合CSV解析库实现预处理批量插入
如果需要对CSV内容做字段校验、转换等预处理,可配合CSV解析库(如OpenCSV)解析数据后批量插入:
String url = "jdbc:ch://localhost"; ClickHouseDataSource dataSource = new ClickHouseDataSource(url, new Properties()); try (ClickHouseConnection conn = dataSource.getConnection("default", "password"); ClickHousePreparedStatement ps = (ClickHousePreparedStatement) conn.prepareStatement( "INSERT INTO your_table (col1, col2, col3) VALUES (?, ?, ?)"); CSVReader csvReader = new CSVReader(new FileReader("/path/to/your/data.csv"))) { String[] nextLine; // 跳过CSV表头(如果存在) csvReader.readNext(); while ((nextLine = csvReader.readNext()) != null) { ps.setString(1, nextLine[0]); ps.setInt(2, Integer.parseInt(nextLine[1])); ps.setDouble(3, Double.parseDouble(nextLine[2])); ps.addBatch(); } ps.executeBatch(); } catch (SQLException | IOException e) { e.printStackTrace(); }
注意事项
- 确保CSV的列顺序与目标表列顺序匹配,或在INSERT语句中明确指定列映射(如
INSERT INTO your_table (col1, col2) FORMAT CSV) - 大文件优先选用流导入方式,避免内存溢出
- ClickHouse的CSV格式会自动处理特殊字符(如引号、换行符),无需手动转义
内容的提问来源于stack exchange,提问作者Francesc Recio
相关产品推荐
相关产品推荐

