2014-10-01 116 views
18

我在使用dropwizard,我想構建一個在實體中具有各種外鍵關係的REST應用程序。jdbi在插入時返回自動生成的值

例如給出如下3個表:

-- table persons 
CREATE TABLE PUBLIC.PERSONS(
    ID BIGINT DEFAULT NOT NULL AUTOINCREMENT, 
    FIRST_NAME VARCHAR(255), 
    LAST_NAME VARCHAR(255), 
    BIRTHDAY DATE, 
    ADDRESS_ID BIGINT NOT NULL, 
    CREATED TIMESTAMP DEFAULT 'current_timestamp', 
    MODIFIED TIMESTAMP 
); 
ALTER TABLE PUBLIC.PERSONS ADD CONSTRAINT PUBLIC.PK_PERSONS PRIMARY KEY(ID); 

-- table customers 
CREATE TABLE PUBLIC.CUSTOMERS(
    ID BIGINT DEFAULT NOT NULL AUTOINCREMENT, 
    PERSON_ID BIGINT NOT NULL, 
    STATUS_CODE VARCHAR(100) DEFAULT 'ACQUISITION' NOT NULL, 
    CREATED TIMESTAMP DEFAULT 'current_timestamp', 
    MODIFIED TIMESTAMP 
); 
ALTER TABLE PUBLIC.CUSTOMERS ADD CONSTRAINT PUBLIC.PK_CUSTOMERS PRIMARY KEY(ID); 

-- table addresses 
CREATE TABLE PUBLIC.ADDRESSES(
    ID BIGINT DEFAULT NOT NULL AUTOINCREMENT, 
    LINE_1 VARCHAR(255), 
    LINE_2 VARCHAR(255), 
    ZIP VARCHAR(255), 
    CITY VARCHAR(255), 
    COUNTRY_CODE VARCHAR(3), 
    PHONE VARCHAR(255), 
    FAX VARCHAR(255), 
    CREATED TIMESTAMP DEFAULT 'current_timestamp', 
    MODIFIED TIMESTAMP 
); 
ALTER TABLE PUBLIC.ADDRESSES ADD CONSTRAINT PUBLIC.PK_ADDRESSES PRIMARY KEY(ID); 

-- and following forign key constraints: 
ALTER TABLE PUBLIC.PERSONS ADD CONSTRAINT 
    PUBLIC.FK_PERSON_ADDRESS FOREIGN KEY(ADDRESS_ID) 
    REFERENCES PUBLIC.ADDRESSES(ID) ON DELETE SET NULL NOCHECK; 

ALTER TABLE PUBLIC.CUSTOMERS ADD CONSTRAINT 
    PUBLIC.FK_CUSTOMER_PERSON FOREIGN KEY(PERSON_ID) 
    REFERENCES PUBLIC.PERSONS(ID) ON DELETE SET NULL NOCHECK; 

我已經開始實施customerDAO讀取客戶表中的D出現引用同一個SQL查詢表的數據,這是不是很複雜:

@RegisterMapper(CustomerResultMapper.class) 
public interface CustomerDAO { 

    @SqlQuery("select p.id as person_id, " 
      + "p.first_name, p.last_name, p.birthday, " 
      + "c.id as customer_id, c.status_code, " 
      + "a.id as address_id, a.line_1, a.line_2, a.zip, " 
      + "a.city, a.country_code, a.phone, a.fax " 
      + "from customers c, persons p, addresses a " 
      + "where c.id = :id " 
      + "and c.person_id = p.id " 
      + "and p.address_id = a.id") 
    public Customer findCustomerById(@Bind("id") long id); 
} 

(爲簡便起見,我跳過映射器,因爲這不是我的實際問題)

現在我要插入一個新客戶,我擁有所有必需的數據,包括屬於參考表格中的數據。

我無法找到一個方法如何使用jdbi註釋執行多個查詢,所以我想,我必須爲每個表創建一個DAO方法,並從java中插入數據,手動更新外鍵引用。

但這也不起作用,因爲我找不到插入後讀取自動生成的ID值的方法。

任何想法我可以如何解決這個問題,所以我可以保持引用正確?

回答

31

沒關係,我發現在此期間解決方案,至少如何讓自動生成的密鑰:

在DAO

,添加註釋@GetGeneratedKeys,確保該方法的返回值相匹配的生成的密鑰值:

@SqlUpdate("insert into addresses (line_1) values ('address line 1')") 
@GetGeneratedKeys 
public long insertAddress(); 

在你的資源,那麼,你可以簡單地使用返回值:

long id = customerDAO.insertAddress(); 
System.out.println("Found id " + id); 

這個工程來獲取生成的科Ÿ對於一個語句,但在我的情況下,我仍然需要進行多個查詢並手動填寫正確的引用。

如果任何人有一個想法,我可以如何簡化這個過程,並讓參考資料自動填寫,我仍然會有興趣聽到。

謝謝。

+0

您是否嘗試過製作方法返回一個列表? – 2014-10-07 03:30:27

+0

不,據我瞭解,GetGeneratedKeys Annotation返回值asint或long,你不能返回一個列表。 – 2014-10-09 00:24:58

+2

看着org.skife.jdbi.v2.GeneratedKeys,它可能會起作用。代碼調用返回ResultSet的java.sql.Statement.getGeneratedKeys()。試一試。 – 2014-10-09 17:49:49

13

有了postgres,你不僅可以獲得一個,而且可以獲得所有自動生成的值。

你可以通過改變@SqlUpdate到@SqlQuery和使用INSERT ... RETURNING *,假設這樣做,你有地址的映射:

@SqlQuery("insert into addresses (line_1) values ('address line 1') returning *") 
public Address insertAddress(@BindBean Address address); 
+1

那真棒嗎? – Christian 2016-02-02 12:54:26

+1

這應該是答案。 – 2016-09-30 14:49:37

+0

太棒了,讓我的工作輕鬆+1 – BeginnersSake 2017-11-21 13:50:32

相關問題