2011-02-04 64 views
5

我使用PostgreSQL的官方JDBC驱动程序,但我坚持了以下问题:什么是替代JDBC驱动程序访问PostgreSQL数据库

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

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

+7

不应该将任何逸出你使用`PreparedStatement`,并在其中设置值处理的呢?批量更新不适用于插入多行? – ColinD 2011-02-04 16:18:30

+0

你究竟是什么意思:*没有函数来逃避值消耗* – 2011-02-04 16:26:33

+0

@ColinD对于同类语句来说没关系,但我也需要批量执行异类语句,并且Statement.addBatch只能接受SQL语句作为String,不是另一种说法。 – andreypopp 2011-02-04 17:06:12

回答

9

这似乎是一些(除非我不明白)在使用JDBC的用户错误。 JDBC是一个相当丑陋的API,所以千万不要问是否可以优雅地做到这一点,只是问你是否可以做到这一点。

转义和插入多行应像@ColinD和@a_horse指出的那样通过Prepared语句和批处理操作来处理。在底层,我期望一个好的JDBC实现来完成你想要的事情(我对PostgreSQL的实现不熟悉)。

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

All that PostgreSQL can do is convert string literals to uuid. 

You can make use of this by using the data type 
org.postgresql.util.PGobject, which is a general class used to 
represent data types unknown to JDBC. 

You can define a helper class: 

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

Then the following piece of code will succeed: 

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

工作正常。

1
No support for PostgreSQL-ish data structures such as UUIDs. 

相反,所述current JDBC driver(9.2-1002 JDBC 4)Postgres 9.x的确实支持经由setObject​​和命令UUID。因为JDBC不能将UUID识别为数据类型,所以不能再比这更直接或更简单(在任何数据库,Postgres或任何其他数据库中)。

据我所知,没有必要创建一个辅助类作为另一个答案中的建议Yishai。

无需做任何铸造或穿过字符串。

enter image description here

参见my blog post更多的讨论和代码示例。

代码示例摘录:

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