2013-06-24 82 views
2

是否有任何方式讓我得到下一個表格行的可用ID(當在表中插入一行時會自動創建),所以我不會被強制插入在給定的時間行,以獲得它?greenDao得到自動遞增編號

更確切地說:我有一個包含listview的活動,並且每個這些項目都是使用第二個活動添加的。當我在第二個活動中添加項目詳細信息時,我將該項目傳遞給一個parcelable對象(我將Parcelable Interface實現爲DaoGenerator創建的其中一個持有者類)。該對象的id值不能爲空,要用writeLong(id)傳遞它,並在我的Parcelable方法中用readLong()接收它,所以我必須自動生成id值,方法是將當前項目已經插入數據庫。 我想要做的是:生成這些ID(不插入數據庫中的項目),將該項目傳遞給第一個活動,當用戶決定保存列表中的所有項目時,我會將它們全部添加到數據庫在一次交易中。

一些示例代碼,我有個大氣壓:

public class Question implements Parcelable { 

private Long id; 
private String questionContent; 

// KEEP FIELDS - put your custom fields here 
// KEEP FIELDS END 

public Question() { 
} 

public Question(Long id) { 
    this.id = id; 
} 

public Question(Long id,String questionContent) { 
    this.id = id; 
    this.questionContent = questionContent; 
} 

public Long getId() { 
    return id; 
} 

public void setId(Long id) { 
    this.id = id; 
} 


// KEEP METHODS - put your custom methods here 

// begin Parcelable implementation 

@Override 
public int describeContents() { 
    return 0; 
} 

@Override 
public void writeToParcel(Parcel dest, int flags) { 

    dest.writeLong(id); 
    dest.writeString(questionContent); 

} 

public static final Parcelable.Creator<Question> CREATOR = new Parcelable.Creator<Question>() { 
    public Question createFromParcel(Parcel in) { 
     return new Question(in); 
    } 

    public Question[] newArray(int size) { 
     return new Question[size]; 
    } 
}; 

private Question(Parcel in) { 

    id = in.readLong(); 
    questionContent = in.readString(); 
} 

// end Parcelable implementation 
// KEEP METHODS END 

}

,這是我如何創建和發送的項目清單:

Question questionHolder = new Question(
            null,          etItemContent.getText().toString()          .trim(),); 

          Log.d(LOG_TAG, "question id = " 
            + questionHolder.getId()); 

// inserting it here, would auto-generate the ID I required, 
// but I would like to do that to all of the items in the first Activity (containing the list of all of the items)         
// questionDao.insert(questionHolder); 

          Log.d(LOG_TAG, "question id = " 
            + questionHolder.getId()); 

          // add item to intent 
          Bundle b = new Bundle(); 
          b.putParcelable(IMPORTANCE_TAG, questionHolder); 

          Intent intent = new Intent(); 
          intent.putExtras(b); 

          setResult(RESULT_OK, intent); 
          QuestionItemActivity.this.finish(); 

回答

2

我不會建議這樣做,因爲它會造成太多的緊密耦合。 是在我腦海中一對夫婦的選擇:

  • 如果字段爲空,我建議增加一個標誌parcelable表示,如果該字段爲空或不是。 所以寫的時候

    if(id == null) { 
        out.writeByte((byte)0); 
    } else { 
        out.writeByte((byte)1); 
        out.writeLong(id); 
    } 
    

    和閱讀

    boolean hasId = in.readByte() == 1; 
    if(hasId) { 
        id = in.readLong(); 
    } 
    
  • 另一種選擇時,因爲DB IDS從1日開始,您可以設置ID爲0,邏輯上處理這個問題。所以,當你接收對象在你的第一個活動,你可以檢查ID和設置爲null,如果是0

+0

不錯的一個,我選擇了Parcelable標誌,看起來沒問題。你會介意一些你想說的話:「它會產生太多的緊密耦合」? – DoruAdryan

+0

當然。您的解決方案假定兩個活動將訪問數據庫,並且數據庫狀態不會在兩者之間改變。基本上,3個獨立的組件假定在同步工作(緊密耦合) 對於基本情況,這可能會正常工作,但在將來,您可能有另一種方式向數據庫添加任務(例如從服務器在後臺下載)影響自動遞增計數器。這將打破你的算法時間,並且最終你會很難重新產生令人討厭的錯誤。 通過讓對象自成一體,您可以避免將來出現這種令人討厭的錯誤。 – yigit

+0

非常感謝您的回答和解釋,yigit – DoruAdryan

1

是有一個平均要做到這一點,如果你使用的是ORM,這很容易!@#%。 所有你必須例如做的是:

  • 獲取生成的ID序列名(總有一個,即使你沒有手動創建它)。

  • 在你的代碼,例如創建一個SQL查詢:

    執行Session.createSQLQuery( 「SELECT NEXTVAL( 'mySequenceName')」);

  • 然後執行查詢來檢索唯一ID。

我希望這會有所幫助。

乾杯

+0

謝謝您的回答,Belkacem,但似乎yigit的解決方案是更簡單,更優雅。 – DoruAdryan

+0

不客氣:) –