[Перевод] Применение SQLiteOpenHelper и Database Inspector в Android-разработке

Автор статьи, перевод которой мы публикуем сегодня, хочет рассказать об использовании баз данных SQLite в Android-разработке. В частности — он коснётся тут двух вопросов. Во-первых — речь пойдёт о классе SQLiteOpenHelper, который применяется для работы с базами данных в коде приложений. Во-вторых — он уделит определённое внимание инструменту Database Inspector, инспектору баз данных, встроенному в Android Studio.

xqbatvtxsqpn_lm9jlsdcgwrjxy.jpeg

Что такое SQLite?


SQLite — это опенсорсная реляционная СУБД, похожая на MySQL. SQLite входит в состав стандартной библиотеки Android, где реализован движок базы данных, не нуждающийся в применении клиент-серверной архитектуры, не требующий особой настройки, поддерживающий транзакции. Для работы SQLite не нужен сервер баз данных. Всё, что нужно, хранится в обычных файлах. Полноценная БД SQLite, в которой имеется множество таблиц, триггеров, индексов и представлений, содержится в единственном, самом обыкновенном файле. Стандартная поддержка СУБД SQLite имеется во всех мобильных телефонах и в большинстве компьютеров. При этом работа с SQLite не требует решения задач по администрированию или настройке баз данных.

Android-разработчик, для выполнения CRUD-операций из своего приложения, может пользоваться пакетом android.database.sqlite.SQLiteDatabase, в котором реализованы все необходимые API.

Класс SQLiteOpenHelper


SQLiteOpenHelper — это класс, встроенный в пакет android.database.sqlite.SQLiteDatabase. Это — вспомогательный класс, который отвечает за создание баз данных SQLite и за управление их версиями. Для того чтобы воспользоваться возможностями этого класса, нужно создать его подкласс, в котором надо переопределить два метода — onCreate() и onUpgrade(). Этот класс позволяет открывать существующие базы данных, создавать новые базы данных и обновлять версии баз данных.

▍Метод onCreate ()


Метод onCreate() вызывается при создании базы данных. Он, в процессе жизненного цикла приложения, вызывается лишь один раз. А именно, его вызов производится при первом обращении к методу getReadableDatabase() или getWritableDatabase(). Эти методы принадлежат классу SQLiteOpenHelper.

В следующем примере показано создание экземпляра класса DatabaseHelper, являющегося наследником SQLiteOpenHelper:

DatabaseHelper dbh = new DatabaseHelper(getApplicationContext());

Вот код конструктора DatabaseHelper:
public DatabaseHelper(Context context) {
    super(context,dbName,null,version);
    context=this.context;
}

Класс SQLiteOpenHelper вызывает метод onCreate() после создания базы данных и создания экземпляра класса SQLiteDatabase. Этот метод, напомним, вызывается лишь один раз, при создании базы данных:
@Override
public void onCreate(SQLiteDatabase db) {
    try {
        db.execSQL(CREATE_TABLE);
    } catch (Exception e) {
    }
}

▍Метод onUpgrade ()


Метод onUpgrade() вызывается в тех случаях, когда нужно обновить версию существующей базы данных:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL(DROP_TABLE);
    onCreate(db);
}

▍Пример


Создадим простое Android-приложение и разберём практический пример работы с классом SQLiteOpenHelper. Это приложение, применяя данный класс, позволит нам добавлять записи о работниках некоей компании в таблицу Empdata базы данных Company.db.

Приложение имеет весьма простой интерфейс, описанный в файле activity_main.xml.

6a9c4af81f1ee8a9c40667a6ee1665aa.jpg

Интерфейс приложения

Вот содержимое файла MainActivity.java:

package www.sqliteopenhelper.sqliteopenhelper;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText edtEmpName = findViewById(R.id.edtName);
        EditText edtDesig = findViewById(R.id.edtDesig);
        EditText edtSalary = findViewById(R.id.edtSalary);
        Button btnSave = findViewById(R.id.btnSave);
        DatabaseHelper dbh= new DatabaseHelper(getApplicationContext());
        btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                   Employee objEmp = new Employee(edtEmpName.getText().toString(),edtDesig.getText().toString(),Integer.parseInt(edtSalary.getText().toString()));

                if(dbh.InsertEmployee(objEmp))
                    Toast.makeText(getApplicationContext(),"Record inserted successfully",Toast.LENGTH_LONG).show();
                else
                    Toast.makeText(getApplicationContext(),"Record not inserted",Toast.LENGTH_LONG).show();
            }
        });
    }
}

