2014-12-02 52 views
2

我需要插入與Order及其相應的Detail相關的數據。Android - 如何將與兩個表相關的數據傳遞給內容提供者的插入方法

如果沒有ContentProvider我會做這樣的事情:

public boolean insertOrder(Order order, ArrayList<OrderDetail> items) { 
    boolean wasSuccessful = false; 
    ContentValues cvOrder = new ContentValues(); 
    cvPedido.put(ORDER_CUSTOMER_ID, order.getCustomerId()); 
    cvPedido.put(ORDER_CUSTOMER_NAME, order.getCustomerName());  
    String insertQuery = "INSERT INTO " + ORDER_DETAIL_TABLE 
      + " VALUES (?,?)"; 
    //... 
    try { 

     this.openWriteableDB(); 
     SQLiteStatement statement = db.compileStatement(insertQuery); 
     db.beginTransaction(); 
     long idOrder = db.insertOrThrow(ORDER_TABLE, null, cvOrder); 
     if (idOrder > 0) { 


      for (int i = 0; i < items.size(); i++) {  
       OrderDetail detail=items.get(i); 
       statement.clearBindings(); 
       statement.bindString(1, detail.getDescription); 
       statement.bindDouble(2, detail.getPrice); 
       //... 
       statement.execute(); 
      } 
      db.setTransactionSuccessful(); 
      wasSuccessful = true;    
     } 

    } finally { 
     db.endTransaction(); 
     this.closeDB(); 
    } 
    return wasSuccessful; 
} 

的問題是,現在我想用一個ContentProvider,我不知道如何處理這種情況下做的,其中約兩個數據或多個表必須傳遞給一個CRUD操作,知道insert操作只接受兩個參數:

@Override 
    public Uri insert(Uri uri, ContentValues values) { 

    } 

,當你有一個交易插入關係數據,你在ContentProvider的做些什麼N +

在此先感謝。

回答

3

您應該使用ContentProviderOperation。由於這是您的ContentProvider,您可以確保applyBatch()將執行交易中的所有操作。所有標準內容提供商也確保這種情況。

查看我的博客post about ContentProviderOperation一般和我的其他帖子關於how to use withBackReference() to access results of previous operations - 您需要訪問orderId

一個重要的警告:一個批次的所有ContentProviderOperations必須使用相同的權限 - 但可以使用不同的URI!在你的情況下,這應該沒有問題。

+1

對不起,我沒有把這個標記爲答案,但因爲我不得不回到IOS項目,然後其他的東西出現了,直到昨天我才能回到我的android項目並確認你的解決方案是正確的答案。 – eddy 2015-04-10 12:24:53

+1

沒問題。感謝您記住這一點,並在經過這麼長時間後提升我!這應該是值得的SO獎勵自己。 – 2015-04-10 13:59:56

+1

當你把我放在正確的軌道上,你真的值得。再次非常感謝你,對不起,如果花了我很多時間來標記這個答案,但因爲我在空閒時間學習Android,所以我不得不推遲這個個人項目一段時間。最後如果有人覺得有用,這裏是一個例子,說明如何在Content Provider中實現'applyBatch'方法https://github.com/google/iosched/blob/master/android/src/main/java/com /google/samples/apps/iosched/provider/ScheduleProvider.java – eddy 2015-04-10 16:09:43

0

你可以設計內容提供者來鏡像你的SQLite表,並且使用與上面相同的代碼insertOrder

只需使用內容提供商的insert爲每個表(URI),進行類似的操作在您的insertOrder方法

另一種選擇是定義的內容提供商的URI把你Orderitems的組合,並實現在提交到底層數據模型之前解析您自己的內容提供者。

+0

你認爲你可以給我一個例子嗎? – eddy 2014-12-03 02:47:16

+1

對不起,我不認爲我想你想法 – Axel 2014-12-03 11:04:30

+2

我認爲這個想法是使用一個特殊的URI,例如'content:// authority/orderwithdetails/orderId'。問題是:在這種情況下,這不會起作用,因爲有很多細節可以插入,而不僅僅是一個。 – 2014-12-08 19:58:15

1

您可以將所有數據放入ContentValues並擁有提供者。您必須獲得有關訂單詳情的一點創意。

在psuedo代碼下面,我創建一個關鍵的「詳細信息」,用一個整數然後是項目。

  ContentValues values = new ContentValues(); 
      values.put(ORDER_ID,orderid); 

      for (int i = 0; i < items.size(); i++) {  
      values.put("DETAIL" + Integer.ToString(i),items.get(i)); 
      } 

      Uri uri = context.getContentResolver().insert(
        ORDER_URI, values); 

然後在內容提供商中對其進行分類。

@Override 
public Uri insert(Uri uri, ContentValues values) { 

    int uriType = sURIMatcher.match(uri); 
    SQLiteDatabase sqlDB = database.getWritableDatabase(); 
    long id = 0; 
    switch (uriType) { 
    case ORDER: 
     // trim name and description 
     trimNameDescriptions(values); 
     try { 
      id = sqlDB.insertOrThrow(ORDERS_TABLE, 
        null, values); 
     Integer i =0; 
     do (values.containsKey("DETAIL" + i.toString()){ 
     ContentValues v = new ContentValues(); 
     v.put("DETAIL",values.get("Detail" + i.toString())); 
     v.put("ORDERID",id); 
      //ACTUALLY CALL THE INSERT METHOD OF THE PROVIDER 
     insert(DETAIL_URI,v); 
     i+=1; 
    } 
+1

那麼沒有交易需要? – Axel 2014-12-03 12:05:33

+0

好吧,你可以再調整一下,並在那裏進行交易。我只是展示瞭如何使用ContentValues來傳遞信息。如果我是你,我會在你的問題中使用代碼或修改訂單,以便將它寫入ContentValues。 – danny117 2014-12-03 21:16:07

+0

謝謝@ danny117。那麼ContentProviders基本上只與當時的一個表一起工作? – eddy 2014-12-05 12:22:25

相關問題