Storage sqlite что это
Перейти к содержимому

Storage sqlite что это

  • автор:

Базы данных в памяти

Выполняющиеся в памяти базы данных SQLite — это базы данных, которые полностью хранятся в памяти, а не на диске. Для создания выполняющейся в памяти базы данных используется специальное имя файла источника данных :memory: . Когда подключение закрывается, база данных удаляется. При использовании :memory: каждое подключение создает собственную базу данных.

Data Source=:memory: 

Общий доступ к выполняющимся в памяти базам данных

Выполняющиеся в памяти базы данных могут совместно использоваться несколькими подключениями, если указать Mode=Memory и Cache=Shared в строке подключения. С помощью ключевого слова Data Source можно задать имя для выполняющейся в памяти базы данных. Строки подключения, в которых указано одно и то же имя, будут обращаться к одной и той же выполняющейся в памяти базе данных. База данных существует, пока остается открытым хотя бы одно подключение к ней. На GitHub имеется пример, который это демонстрирует.

Data Source=InMemorySample;Mode=Memory;Cache=Shared 

Совместная работа с нами на GitHub

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

Storage sqlite что это

При определении столбцов таблицы для них необходимо указать тип данных. Каждый столбец имеет определенный тип данных. Для хранения данных в в SQLite применяются следующие типы:

  • NULL : указывает фактически на отсутствие значения
  • INTEGER : представляет целое число, которое может быть положительным и отрицательным и в зависимости от своего значения может занимать 1, 2, 3, 4, 6 или 8 байт
  • REAL : представляет число с плавающей точкой, занимает 8 байт в памяти
  • TEXT : строка текста в одинарных кавычках, которая сохраняется в кодировке базы данных (UTF-8, UTF-16BE или UTF-16LE)
  • BLOB : бинарные данные

Стоит отметить, что SQLite оперирует концепцией классов хранения или storage class . И по сути все эти пять типов называются классами хранения. Концепция классов хранения несколько шире, чем тип данных. Например, класс INTEGER по сути объединяет 6 различных целочисленных типов данных разной длины. Однако это больше относится к внутренней работе SQLite. И внешне, например, на уровне определения таблицы и работы с данными мы будем работать с типом INTEGER , а не со всеми реальными типами, которые скрываются за этим названием. Поэтому фактически классы хранения ассоциируются с типа данных. И выше представленные пять классов хранения также обычно называют типами данных и данные можно применять при определении столбцов:

CREATE TABLE users ( id INTEGER, name TEXT, age INTEGER, weight REAL, image BLOB );

Кроме того, мы можем применять идентификатор NUMERIC . Этот идентификатор не представляет отдельного типа данных. А фактически представляет столбец, который может хранить данные всех пяти выше перечисленных типов (в терминологии SQLite NUMERIC еще называется type affinity ). Например:

CREATE TABLE users ( id INTEGER, name TEXT, age NUMERIC );

Использование базы данных SQLite в приложении Windows

Вы можете использовать SQLite для хранения и извлечения данных в упрощенной базе данных на устройстве пользователя. В этом руководстве показано, как это сделать в приложениях пакета SDK для приложений для приложений windows.

Некоторые преимущества использования SQLite для локального хранения данных

✔️ SQLite является упрощенным и автономным. Это библиотека кода без других зависимых компонентов. Ее не требуется настраивать.

✔️ Тут нет сервера базы данных. Клиент и сервер работают в одном процессе.

✔️ SQLite находится на общедоступном домене, поэтому вы можете свободно использовать и распространять ее в вашем приложении.

✔️ SQLite работает на разных платформах и архитектурах.

Подробнее о SQLite см. здесь.

Выбор слоя абстрагирования

Рекомендуется использовать Entity Framework Core или библиотеку SQLite с открытым кодом, созданную корпорацией Майкрософт.

Entity Framework Core

Entity Framework (EF) — это объектно-реляционный модуль сопоставления, позволяющий разработчикам работать с реляционными данными с помощью объектов, специализированных для доменов. Если вы уже использовали эту платформу для работы с данными в других приложениях .NET, вы можете использовать тот же код в приложении пакета SDK для приложений Windows, и он будет работать с соответствующими изменениями в строка подключения.

Чтобы испытать ее, см. раздел Начало работы с EF Core.

Библиотеке SQLite

Библиотека Microsoft.Data.Sqlite реализует интерфейсы в пространстве имен System.Data.Common. Майкрософт активно поддерживает эти реализации и предоставляет интуитивно понятную оболочку для низкоуровневых собственных API-интерфейсов SQLite.

