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

eagi6jfj  于 2023-10-18  发布在  Scala
关注(0)|答案(6)|浏览(201)

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

  • 不支持PostgreSQL类型的数据结构,如UUID。
  • 常见的JDBC异常,例如:
  • 没有函数来转义PostgreSQL使用的值。
  • 对批处理中执行异构语句的支持有限。
  • 在一个表中插入多行时,不需要将多个insert语句重写为单个insert语句。

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

41zrol4v

41zrol4v1#

其中一些似乎是(除非我不理解)使用JDBC时的用户错误。JDBC是一个相当丑陋的API,所以永远不要问你是否能优雅地完成它,只要问你是否能完成它。
正如@ColinD和@a_horse所指出的,应该使用Prepared语句和批处理操作来处理转义和插入多行。在引擎盖下,我希望一个好的JDBC实现来做你想要的事情(我不熟悉PostgreSQL的实现)。
关于UUID,here是一个解决方案:
PostgreSQL所能做的就是将字符串转换为uuid。
您可以通过使用数据类型org.postgresql.util.PGobject来利用这一点,这是一个用于表示JDBC未知的数据类型的通用类。
你可以定义一个helper类:

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

o7jaxewo2#

该驱动程序支持批处理语句以加快批量插入。
使用批处理语句比使用专有的SQL语法更便于移植(据我所知,多行插入和批处理插入之间没有太大的区别)
查看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给你的自动转义。

omtl5h9j

omtl5h9j3#

我知道这并没有回答你的全部问题,但希望它仍然有用。
我使用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);
6gpjuf90

6gpjuf904#

不支持PostgreSQL类型的数据结构,如UUID。
相反,Postgres 9.x的current JDBC driver(9.2-1002 JDBC 4)确实通过setObject和getObject命令支持UUID。你不能得到比这更直接或更简单的(在任何数据库中,Postgres或任何其他),因为JDBC不识别UUID作为数据类型。
据我所知,没有必要像Yishai在另一个回答中建议的那样创建一个助手类。
不需要做任何铸造或通过字符串。

请参阅my blog post以获取更多讨论和代码示例。
代码示例摘录:

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

8ulbf1ek5#

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

q8l4jmvw

q8l4jmvw6#

下面是一个自实现的(实验性的)最小客户端库的一些实验:https://github.com/BeatEngine/postgresql-client-minimal(我尝试在Android API级别< 24上使用此功能)

相关问题