Работа с базой данных SQLite

| 09.07.2014

ОС Андроид также позволяет хранить данные приложения в базе данных SQLite. Мы рассмотрим простейший пример создания базы данных, а также работу с ее данными (чтение, вставка, обновление и удаление записей).

Нам понадобиться создать:
1. MainActivity.java (здесь будет происходить основная логика)
2. DbHelper.java (вспомогательный класс, отвечающий за создание базы данных и ее обновление при изменении версии)
3. Db.java (класс, в котором мы поместим все основные методы работы с базой данных. Из Activity мы будем лишь вызывать эти методы)
4. Friend.java (класс модели данных)
5. activity_main.xml (разметка с пустым LinearLayout — все данные будем выводить только в лог)

Итак, создадим класс модели Friend. Здесь будет всего три свойства — id, имя (name) и email. Также добавим «геттеры» и «сеттеры».

Friend.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package ru.androiddocs.sqlite.model;
 
public class Friend {
 
    private Integer id;
    private String name;
    private String email;
 
    Friend(){}
 
    public Friend(Integer id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }		
}

Класс-помощник DbHelper отвечает за создание и обновление базы данных. Здесь мы помещаем два ключевых метода onCreate() и onUpgrade(). Первый срабатывает при первом создании базы данных. Если вдруг версия базы данных меняется (константа DATABASE_VERSION), то будет запущен метод onUpgrade(). В нашем случае при обновлении базы мы просто удаляем текущую базу данных и вызываем метод onCreate() для создания новой.

Обратите внимание, что также мы в константы поместили имя таблицы и наименования колонок. В методе onCreate() мы запускаем выполнение запроса на создание таблицы execSQL(), а затем делаем вставку трех строк с именем и email. Для передачи вставляемых данных используется коллекция ContentValues, где в качестве ключа выступает имя колонки, а значение — это значение для данного поля.

DbHelper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package ru.androiddocs.sqlite;
 
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
 
public class DbHelper extends SQLiteOpenHelper {
 
    private static final String LOG_TAG = "my_tag";
 
    public static final String TABLE_NAME = "friends";
 
    public static final String KEY_ID = "_id";
    public static final String KEY_NAME = "name";
    public static final String KEY_EMAIL = "email";
 
    private static final String DATABASE_NAME = "friendsDB";
    private static final int DATABASE_VERSION = 1;
 
    public DbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
 
    @Override
    public void onCreate(SQLiteDatabase db) {       
 
        db.execSQL("create table " + TABLE_NAME +" ("
            + KEY_ID + " integer primary key autoincrement," 
            + KEY_NAME + " text,"
            + KEY_EMAIL + " text" + ");");
 
        ContentValues cv = new ContentValues(); 
 
        cv.put(KEY_NAME, "Igor"); 
        cv.put(KEY_EMAIL, "email1@email.com"); 
        db.insert(TABLE_NAME, null, cv);
 
        cv.put(KEY_NAME, "Dima"); 
        cv.put(KEY_EMAIL, "email2@email.com"); 
        db.insert(TABLE_NAME, null, cv);
 
        cv.put(KEY_NAME, "Alex"); 
        cv.put(KEY_EMAIL, "email3@email.com"); 
        db.insert(TABLE_NAME, null, cv);
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    	
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);       
        this.onCreate(db);
    }
 
}

В сети встречаются примеры, где в класс DbHelper помещаются также другие методы для работы с базой данных. Однако, это некорректно, поскольку согласно документации есть такое определение данного класса:

A helper class to manage database creation and version management.

Нужные методы для работы с данными мы поместим в новый класс, который назовем Db.

Db.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package ru.androiddocs.sqlite;
 
import java.util.ArrayList;
import java.util.List;
 
import ru.androiddocs.sqlite.model.Friend;
 
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
 
public class Db {
 
    private static final String LOG_TAG = "my_tag";
    DbHelper dbHelper;
    Context context;
    Cursor cursor;
    SQLiteDatabase db;
    List<Friend> mFriendsList;
 