В остальных разделах этого руководства приведены инструкции по работе с этой библиотекой.

Настройка решения для использования библиотеки Microsoft.Data.SQlite

Мы начнем с базового проекта пакета SDK для приложений Windows, а затем установим пакет NuGet SQLite.

Все поддерживаемые версии Windows поддерживают SQLite, поэтому приложению не нужно упаковать библиотеки SQLite. Вместо этого ваше приложение может использовать версию SQLite, которая поставляется вместе с Windows. Это обеспечивает следующие преимущества.

✔️ Уменьшает размер приложения, так как не требуется скачивать двоичную библиотеку SQLite, а затем упаковывать ее в качестве части приложения.

✔️ Отсутствие необходимости в принудительной передаче новой версии вашего приложения пользователям, если SQLite опубликует важные исправления ошибок и уязвимостей безопасности в SQLite. Версия Windows SQLite обслуживается корпорацией Майкрософт совместно с SQLite.org.

✔️ Загрузка приложения может быть быстрее, так как, скорее всего, версия SDK-пакета SQLite будет уже загружена в память.

Начнем с добавления класса в проект с именем DataAccess. Если вы планируете предоставить общий доступ к логике доступа к данным с другим клиентским кодом, можно использовать проект библиотеки классов .NET для хранения кода доступа к данным, но мы не будем использовать его в нашем примере.

Щелкните правой кнопкой мыши решение, а затем нажмите кнопку Управление пакетами NuGet для решения.

A screenshot of Visual Studio

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

Перейдите на вкладку «Обзор «, найдите пакет Microsoft.Data.SQLite и установите последнюю стабильную версию.

SQLite NuGet package

Добавление данных в базу данных SQLite и их извлечение

Мы выполним следующие действия.

1️⃣ Подготовка класса доступа к данным.

2️⃣ Инициализация базы данных SQLite.

3️⃣ Вставка данных в базу данных SQLite.

4️⃣ Извлечение данных из базы данных SQLite.

5️⃣ Добавление базового пользовательского интерфейса.

Подготовка класса доступа к данным

DataAccess Откройте класс в проекте и сделайте этот класс статическим.

Хотя в нашем примере код доступа к данным помещается в статический класс, это вариант разработки и является полностью необязательным.

public static class DataAccess

Добавьте следующие using инструкции в начало этого файла.

using Microsoft.Data.Sqlite; using System.Collections.Generic; 

Инициализация базы данных SQLite

Добавьте метод в DataAccess класс, который инициализирует базу данных SQLite.

public async static void InitializeDatabase() < await ApplicationData.Current.LocalFolder .CreateFileAsync("sqliteSample.db", CreationCollisionOption.OpenIfExists); string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqliteSample.db"); using (var db = new SqliteConnection($"Filename=")) < db.Open(); string tableCommand = "CREATE TABLE IF NOT " + "EXISTS MyTable (Primary_Key INTEGER PRIMARY KEY, " + "Text_Entry NVARCHAR(2048) NULL)"; var createTable = new SqliteCommand(tableCommand, db); createTable.ExecuteReader(); >> 

Приведенный выше код, использующий ApplicationData элементы, будет работать только для упакованных приложений, работающих в контейнере приложений. Все остальные приложения Windows должны обращаться к ApplicationData членам через класс ApplicationDataManager .

Этот код создает базу данных SQLite и сохраняет ее в локальном хранилище данных приложения.

В этом примере мы используем имя базы данных sqlliteSample.db , но вы можете использовать любое имя при условии, что оно будет использоваться во всех объектах SqliteConnection, экземпляры которых необходимо создать. В рабочем приложении сведения о подключении, такие как имя файла базы данных, должны храниться в конфигурации приложения, а не жестко закодированы (см. статью «Добавление Конфигурация приложений Azure с помощью visual Studio Подключение ed Services«).

В конструкторе файла App.xaml.cs проекта вызовите InitializeDatabase метод DataAccess класса. Это обеспечит создание или открытие базы данных при каждом запуске приложения.

public App()

Вставка данных в базу данных SQLite

Добавьте метод в DataAccess класс, который вставляет данные в базу данных SQLite. Этот код использует параметры в запросе для предотвращения атак путем внедрения кода SQL.

