2011-02-04 63 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.