    public Db(Context context) {
        this.context = context;
        dbHelper = new DbHelper(context);
    }
    // возвращает количество записей в таблице
    public int getItemCount() {
 
        db = dbHelper.getReadableDatabase();
 
        cursor = db.query(DbHelper.TABLE_NAME, null, null, null, null, null, null);
        int cnt = cursor.getCount();
        cursor.close();
 
        return cnt;		
    }
    // метод для обновления email	
    public void updateEmail(String name, String newEmail){
        db = dbHelper.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(DbHelper.KEY_EMAIL, "newemail@newemail.com");		
        String[] args = new String[]{name};
        db.update(DbHelper.TABLE_NAME, cv, "name = ?", args);		
    }
    // метод для удаления строки по id	
    public void deleteItem(int id) {
        db = dbHelper.getWritableDatabase();
        db.delete(DbHelper.TABLE_NAME, DbHelper.KEY_ID + "=" + id, null);
    }
    // метод возвращающий коллекцию всех данных
    public List<Friend> getFriends() {
        cursor = db.query(DbHelper.TABLE_NAME, null, null, null, null, null, null);
        mFriendsList = new ArrayList<Friend>();
 
        if (cursor.moveToFirst()) {
 
            int idColInd = cursor.getColumnIndex(DbHelper.KEY_ID);
            int nameColInd = cursor.getColumnIndex(DbHelper.KEY_NAME);
            int emailColInd = cursor.getColumnIndex(DbHelper.KEY_EMAIL);
 
            do {	        
                Friend friend = new Friend(cursor.getInt(idColInd), 
                        cursor.getString(nameColInd), cursor.getString(emailColInd));            
                mFriendsList.add(friend);	            	          
            } while (cursor.moveToNext());
 
        } else {
            Log.d(LOG_TAG, "В базе нет данных!");
        }
 
        cursor.close();
 
        return mFriendsList;
 
    }
    // здесь закрываем все соединения с базой и класс-помощник
    public void close() {
        dbHelper.close();
        db.close();		
    }
 
}

Пустой layout.

activity_main.xml

1
2
3
4
5
6
7
8
9
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="ru.androiddocs.sqlite.MainActivity">
 
</LinearLayout>

Класс MainActivity, в котором помещаем основную логику.

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package ru.androiddocs.sqlite;
 
import java.util.List;
 
import ru.androiddocs.sqlite.model.Friend;
import android.support.v7.app.ActionBarActivity;
 
import android.os.Bundle;
import android.util.Log;
 
public class MainActivity extends ActionBarActivity {
 
    private static final String LOG_TAG = "my_tag";    
    Db db;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        db = new Db(this);
        // получаем количество записей в базе перед изменениями
        int mCount = db.getItemCount();		  
        Log.d(LOG_TAG, "Количество записей в базе:" + mCount);
 
        // обновляем запись с id = 1 (меняем email)
        db.updateEmail("Igor", "newemail@newemail.com");
 
        // удаляем запись с id = 3
        db.deleteItem(3);
 
        // выводим все имеющиеся записи в лог
        List<Friend> friends = db.getFriends();
        for (Friend friend : friends) {
            Log.d(LOG_TAG, "Имя: " + friend.getName() + " email: " + friend.getEmail());
        }
 
        db.close();
    }
}

Как видно из кода, мы вызываем различные методы класса Db для изменения данных в таблице Friends. В самом конце мы достаем все текущие данные и выводим их в лог. Думаю, будет понятно, почему получился именно такой результат.

Работа с базой данных SQLite

Использование интерфейса BaseColumns

Описание структуры таблиц базы данных также удобно делать с помощью внутреннего класса, реализующего интерфейс BaseColumns. В этом случае, колонку _ID описывать не нужно, т.к. она уже есть в «родителе». Это может быть описано примерно так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package ru.androiddocs.sqlite;
 
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
 
 
public class DbHelper extends SQLiteOpenHelper {
 
    public static final String TABLE_NAME = "friends";
 
    private static final String DATABASE_NAME = "friendsDB";
    private static final int DATABASE_VERSION = 1;
 
    public DbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
 
    public class FriendsContract implements BaseColumns {
        public static final String KEY_NAME = "name";
        public static final String KEY_EMAIL = "email";
    }
 
    private static final String CREATE_FRIENDS_TABLE_SQL = "create table " + TABLE_NAME +" ("
            + FriendsContract._ID + " integer primary key autoincrement,"
            + FriendsContract.KEY_NAME + " text,"
            + FriendsContract.KEY_EMAIL + " text" + ");";
 
    @Override
    public void onCreate(SQLiteDatabase db) {
 
        db.execSQL(CREATE_FRIENDS_TABLE_SQL);
 
        ContentValues cv = new ContentValues();
 
        cv.put(FriendsContract.KEY_NAME, "Igor");
        cv.put(FriendsContract.KEY_EMAIL, "email1@email.com");
        db.insert(TABLE_NAME, null, cv);
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        this.onCreate(db);
    }
 
}

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*