2013-06-24 5 views
2

Можно ли получить следующий доступный идентификатор для строки таблицы (которая будет автоматически создана при вставке строки в таблицу), поэтому я не буду вынужден вставлять эта строка в данный момент, чтобы получить ее?greenDao get auto-increment-ed ID

Чтобы быть более точным: у меня есть активность, которая содержит список, и каждый из этих элементов добавляется с использованием второго действия. Когда я завершаю добавление данных элемента во второе действие, я передаю этот элемент через объект parcelable (я применил Parcelable Interface к одному из классов держателей, созданного DaoGenerator). Значение id этого объекта не может быть null, передать его с помощью writeLong (id) и получить его с помощью readLong() в моих методах Parcelable, поэтому мне нужно автоматически генерировать значение 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 Идентификаторы начинаются с 1, вы можете установить идентификатор 0, и справиться с этим логически. поэтому, когда вы получаете объект в первом упражнении вы можете проверить идентификатор и установлены в нуль, если он равен 0.

+0

Приятный, я выбрал тот, у которого есть флаг Parcelable, и все выглядит нормально. Не могли бы вы немного объяснить, что вы хотели сказать: «Это создает слишком много жесткой связи»? – DoruAdryan

+0

уверен. ваше решение предполагает, что два действия будут доступны для доступа к базе данных, а состояние базы данных не изменится. В принципе, три отдельных компонента предполагают работать синхронно (плотно связаны) Для базового варианта это, вероятно, будет работать нормально, но в будущем у вас может быть другой способ добавления задач в базу данных (например, загрузка с сервера в фоновом режиме), что может влияют на счетчик автоматического увеличения. Это будет время от времени прерывать ваш алгоритм, и вы в конечном итоге обретете серьезную проблему, чтобы повторно создать неприятную ошибку. Если вы создадите объекты самостоятельно, вы избегаете таких неприятных ошибок в будущем. – yigit

+0

большое спасибо за ваш ответ и объяснение, yigit – DoruAdryan

1

Да есть среднее, чтобы сделать это , если вы используете ORM, это будет легко, как @ @%. Все, что вам нужно сделать, например, является:

  • Получить имя последовательности, которая генерирует идентификатор (всегда есть один, даже если вы не создавали его вручную).

  • Создание запроса SQL в коде, например:

    session.createSQLQuery ("SELECT NEXTVAL ('mySequenceName')");

  • Затем выполните запрос, чтобы получить уникальный идентификатор.

Надеюсь, это поможет.

Приветствие

+0

Спасибо за ваш ответ, Белкастет, но мне кажется, решение Yiğit является более легким и изящным. – DoruAdryan

+0

приветствуется :) –