什么是用于访问PostgreSQL数据库的JDBC驱动程序的替代方案

时间:2011-02-04 16:13:34

标签: java postgresql scala jdbc

我正在为PostgreSQL使用官方JDBC驱动程序,但我遇到了以下问题:

  • 不支持PostgreSQL-ish数据结构,例如UUID。
  • 常见的JDBC奇怪,例如:
    • 没有函数来转义PostgreSQL使用的值。
    • 批量执行异构语句的支持有限。
    • 在一个表中插入多行时,不会将多个insert语句重写为单个insert语句。

所以,问题是 - 是否有任何PostgreSQL数据库驱动程序可以利用PostgreSQL的全部功能而没有太多样板?我也使用Scala语言进行开发,所以如果驱动程序是专门为Scala设计的,那就太棒了。

5 个答案:

答案 0 :(得分:9)

其中一些似乎是(除非我不理解)使用JDBC时的用户错误。 JDBC是一个非常丑陋的API,所以永远不要问你是否可以优雅地做到这一点,只要问你是否可以做到这一点。

@ColinD和@a_horse指出,应该使用Prepared语句和批处理操作来处理转义和插入多行。在幕后,我希望有一个很好的JDBC实现来完成你想要的东西(我不熟悉PostgreSQL的实现)。

关于UUID,here是一个解决方案:

  

PostgreSQL可以做的就是将字符串文字转换为uuid。

     

您可以使用数据类型来使用它   org.postgresql.util.PGobject,这是一个常用的类   表示JDBC不知道的数据类型。

     

您可以定义辅助类:

public class UUID extends org.postgresql.util.PGobject {
    public static final long serialVersionUID = 668353936136517917L;
    public UUID(String s) throws java.sql.SQLException {
        super();
        this.setType("uuid");
        this.setValue(s);
    }
}
     

然后以下代码将成功:

 java.sql.PreparedStatement stmt =
 conn.prepareStatement("UPDATE t SET uid = ? WHERE id = 1");
 stmt.setObject(1, new UUID("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"));
 stmt.executeUpdate();

答案 1 :(得分:4)

驱动程序支持批处理语句以加速批量插入。

使用批处理语句比使用专有INSERT语法要便携得多(据我所知,多行插入和批量插入之间没有太大差别)

查看PreparedStatement.addBatch()

不支持UUID的原因可能是UUID不是Postgres核心的一部分,只是一个contrib模块。

修改
关于执行异构语句

Postgres驱动程序支持批处理中不同类型的语句。

以下工作正常:

Connection con = DriverManager.getConnection("jdbc:postgresql://localhost/postgres", "foo", "bar");
con.setAutoCommit(false);
Statement stmt = con.createStatement();
stmt.addBatch("create table foo (id integer, data varchar(100))");
stmt.addBatch("insert into foo values (1, 'one')");
stmt.addBatch("insert into foo values (2, 'two')");
stmt.addBatch("update foo set data = 'one_other' where id = 1");
stmt.executeBatch();
con.commit();

虽然您确实失去了PreparedStatement为您提供的自动转义功能。

答案 2 :(得分:3)

我意识到这并不能回答你的整个问题,但希望它会同样有用。

我正在使用Java 6和Postgres 8.4。我正在使用的驱动程序在我的Maven POM文件中:

<dependency>
    <groupId>postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>8.4-702.jdbc4</version>
</dependency>

我正在使用PreparedStatement.getObject()PreparedStatement.setObject()与Java的java.util.UUID类来检索和存储UUID。

例如:

pstm.setObject(1, guid); //where pstm is a PreparedStatement and guid is a UUID

//where rs is a ResultSet
UUID myGuid = (UUID) rs.getObject("my_uuid_column_name"); 

工作正常。

对于较新的驱动程序,以下是支持

UUID myGuid = rs.getObject("my_uuid_column_name", UUID.class); 

答案 3 :(得分:1)

  

不支持PostgreSQL-ish数据结构,例如UUID。

相反,current JDBC driver 9.x的Postgres(9.2-1002 JDBC 4)确实通过UUIDsetObject支持getObject命令。您无法获得更直接或更简单的信息(在任何数据库,Postgres或任何其他数据库中),因为JDBC无法将UUID识别为数据类型。

据我所知,没有必要按照Yishai的另一个答案建议帮助类。

无需进行任何演员或通过字符串。

enter image description here

有关更多讨论和代码示例,请参阅my blog post

代码示例摘录:

java.util.UUID uuid = java.util.UUID.randomUUID();
…
preparedStatement.setObject( nthPlaceholder++, uuid ); // Pass UUID to database.

答案 4 :(得分:0)

查看O/R Broker,这是一个基于Scala JDBC的关系数据库访问库。