Запросы и работа с курсорами в SQLite на Android - PullRequest
21 голосов
/ 14 июля 2009

Не уверен, что я единственный, кто чувствует это ...

Я нахожу работу с API sqlite в Android полной болью в заднице и разрушением красивой души. Кто-нибудь получил какие-нибудь советы / помощники, чтобы облегчить мне жизнь?

Вот пример того, о чем я говорю.

//create code

db.execSQL("CREATE TABLE " + CUSTOMER_TABLE_NAME + " ("
                        + GENERIC_ID_KEY+ " INTEGER PRIMARY KEY NOT NULL, " 
                        + PHONE_KEY + " INTEGER NOT NULL, "
                        + CUSTOMER_NAME_KEY+ " TEXT NOT NULL, "
                        + EMAIL_KEY + " TEXT NOT NULL, "
                        + ADDRESS_KEY +" TEXT);");


//get code
    Cursor mCursor = mDb.query(true, CUSTOMER_TABLE_NAME, new String[] {GENERIC_ID_KEY,
                        ADDRESS_KEY, PHONE_KEY, EMAIL_KEY,CUSTOMER_NAME_KEY}, GENERIC_ID_KEY + "=" + customerDbId, null,
                                null, null, null, null);

        Customer customer = new Customer (customerDbId, (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(CUSTOMER_NAME_KEY)),
                            (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(PHONE_KEY)),
                            (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(EMAIL_KEY)),
                            (CharSequence)mCursor.getString(mCursor.getColumnIndexOrThrow(ADDRESS_KEY)));

Это простой пример создания простого объекта customer из запроса базы данных; часть моего кода намного более противна чем это. Подобные ручные запросы приводят ко всем видам ошибок, которые я не нахожу до времени выполнения.

Любые советы очень ценятся!

Хорошо, после подсказок ниже у меня теперь есть это:

  db.execSQL("CREATE TABLE customer (_id INTEGER PRIMARY KEY NOT NULL, " 
                        + "phone_number INTEGER NOT NULL, "
                        + "name TEXT NOT NULL, "
                        + "email TEXT NOT NULL, "
                        + "address TEXT);");


    //get code
String q = "SELECT * FROM customer WHERE _id = " + customerDbId +";"
        Cursor mCursor = mDb.rawQuery(q, null);

        Customer customer = new Customer (mCursor);

в Customer, я получаю доступ к таким полям

mName = cursor.getString(2)

Ах, я чувствую себя намного лучше:)

Приветствие Si

Ответы [ 2 ]

39 голосов
/ 14 июля 2009
  1. Не используйте объекты модели, если вам это не нужно. Я пришел к выводу, что, если нет существенной бизнес-логики, которая может быть представлена ​​только через объекты моделей, они доставляют больше хлопот, чем стоят на мобильной платформе.
  2. Предполагая, что вы застряли с объектами модели, пусть они загружают себя из Cursor, вместо того, чтобы пытаться передать множество параметров.
  3. query() гораздо более многословно, чем rawQuery() для ограниченной добавленной стоимости, если вы знаете SQL.
  4. Сборка вашего предложения CREATE TABLE с помощью конкатенации является навязанной болью, не обязательной для SQLite или Android.
  5. Не используйте getColumnIndexOrThrow() из пользовательского кода. Вы написали запрос, так что вы знаете, в каком порядке возвращаются столбцы. Используйте что-то вроде getColumnIndexOrThrow() только в том случае, если вы создаете какую-то абстрактную библиотеку, которая не знает подробности того Курсора, который ей был дан.
  6. String наследуется от CharSequence, поэтому все эти броски можно отбросить.
3 голосов
/ 15 июля 2009

Я протестировал многие из своих SQL в SQLite, прежде чем скопировать их в Android в виде строк. Мне легче отлаживать, когда я могу напрямую взаимодействовать с командной строкой.

Другой метод, который я использую, - это сохранение как можно большего количества моих запросов, как строковых констант или строковых ресурсов.

Вам также не нужен SQL, такой как INTEGER NOT NULL, так как SQLite использует типизацию утилит / манифест. Это действительно помогает для сходства типов, хотя ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...