还在为传统 DBMS 的性能问题而烦恼?想借助 ODPS 的分布计算能力?但是你又不想学习官方的 SDK ?如果你恰好在老项目中用了 JDBC 访问 Oracle 或 MySQL?那么你可能对这篇文章感兴趣。
本文将结合几种常见的使用场景(数据查询、数据导入、第三方客户端工具)来介绍 odps-jdbc ,并附有代码示例级别的入门教程(比较长,所以放在了最后,并不建议看 :D)。
什么是 odps-jdbc?odps-jdbc 是 ODPS 官方提供的 JDBC 驱动,它向 Java 程序提供了一套执行 SQL 任务的接口。还记得吗? 当年 Java 红遍大江南北靠的就是一句“编写一次,处处运行”,JDBC 也是这种思潮下产物。
目前 hive-jdbc 支持的功能 odps-jdbc 都能够支持,hive-jdbc 不支持的一些功能,例如滚动游标的 ResultSet,也支持了。 我们的目标是使 ODPS 更加开放、灵活和易用。项目托管在github。欢迎各位开源热心人士积极反馈,贡献代码。
场景1:数据查询
用 JDBC API 执行查询语句(Select)是最常见的场景。对于 ODPS 的 SQL 任务,我们只要通过几个简单的 API,就可以拿到带有类型信息的数据。
具体来说,就是调用 Statement 对象的 execute()
方法,Statement 对象可以通过 conn 对象的来创建(conn 是 JDBC 连接对象,后面的入门教程会具体描述它是如何创建的)。Statement 对象可以重复地使用来执行不同的 SQL。
Statement stmt = conn.createStatement();
ResultSet rs = stmt.execute("SELECT foo FROM bar");
Select 语句执行完成会返回一个 ResultSet 对象,它的用法类似一个迭代器,你可以在一个 while 循环中访问结果中每一行的数据。是不是很简单?
while (rs.next()) {
...
}
假设查询到的结果只有两列数据,第一列为整型,第二列为字符串,把所有行打印出来的代码应该长这样:
while (rs.next()) {
System.out.printf("col1:%d, col2:%s", rs.getInt(1), rs.getString(2));
}
更多 API 的使用可以查看 JDBC 的文档。
场景2:批量数据导入
JDBC 接口定义了批处理(batch)操作,结合 PreparedStatement 使用,odps-jdbc 就可以实现数据批量导入 ODPS 的功能。
具体地,只要把带有类型信息的数据先添加到 batch 中,当累计到一定数量(batchSize),就调用一次批量执行方法,这样就能批量地将你的数据上传到 odps。省去了额外序列化反序列化的麻烦,尤其适合从传统数据库导到 ODPS 的场景。
还是直接看代码吧:
String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
final int batchSize = 1000;
int count = 0;
for (Employee employee: employees) {
ps.setString(1, employee.getName());
ps.setString(2, employee.getCity());
ps.setString(3, employee.getPhone());
ps.addBatch();