Java 用于访问PostgreSQL数据库的JDBC驱动程序有哪些替代方案
我正在使用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数据结构,如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.