Вот содержимое Employee.java:
package www.sqliteopenhelper.sqliteopenhelper;

public class Employee {
    private String employeeName;
    private String employeeDesig;
    private int employeeSalary;

    public Employee() {
    }

    public Employee(String employeeName, String employeeDesig, int employeeSalary) {
        this.employeeName = employeeName;
        this.employeeDesig = employeeDesig;
        this.employeeSalary = employeeSalary;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public String getEmployeeDesig() {
        return employeeDesig;
    }

    public int getEmployeeSalary() {
        return employeeSalary;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public void setEmployeeDesig(String employeeDesig) {
        this.employeeDesig = employeeDesig;
    }

    public void setEmployeeSalary(int employeeSalary) {
        this.employeeSalary = employeeSalary;
    }
}

Вот файл DatabaseHelper.java:
package www.sqliteopenhelper.sqliteopenhelper;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {
    public static final int version = 1;
    public  static String dbName="Company.db";
    public static final String TABLE_NAME ="Empdata";
    public static final String COL1 = "id";
    public static final String COL2 = "name";
    public static final String COL3 = "designation";
    public static final String COL4 = "salary";
    private static final String CREATE_TABLE="create table if not exists "+ TABLE_NAME + "(" + COL1 + " INTEGER PRIMARY KEY AUTOINCREMENT,"+COL2+" TEXT NOT NULL,"
            + COL3 + " TEXT, " +COL4 + " INTEGER);";
    private static final String DROP_TABLE = "DROP TABLE IF EXISTS "+ TABLE_NAME;

    private Context context;

    public DatabaseHelper(Context context) {
        super(context,dbName,null,version);
        context=this.context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        try {
            db.execSQL(CREATE_TABLE);
        } catch (Exception e) {
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(DROP_TABLE);
        onCreate(db);
    }

    public boolean InsertEmployee(Employee objEmp)
    {
        SQLiteDatabase db=this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COL2,objEmp.getEmployeeName());
        cv.put(COL3,objEmp.getEmployeeDesig());
        cv.put(COL4,objEmp.getEmployeeSalary());

        long result = db.insert(TABLE_NAME,null,cv);
        if(result == -1)

            return false;
        else
            return true;
    }
}

В коде DatabaseHelper.java видно, что класс DatabaseHelper является наследником класса SQLiteOpenHelper.

После того, как база данных создана, можно приступать к работе с ней. В частности — создавать и обновлять поля её таблиц. При решении этих задач можно пользоваться объектом типа ContentValues, который позволяет хранить пары ключ-значение. Именно такие объекты используются для добавления новых записей в таблицы базы данных (с помощью метода insert() объекта SQLiteDatabase) и для обновления существующих записей (с помощью метода update()).

Database Inspector в Android Studio


Инструмент Database Inspector позволяет исследовать базы данных, используемые в приложениях, выполнять запросы к ним, модифицировать их, делая всё это во время работы приложений. Database Inspector имеется в Android Studio начиная с версии 4.1. Этот инструмент особенно полезен при отладке механизмов программ, ответственных за работу с базами данных. Database Inspector работает и с обычной реализацией SQLite, и с библиотеками, построенными на её основе, вроде Room. Database Inspector работает лишь с библиотекой SQLite, входящей в состав операционных систем Android, уровень API которых не ниже 26.

Для того чтобы открыть базу данных в Database Inspector нужно выполнить следующие действия:

  1. Запустите приложение в эмуляторе или на устройстве, подключённом к компьютеру. На эмуляторе или на устройстве должно присутствовать API не ниже 26 уровня.
  2. Выполните команду меню View > Tool Windows > Database Inspector.
  3. Выберите процесс выполняющегося приложения из выпадающего меню.
  4. В панели Databases появятся записи о базах данных, которые имеются в выбранном приложении. Теперь можно работать с этими базами данных.

48f8e84b8f5f5e5b589d3ce0f7f9f9d3.jpg

Исследование базы данных с помощью Database Inspector

Обратите внимание на то, что есть одна проблема, связанная с аварийным завершением работы программ на эмуляторе Android 11 при подключении к Database Inspector. Если вы с этой проблемой столкнётесь — здесь вы можете найти сведения о том, как с ней справиться.

Применяете ли вы SQLite в Android-разработке?
oug5kh6sjydt9llengsiebnp40w.png

© Habrahabr.ru