2009-11-20 32 views
14

Tôi đang sử dụng iBatis/Java và Postgres 8.3. Khi tôi làm một chèn trong ibatis tôi cần id trả lại.
Tôi sử dụng bảng sau đây để mô tả câu hỏi của tôi:
CREATE TABLE sometable (id serial NOT NULL, somefield VARCHAR(10));
Trình tự sometable_id_seq được tự động phát bằng cách chạy câu lệnh tạo.Làm thế nào để trả về id trên Chèn với Ibatis (với từ khóa RETURNING)

Tại thời điểm tôi sử dụng bản đồ sql sau:

<insert id="insertValue" parameterClass="string" > 
INSERT INTO sometable (somefield) VALUES (#value#); 
<selectKey keyProperty="id" resultClass="int"> 
    SELECT last_value AS id FROM sometable_id_seq 
</selectKey> 
</insert> 

Có vẻ như đây là cách ibatis thu hồi id mới chèn vào. Đầu tiên, Ibatis chạy một câu lệnh INSERT và sau đó nó yêu cầu trình tự cho id cuối cùng.
Tôi nghi ngờ rằng thao tác này sẽ hoạt động với nhiều lần chèn đồng thời. (discussed in this question)

Tôi muốn sử dụng câu lệnh sau đây với ibatis:
INSERT INTO sometable (somefield) VALUES (#value#) RETURNING id;

Nhưng khi tôi cố gắng sử dụng nó trong một ibatis <insert> sqlMap không trả lại id. Có vẻ như cần thẻ <selectKey>.

Vì vậy, đây là câu hỏi:

Tôi có thể sử dụng câu lệnh trên với ibatis như thế nào?

Trả lời

15

Yếu tố <selectKey> là một đứa trẻ của phần tử <insert> và nội dung của nó được thực hiện trước khi chính INSERT tuyên bố. Bạn có thể sử dụng hai cách tiếp cận.

Fetch chìa khóa sau khi bạn đã chèn các bản ghi

cách tiếp cận này hoạt động phụ thuộc vào trình điều khiển của bạn. Threading có thể là một vấn đề với điều này.

Tìm nạp các phím trước khi chèn bản ghi

Cách tiếp cận này tránh được các vấn đề luồng nhưng là làm việc nhiều hơn. Ví dụ:

<insert id="insert"> 
    <selectKey keyProperty="myId" 
      resultClass="int"> 
    SELECT nextVal('my_id_seq') 
    </selectKey> 
    INSERT INTO my 
    (myId, foo, bar) 
    VALUES 
    (#myId#, #foo#, #bar#) 
</insert> 

Về phía Java sau đó bạn có thể làm

Integer insertedId = (Integer) sqlMap.insert("insert", params) 

này sẽ cho bạn chìa khóa được lựa chọn từ các chuỗi my_id_seq.

+0

giải pháp này giải quyết những lo lắng về đồng thời của tôi. Nó chỉ để lại câu hỏi nếu ibatis có thể làm việc với cú pháp INSERT INTO .. ​​RETURING .. – Christoph

9

Dưới đây là ví dụ đơn giản:

<statement id="addObject" 
     parameterClass="test.Object" 
     resultClass="int"> 
     INSERT INTO objects(expression, meta, title, 
     usersid) 
     VALUES (#expression#, #meta#, #title#, #usersId#) 
     RETURNING id 
</statement> 

Và trong mã Java:

Integer id = (Integer) executor.queryForObject("addObject", object); 
object.setId(id); 

Bằng cách này hơn tốt hơn so với sử dụng:

  1. Sẽ đơn giản;
  2. Nó không yêu cầu phải biết tên trình tự (thường được ẩn từ các nhà phát triển postgresql).
+0

Đó sẽ là câu trả lời tôi đã tìm kiếm ... nhưng nó không hoạt động: khi sử dụng executer.queryForObject id được trả về, nhưng không có gì được chèn, và khi tôi sử dụng executer.insert hàng được chèn, nhưng null là trả lại – Christoph

+0

Điều đó rất lạ, bởi vì tôi sao chép và dán mã công việc của mình. Ngoài ra tôi không hiểu - làm thế nào bạn có thể nhận được id mà không cần thêm bản ghi mới? Bạn thấy gì trong nhật ký iBatis SQL? – leonidv

+2

Có vẻ như một trong các bạn đã bật tính năng tự động cam kết và người khác thì không. – inanutshellus

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