MyTetra Share
Делитесь знаниями!
CrimeLab.java
29.04.2017
16:00
Раздел: Android - books - AndroidProgramming2e - 14 Базы данных SQLite
CrimeLab.java

CrimeLab.java

package com.bignerdranch.android.criminalintent;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import com.bignerdranch.android.criminalintent.database.CrimeBaseHelper;

import com.bignerdranch.android.criminalintent.database.CrimeCursorWrapper;

//Директива позволяет ссылаться на строковые константы из CrimeDbSchema.

// CrimeTable в форме CrimeTable.Cols.UUID (вместо того, чтобы вводить полное

// имя CrimeDbSchema.CrimeTable.Cols.UUID).

import com.bignerdranch.android.criminalintent.database.CrimeDbSchema.CrimeTable;

import java.util.ArrayList;

import java.util.List;

import java.util.UUID;

public class CrimeLab {

private static CrimeLab sCrimeLab;

private Context mContext;

private SQLiteDatabase mDatabase;

public static CrimeLab get(Context context) {

if (sCrimeLab == null) {

sCrimeLab = new CrimeLab(context);

}

return sCrimeLab;

}

private CrimeLab(Context context) {

mContext = context.getApplicationContext();

mDatabase = new CrimeBaseHelper(mContext)

.getWritableDatabase();

}

private static ContentValues getContentValues(Crime crime) {

ContentValues values = new ContentValues();

values.put(CrimeTable.Cols.UUID, crime.getId().toString());

values.put(CrimeTable.Cols.TITLE, crime.getTitle());

values.put(CrimeTable.Cols.DATE, crime.getDate().getTime());

values.put(CrimeTable.Cols.SOLVED, crime.isSolved() ? 1 : 0);

return values;

}

public void addCrime(Crime c) {

ContentValues values = getContentValues(c);

mDatabase.insert(CrimeTable.NAME, null, values);

}

// Метод update(String, ContentValues, String, String[]) начинается так же, как insert(…), — при вызове передается имя таблицы и объект ContentValues, который должен быть присвоен каждой обновляемой записи. Однако последняя часть отличается, потому что в этом случае необходимо указать, какие именно записи должны обновляться. Для этого строится условие WHERE (третий аргумент), за которым следуют значения аргументов в условии WHERE (завершающий массив String[]).

// Почему мы не вставили uuidString прямо в условие WHERE? Ведь это проще, чем использовать ? и передавать значение в String[]. Дело в том, что в некоторых случаях сама строка может содержать код SQL. Если вставить ее содержимое прямо в запрос, этот код может изменить смысл запроса или даже модифицировать базу данных. Подобные ситуации, называемые атаками внедрения SQL, безусловно нежелательны. Но при использовании ? ваш код будет делать именно то, что положено: значение интерпретируется как строковые данные, а не как код. Таким образом, лучше перестраховаться и привыкнуть к использованию заполнителя ?, который всегда приведет к желаемому результату независимо от содержимого строки.

public void updateCrime(Crime crime) {

String uuidString = crime.getId().toString();

ContentValues values = getContentValues(crime);

mDatabase.update(CrimeTable.NAME, values,

CrimeTable.Cols.UUID + " = ?",

new String[] { uuidString });

}

//вспомогательный метод, в котором будет вызываться метод query(…) для таблицы CrimeTable

private CrimeCursorWrapper queryCrimes(String whereClause, String[] whereArgs) {

Cursor cursor = mDatabase.query(

CrimeTable.NAME,

null, // Columns - null selects all columns

whereClause,

whereArgs,

null, // groupBy

null, // having

null // orderBy

);

return new CrimeCursorWrapper(cursor);

}

public List<Crime> getCrimes() {

List<Crime> crimes = new ArrayList<>();

CrimeCursorWrapper cursor = queryCrimes(null, null);

// Курсоры базы данных всегда устанавливаются в определенную позицию в результатах запроса. Таким образом, чтобы извлечь данные из курсора, его следует перевести к первому элементу вызовом moveToFirst(), а затем прочитать данные строки. Каждый раз, когда потребуется перейти к следующей записи, мы вызываем moveToNext(), пока isAfterLast(), наконец, не сообщит, что указатель вышел за пределы набора данных.

cursor.moveToFirst();

while (!cursor.isAfterLast()) {

crimes.add(cursor.getCrime());

cursor.moveToNext();

}

cursor.close();

return crimes;

}

public Crime getCrime(UUID id) {

CrimeCursorWrapper cursor = queryCrimes(

CrimeTable.Cols.UUID + " = ?",

new String[] { id.toString() }

);

try {

if (cursor.getCount() == 0) {

return null;

}

cursor.moveToFirst();

return cursor.getCrime();

} finally {

// Последнее, что осталось сделать, — вызвать close() для объекта Cursor. Не забывайте об этой служебной операции, это важно. Если вы забудете закрыть курсор, устройство Android начнет выдавать в журнал сообщения об ошибках. Что еще хуже, если ваша забывчивость будет проявляться хронически, со временем это приведет к исчерпанию файловых дескрипторов и сбою приложения. Итак, помните: курсоры нужно закрывать.

cursor.close();

}

}

}


 
MyTetra Share v.0.52
Яндекс индекс цитирования