Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用于访问PostgreSQL数据库的JDBC驱动程序有哪些替代方案_Java_Postgresql_Scala_Jdbc - Fatal编程技术网

Java 用于访问PostgreSQL数据库的JDBC驱动程序有哪些替代方案

Java 用于访问PostgreSQL数据库的JDBC驱动程序有哪些替代方案,java,postgresql,scala,jdbc,Java,Postgresql,Scala,Jdbc,我正在使用PostgreSQL的官方JDBC驱动程序,但我遇到了以下问题: 不支持PostgreSQL数据结构,如UUID 常见的JDBC怪异之处,例如: 没有用于转义PostgreSQL使用的值的函数 对批量执行异构语句的支持有限 在一个表中插入多行时,不会将多个insert语句重写为单个insert语句 那么,问题是——是否有任何PostgreSQL数据库驱动程序可以在没有太多样板文件的情况下充分利用PostgreSQL的强大功能?我也在使用Scala语言进行开发,所以如果驱动程序是

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

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

那么,问题是——是否有任何PostgreSQL数据库驱动程序可以在没有太多样板文件的情况下充分利用PostgreSQL的强大功能?我也在使用Scala语言进行开发,所以如果驱动程序是专门为Scala设计的,那就太棒了。

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

使用批处理语句比使用专有的插入语法更具可移植性(据我所知,多行插入和批处理插入之间没有什么大的区别)

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

但其中一些似乎是(除非我不理解)使用JDBC时的用户错误。JDBC是一个相当丑陋的API,所以永远不要问你是否可以优雅地完成它,只要问你是否可以完成它就行了

正如@ColinD和@a_horse指出的那样,应该使用准备好的语句和批处理操作来处理转义和插入多行。在幕后,我希望一个好的JDBC实现能够完成您想要的事情(我不熟悉PostgreSQL的实现)

关于UUID,是一种解决方案:

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

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

我意识到这并不能回答您的全部问题,但希望它仍然有用

我正在使用Java6和Postgres8.4。我使用的驱动程序在我的Maven POM文件中是:

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

很好

对于较新的驱动程序,也支持以下内容

UUID myGuid = rs.getObject("my_uuid_column_name", UUID.class); 
不支持PostgreSQL数据结构,如UUID

相反,9.x的(9.2-1002 JDBC 4)确实通过and命令支持。因为JDBC不将UUID识别为数据类型,所以无法获得比这更直接或更简单的结果(在任何数据库、Postgres或任何其他数据库中)

据我所知,没有必要像Yishai在另一个答案中所建议的那样创建一个helper类

不需要做任何铸造或通过字符串

有关更多讨论和代码示例,请参见

代码示例摘录:

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

是否应该使用
PreparedStatement
并在其中设置值来处理任何转义?批量更新不适用于插入多行?您的确切意思是:没有用于转义值的函数consuming@ColinD对于同构语句也可以,但我还需要在批处理和语句中执行同构语句。addBatch只能接受SQL语句作为字符串,不是另一种说法。@andreypopp:老实说,我不知道你想做什么,比如批处理,还有字符串转义
PreparedStatement.setString
应该为您处理任何转义。这就是重点。@andreypopp:转义单引号正是PreparedStatement可以为您做的事情。关于addBatch():我不理解“异构语句”的含义,如果您有不同的语句(例如,不同的表),您将无法利用PostgreSQL的多行插入。但是,我还需要使用UUID,这就是我询问其他PostgreSQL驱动程序存在的原因。感谢您提供了注册自己的类型句柄的示例,但其他问题对我来说仍然没有解决。我注意到Postgres JDBC驱动程序似乎通过
getObject()
setObject()
方法支持
java.util.UUID
。这在什么地方有记录吗?这很好,但似乎并不总是有效:@user340535不幸的是,你链接到的那个问题毫无用处。没有提供源代码、细节或上下文,因此无法得出结论。另一方面,您可以运行我在这个答案中发布的源代码,以及在我的链接博客文章中发布的源代码。它一直在运行,对我来说没有问题。
UUID myGuid = rs.getObject("my_uuid_column_name", UUID.class); 
java.util.UUID uuid = java.util.UUID.randomUUID();
…
preparedStatement.setObject( nthPlaceholder++, uuid ); // Pass UUID to database.