平常開發中,對於操做ClickHouse中的數據,查詢是最經常使用的功能。本文經過代碼示例介紹使用JDBC方式鏈接ClickHouse查詢數據的兩種接口:Statement 和 PreparedStatement接口。html
筆者使用idea開發工程,首先建立maven項目,POM文件引入ClickHouse驅動依賴包。java
<dependency> <groupId>ru.yandex.clickhouse</groupId> <artifactId>clickhouse-jdbc</artifactId> <version>0.2.4</version> </dependency>
JDBC鏈接ClickHouse的兩種接口主要區別是:Statement 接口不接受參數,PreparedStatement 接口運行時接受輸入的參數。git
Statement能夠正常訪問數據庫,適用於運行靜態 SQL 語句。 Statement 接口不接受參數。github
import java.sql.*; public class ClickHouseClient { private static final String URL = "jdbc:clickhouse://<host>:<port>[/<database>]"; private static final String USER = "your username"; private static final String PASSWORD = "your password"; public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 註冊JDBC驅動 Class.forName("ru.yandex.clickhouse.ClickHouseDriver"); // 打開鏈接 connection = DriverManager.getConnection(URL, USER, PASSWORD); System.out.println("connected database successfully"); // 執行查詢 statement = connection.createStatement(); String sql = "select * from database.table_name limit 10"; ResultSet rs = statement.executeQuery(sql); // 從結果集中提取數據 while (rs.next()){ String name = rs.getString("name"); float size = rs.getFloat("size"); System.out.println(name + " " + size); } rs.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { // 釋放資源 try { if(statement!=null){ statement.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); } try { if(connection!=null){ connection.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); } } } }
PreparedStatement計劃屢次使用 SQL 語句, PreparedStatement 接口運行時接受輸入的參數。sql
import java.sql.*; public class ClickHouseClient2 { private static final String URL = "jdbc:clickhouse://<host>:<port>[/<database>]"; private static final String USER = "your username"; private static final String PASSWORD = "your password"; public static void main(String[] args) { Connection connection = null; // 注意這裏使用的CK本身實現的PreparedStatement ClickHousePreparedStatement statement = null; try { // 註冊JDBC驅動 Class.forName("ru.yandex.clickhouse.ClickHouseDriver"); // 打開鏈接 connection = DriverManager.getConnection(URL, USER, PASSWORD); System.out.println("connected database successfully"); // 執行查詢 String sql = "select * from database.table_name where name = ?"; ClickHousePreparedStatement statement = (ClickHousePreparedStatement)connection.prepareStatement(sql); statement.setString(1, "bjehp"); ResultSet rs = statement.executeQuery(); // 打印填充後的SQL語句(ck實現的PreparedStatement類包含了打印sql語句的方法) System.out.println("execute: " + statement.asSql()); // 從結果集中提取數據 while (rs.next()){ String name = rs.getString("name"); float size = rs.getFloat("size"); System.out.println(name + " " + size); } rs.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { // 釋放資源 try { if(statement!=null){ statement.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); } try { if(connection!=null){ connection.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); } } } }
這裏要注意的是,在調用executeQuery方法時,Statement須要傳入sql參數,而PreparedStatement無需傳入sql參數,由於在建立PrepareStatement對象時,已經傳入sql參數。PrepareStatement能夠使用佔位符,會對傳入的sql進行預編譯,批處理比Statement效率高。數據庫
[1] JDBC教程 https://www.yiibai.com/jdbc/jdbc_quick_guide.html
[2] ClickHouse/clickhouse-jdbc https://github.com/ClickHouse/clickhouse-jdbcyii