public static void AddData(string inputText) < string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqliteSample.db"); using (var db = new SqliteConnection($"Filename=")) < db.Open(); var insertCommand = new SqliteCommand(); insertCommand.Connection = db; // Use parameterized query to prevent SQL injection attacks insertCommand.CommandText = "INSERT INTO MyTable VALUES (NULL, @Entry);"; insertCommand.Parameters.AddWithValue("@Entry", inputText); insertCommand.ExecuteReader(); >> 

Извлечение данных из базы данных SQLite

Добавьте метод, который получает все строки данных из таблицы в базе данных SQLite.

public static List GetData() < var entries = new List(); string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqliteSample.db"); using (var db = new SqliteConnection($"Filename=")) < db.Open(); var selectCommand = new SqliteCommand ("SELECT Text_Entry from MyTable", db); SqliteDataReader query = selectCommand.ExecuteReader(); while (query.Read()) < entries.Add(query.GetString(0)); >> return entries; > 

Метод Read считывает строки возвращаемых данных. Возвращается true , если есть строки слева, в противном случае возвращается false .

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

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

Добавление базового пользовательского интерфейса

В файле MainWindow.xaml проекта добавьте следующий код XAML.

Этот базовый пользовательский интерфейс предоставляет пользователю поле TextBox , которое можно использовать для ввода строки, которую мы добавим в базу данных SQLite. Мы подключимся Button в этом пользовательском интерфейсе к обработчику событий, который будет получать данные из базы данных SQLite и затем отображать их в ListView .

В файле MainWindow.xaml.cs добавьте следующий обработчик. Это метод, который мы связали с кнопкой Click событие Button в пользовательском интерфейсе.

private void AddData(object sender, RoutedEventArgs e)

Мы также хотим убедиться, что все существующие данные загружаются при запуске приложения. Добавьте строку кода в MainWindow конструктор для вызова GetData() .

public MainWindow()

Вот и все. Изучите Microsoft.Data.Sqlite чтобы узнать, что еще можно сделать с вашей базой данных SQLite. Ознакомьтесь со ссылками ниже, чтобы узнать о других способах использования данных в приложениях Windows.

Следующие шаги

Подключение приложения непосредственно к базе данных SQL Server

Совместное использование кода между разными приложениями на различных платформах

Добавление страниц с основными и подробными данными с помощью серверов Azure SQL

См. статью Customer Orders Database sample (Пример базы данных заказов клиентов).

Урок 34. Хранение данных. SQLite

На прошлом уроке мы рассмотрели самый простой способ хранения данных — Preferences. Но способ этот достаточно ограничен и для хранения большого количества структурированных данных неудобен. На этом уроке рассмотрим SQLite. Это база данных с таблицами и запросами — все как в обычных БД.

Для начала, немного теории по взаимодействию приложения и БД.

В приложении, при подключении к БД мы указываем имя БД и версию. При этом могут возникнуть следующие ситуации:

1) БД не существует. Это может быть например в случае первичной установки программы. В этом случае приложение должно само создать БД и все таблицы в ней. И далее оно уже работает с только что созданной БД.

2) БД существует, но ее версия устарела. Это может быть в случае обновления программы. Например новой версии программы нужны дополнительные поля в старых таблицах или новые таблицы. В этом случае приложение должно апдейтить существующие таблицы и создать новые, если это необходимо.

3) БД существует и ее версия актуальна. В этом случае приложение успешно подключается к БД и работает.

Как вы понимаете, фраза «приложение должно» равнозначна фразе «разработчик должен», т.е. это наша задача. Для обработки описанных выше ситуаций нам надо создать класс, являющийся наследником для SQLiteOpenHelper. Назовем его DBHelper. Этот класс предоставит нам методы для создания или обновления БД в случаях ее отсутствия или устаревания.

onCreate — метод, который будет вызван, если БД, к которой мы хотим подключиться – не существует

onUpgrade — будет вызван в случае, если мы пытаемся подключиться к БД более новой версии, чем существующая

Давайте накидаем простое приложение – справочник контактов, которое будет хранить имя и email. Вводить данные будем на экране приложения, а для отображения информации используем логи. Обычно для этого используется List (список) – но мы эту тему пока не знаем. Да и не хочется перегружать приложение. Главное – освоить приемы работы с БД.

Project name: P0341_SimpleSQLite
Build Target: Android 2.3.3
Application name: SimpleSQLite
Package name: ru.startandroid.develop.p0341simplesqlite
Create Activity: MainActivity

Нарисуем экран для ввода записей и очистки таблицы. Открываем main.xml и пишем:

Пара полей для ввода и кнопки добавления записи, вывода существующих записей и очистки таблицы.

