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

问题描述 投票:5回答:5

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

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

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

java postgresql scala jdbc
5个回答
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();

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为您提供的自动转义功能。


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); 

1
投票

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

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

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

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

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

代码示例摘录:

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

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.