2011-02-04 41 views
5

Tôi đang sử dụng trình điều khiển JDBC chính thức cho PostgreSQL là gì, nhưng tôi bị mắc kẹt với những vấn đề sau:thay thế cho trình điều khiển JDBC cho cơ sở dữ liệu truy cập PostgreSQL

  • Không hỗ trợ PostgreSQL-ish cấu trúc dữ liệu như UUIDs .
  • Mức độ lạ thường của JDBC, chẳng hạn như:
    • Không có chức năng nào để thoát khỏi các giá trị do PostgreSQL tiêu thụ.
    • Hỗ trợ có giới hạn để thực hiện các câu lệnh không đồng nhất theo lô.
    • Không viết lại nhiều câu lệnh chèn vào câu lệnh chèn đơn khi chèn nhiều hàng vào một bảng.

Vì vậy, câu hỏi - là có bất kỳ trình điều khiển cơ sở dữ liệu PostgreSQL có thể tận dụng đầy đủ sức mạnh của PostgreSQL không có nhiều soạn sẵn? Tôi cũng sử dụng ngôn ngữ Scala để phát triển, do đó, nếu trình điều khiển được thiết kế đặc biệt cho Scala thì nó sẽ rất tuyệt vời.

+7

nên không bất kỳ thoát được xử lý cho bạn bằng cách sử dụng một 'PreparedStatement' và thiết lập giá trị trong nó? Bản cập nhật hàng loạt sẽ không hoạt động để chèn nhiều hàng? – ColinD

+0

Chính xác bạn có ý nghĩa gì với: * Không có chức năng nào để thoát các giá trị để tiêu thụ * –

+0

@ColinD Đó là ok cho các câu lệnh đồng nhất, nhưng tôi cũng cần thực hiện các câu lệnh không đồng nhất theo lô và Statement.addBatch chỉ chấp nhận các câu lệnh SQL như String, không phải là một tuyên bố khác. – andreypopp

Trả lời

9

Một số điều này có vẻ là (trừ khi tôi không hiểu) lỗi người dùng khi sử dụng JDBC. JDBC là một API khá xấu xí, vì vậy không bao giờ hỏi bạn có thể làm điều đó một cách thanh lịch hay không, chỉ cần hỏi bạn có thể làm được điều đó không.

Việc thoát và chèn nhiều hàng phải được xử lý, như @ColinD và @a_horse đã chỉ ra, với các câu lệnh được chuẩn bị và hoạt động theo lô. Dưới mui xe, tôi mong đợi một việc thực hiện JDBC tốt để làm những thứ bạn muốn (tôi không quen thuộc với việc triển khai PostgreSQL).

Về UUIDs, here là một giải pháp:

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

Cảm ơn bạn đã cung cấp ví dụ về cách đăng ký các loại xử lý riêng, nhưng các vấn đề khác vẫn chưa được giải quyết cho tôi. – andreypopp

4

Trình điều khiển hỗ trợ các lệnh theo đợt để tăng tốc độ chèn số lượng lớn.

Và sử dụng báo cáo đồng loạt là rất nhiều di động hơn so với sử dụng cú pháp INSERT độc quyền (và như xa như tôi có thể nói, không có sự khác biệt lớn giữa một chèn nhiều hàng và batched chèn)

Check-out PreparedStatement. addBatch()

Lý do tại sao UUID không được hỗ trợ có thể là UUID không phải là một phần của lõi Postgres, chỉ là một mô-đun đóng góp.

Sửa
Về thực hiện báo cáo không đồng nhất

Người tài xế Postgres không hỗ trợ loại khác nhau của các báo cáo trong một lô.

Các công việc sau tốt:

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

Mặc dù bạn mất tự động thoát mà PreparedStatement mang đến cho bạn.

+0

Nhưng, tôi cũng cần phải làm việc với UUID, đó là lý do tại sao tôi hỏi về sự tồn tại của các trình điều khiển PostgreSQL khác. – andreypopp

0

Hãy xem O/R Broker, mà là một thư viện Scala JDBC-based để truy cập cơ sở dữ liệu quan hệ.

3

Tôi nhận thấy điều này không trả lời toàn bộ câu hỏi của bạn, nhưng hy vọng nó sẽ hữu ích như nhau.

Tôi đang sử dụng Java 6 và Postgres 8.4. Người lái xe tôi đang sử dụng là trong tập tin POM Maven của tôi như:

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

Tôi đang sử dụng PreparedStatement.getObject()PreparedStatement.setObject() với lớp java.util.UUID Java để lấy và lưu trữ UUIDs.

Ví dụ:

pstm.setObject(1, guid); //where pstm is a PreparedStatement and guid is a UUID 

và:

//where rs is a ResultSet 
UUID myGuid = (UUID) rs.getObject("my_uuid_column_name"); 

trình tốt.

+0

Tôi nhận thấy rằng trình điều khiển JDBC Postgres dường như hỗ trợ 'java.util.UUID' thông qua phương thức' getObject() 'và' setObject() '. Đây có phải là tài liệu ở đâu đó không? –

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

Ngược lại, các current JDBC driver (9,2-1002 JDBC 4) cho Postgres 9.x không thực sự hỗ trợ UUID qua setObjectgetObject lệnh. Bạn không thể nhận được bất kỳ trực tiếp hay đơn giản hơn (trong bất kỳ cơ sở dữ liệu nào, Postgres hay bất kỳ cơ sở dữ liệu nào khác) vì JDBC không nhận dạng UUID như một kiểu dữ liệu.

Theo như tôi có thể nói, không cần tạo lớp trợ giúp như được đề xuất trong câu trả lời khác của Yishai.

Không cần thực hiện bất kỳ thao tác truyền hoặc truyền qua chuỗi nào.

enter image description here

Xem my blog post để thảo luận nhiều hơn và mã ví dụ.

Mã ví dụ trích đoạn:

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

Thật tuyệt vời, nhưng nó không phải lúc nào cũng hoạt động: http://stackoverflow.com/questions/17969431/postgres-uuid-jdbc-not-working – user340535

+0

@ user340535 Thật không may, câu hỏi mà bạn liên kết là vô ích. Không có mã nguồn, chi tiết hoặc ngữ cảnh nào được cung cấp, vì vậy không thể rút ra kết luận. Mặt khác, bạn có thể chạy mã nguồn của tôi được đăng trong câu trả lời này và được đăng trong bài đăng trên blog được liên kết của tôi. Nó đã chạy liên tục mà không có vấn đề gì đối với tôi. –

Các vấn đề liên quan