Открываем MainActivity.java и пишем:

package ru.startandroid.develop.p0341simplesqlite; import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity implements OnClickListener < final String LOG_TAG = "myLogs"; Button btnAdd, btnRead, btnClear; EditText etName, etEmail; DBHelper dbHelper; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.main); btnAdd = (Button) findViewById(R.id.btnAdd); btnAdd.setOnClickListener(this); btnRead = (Button) findViewById(R.id.btnRead); btnRead.setOnClickListener(this); btnClear = (Button) findViewById(R.id.btnClear); btnClear.setOnClickListener(this); etName = (EditText) findViewById(R.id.etName); etEmail = (EditText) findViewById(R.id.etEmail); // создаем объект для создания и управления версиями БД dbHelper = new DBHelper(this); >@Override public void onClick(View v) < // создаем объект для данных ContentValues cv = new ContentValues(); // получаем данные из полей ввода String name = etName.getText().toString(); String email = etEmail.getText().toString(); // подключаемся к БД SQLiteDatabase db = dbHelper.getWritableDatabase(); switch (v.getId()) < case R.id.btnAdd: Log.d(LOG_TAG, "--- Insert in mytable: ---"); // подготовим данные для вставки в виде пар: наименование столбца - значение cv.put("name", name); cv.put("email", email); // вставляем запись и получаем ее ID long rowID = db.insert("mytable", null, cv); Log.d(LOG_TAG, "row inserted, --- Rows in mytable: ---"); // делаем запрос всех данных из таблицы mytable, получаем Cursor Cursor c = db.query("mytable", null, null, null, null, null, null); // ставим позицию курсора на первую строку выборки // если в выборке нет строк, вернется false if (c.moveToFirst()) < // определяем номера столбцов по имени в выборке int idColIndex = c.getColumnIndex("id"); int nameColIndex = c.getColumnIndex("name"); int emailColIndex = c.getColumnIndex("email"); do < // получаем значения по номерам столбцов и пишем все в лог Log.d(LOG_TAG, "ID = " + c.getInt(idColIndex) + ", name = " + c.getString(nameColIndex) + ", email = " + c.getString(emailColIndex)); // переход на следующую строку // а если следующей нет (текущая - последняя), то false - выходим из цикла >while (c.moveToNext()); > else Log.d(LOG_TAG, "0 rows"); c.close(); break; case R.id.btnClear: Log.d(LOG_TAG, "--- Clear mytable: ---"); // удаляем все записи int clearCount = db.delete("mytable", null, null); Log.d(LOG_TAG, "deleted rows count = " + clearCount); break; > // закрываем подключение к БД dbHelper.close(); > class DBHelper extends SQLiteOpenHelper < public DBHelper(Context context) < // конструктор суперкласса super(context, "myDB", null, 1); >@Override public void onCreate(SQLiteDatabase db) < Log.d(LOG_TAG, "--- onCreate database ---"); // создаем таблицу с полями db.execSQL("create table mytable (" + "id integer primary key autoincrement," + "name text," + "email text" + ");"); >@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) < >> >

Куча новых незнакомых слов в коде. Давайте разбираться.

В методе Activity — onCreate мы определяем объекты, присваиваем обработчики и создаем объект dbHelper класса DBHelper для управления БД. Сам класс будет описан ниже.

Далее смотрим метод Activity – onClick, в котором мы обрабатываем нажатия на кнопки.

Класс ContentValues используется для указания полей таблицы и значений, которые мы в эти поля будем вставлять. Мы создаем объект cv, и позже его используем. Далее мы записываем в переменные значения из полей ввода. Затем, с помощью метода getWritableDatabase подключаемся к БД и получаем объект SQLiteDatabase. Он позволит нам работать с БД. Мы будем использовать его методы insert – вставка записи, query – чтение, delete – удаление. У них много разных параметров на вход, но мы пока используем самый минимум.

Далее смотрим, какая кнопка была нажата:

btnAdd – добавление записи в таблицу mytable. Мы заполняем объект cv парами: имя поля и значение. И (при вставке записи в таблицу) в указанные поля будут вставлены соответствующие значения. Мы заполняем поля name и email. id у нас заполнится автоматически (primary key autoincrement). Вызываем метод insert – передаем ему имя таблицы и объект cv с вставляемыми значениями. Второй аргумент метода используется, при вставке в таблицу пустой строки. Нам это сейчас не нужно, поэтому передаем null. Метод insert возвращает ID вставленной строки, мы его сохраняем в rowID и выводим в лог.

btnRead – чтение всех записей из таблицы mytable. Для чтения используется метод query. На вход ему подается имя таблицы, список запрашиваемых полей, условия выборки, группировка, сортировка. Т.к. нам нужны все данные во всех полях без сортировок и группировок — мы используем везде null. Только имя таблицы указываем. Метод возвращает нам объект класса Cursor. Его можно рассматривать как таблицу с данными. Метод moveToFirst – делает первую запись в Cursor активной и заодно проверяет, есть ли вообще записи в нем (т.е. выбралось ли что-либо в методе query). Далее мы получаем порядковые номера столбцов в Cursor по их именам с помощью метода getColumnIndex. Эти номера потом используем для чтения данных в методах getInt и getString и выводим данные в лог. С помощью метода moveToNext мы перебираем все строки в Cursor пока не добираемся до последней. Если же записей не было, то выводим в лог соответствующее сообщение – 0 rows. В конце закрываем курсор (освобождаем занимаемые им ресурсы) методом close, т.к. далее мы его нигде не используем.

btnClear – очистка таблицы. Метод delete удаляет записи. На вход передаем имя таблицы и null в качестве условий для удаления, а значит удалится все. Метод возвращает кол-во удаленных записей.

После этого закрываем соединение с БД методом close.

Класс DBHelper является вложенным в MainActivity и описан в конце кода. Как я уже писал выше, этот класс должен наследовать класс SQLiteOpenHelper.

В конструкторе мы вызываем конструктор суперкласса и передаем ему:
context — контекст
mydb — название базы данных
null – объект для работы с курсорами, нам пока не нужен, поэтому null
1 – версия базы данных

В методе onCreate этого класса мы используем метод execSQL объекта SQLiteDatabase для выполнения SQL-запроса, который создает таблицу. Напомню – этот метод вызывается, если БД не существует и ее надо создавать. По запросу видно, что мы создаем таблицу mytable с полями id, name и email.

Метод onUpgrade пока не заполняем, т.к. используем одну версию БД и менять ее не планируем.

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

Введем чего-нить в поля ввода и нажмем Add.

— onCreate database —
— Insert in mytable: —
row inserted, >

Мы видим, что вызывался метод onCreate в классе DBHelper, а значит выполнялся скрипт по созданию таблицы. Это произошло потому, что это первый запуск приложения и БД еще не была создана. Теперь БД существует и с ней можно работать.

Далее видим, что вызывался метод вставки записи и вернул ID = 1.

Вставим еще какую-нибудь запись.

— Insert in mytable: —
row inserted, >

На этот раз onCreate не вызывался, т.к. БД уже существует. Вставилась запись с >

Давайте посмотрим содержимое таблицы — нажмем кнопку Read и посмотрим лог:

— Rows in mytable: —
name = John Smith, email = Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
name = Some body, email = Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.

Мы видим записи, которые вставляли. Тут все верно.

Теперь очистим таблицу — нажмем Clear. Смотрим лог:

— Clear mytable: —
deleted rows count = 2

Удалено две записи, все верно. Если теперь посмотрим содержимое таблицы – кнопка Read:

— Rows in mytable: —
0 rows

В этой теме важно понять, что для работы с БД мы использовали два класса:

DBHelper, наследующий SQLiteOpenHelper. В его конструкторе мы вызываем конструктор супер-класса и указываем имя и версию БД. Метод getWritableDatabase выполняет подключение к базе данных и возвращает нам объект SQLiteDatabase для работы с ней. Метод close закрывает подключение к БД. В случае, когда БД отсутствует или устарела, класс предоставляет нам самим реализовать создание или обновление в методах onCreate и onUpgrate.

SQLiteDatabase. Содержит методы для работы с данными – т.е. вставка, обновление, удаление и чтение.

Файл базы можно найти в File Explorer, как и на прошлом уроке. Путь к нему data/data/ru.startandroid.develop.p0341simpelsqlite/databases/myDB.

На следующем уроке продолжим это приложение. Добавим возможность обновления и удаления конкретных записей.

Важное замечание

Я в своих примерах выполняю все операции с базой данных в основном потоке. Я делаю так, чтобы не усложнять урок. Но в реале вам следует использовать для работы с БД отдельный поток, чтобы ваше приложение не тормозило визуально. О том, как это сделать, я пишу в уроках 80-91 и 135-136.

На следующем уроке:

— используем методы query и delete с указанием условия

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

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

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