Pull to refresh

Работаем с SQLite в AIR приложениях

Reading time 7 min
Views 4K


Здравствуйте ценители (и не только) Flash, Flex и AIR.

Сегодня я расскажу как работать с локальной базой данных (SQLite) в AIR приложениях.

Для работы нам понадобится Flex Builder, какой-нибудь, редактор SQLite (я использую приложение для FireFox SQLite Manager) и немного терпения.


Редактор нам нужен для просмотра изменений в файле базы, поскольку AIR не имеет собственного.

Для реализации задуманного нам понадобятся следующие библиотеки:

  1. import flash.data.SQLConnection;       // Необходима для соединения с файлом базы данных (БД)
  2. import flash.data.SQLStatement;        // Необходима для работы с запросами
  3. import flash.data.SQLResult;           // Необходима для обработки результатов запроса
  4. import flash.data.SQLMode;             // Нам не понадобится, а используется для пояснения, для чего мы открываем БД (чтения, записи или обновления)
  5.  
  6. import flash.events.SQLErrorEvent;     // Обрабатывает ошибки подсоединения к БД
  7. import flash.events.SQLEvent;          // Обрабатывает остальные события БД (OPEN, UPDATE и т.д.)
  8.  
  9. import flash.filesystem.File;          // Необходима для указания пути к файлу БД
* This source code was highlighted with Source Code Highlighter.


Как и другие среды работающие с БД SQLite AIR может создавать свои файлы, а может работать уже с готовыми файлами БД.

Рассмотрим вариант с созданием файла БД с нуля.

Для начала нам нужно создать сам файл базы (testDB.sqlite) для этого используем следующую конструкцию:

  1. var dbFile:File = File.desktopDirectory.resolvePath("testDB.sqlite"); // Указываем путь к файлу БД (В нашем случае это рабочий стол)
  2.  
  3. var DBConnection:SQLConnection = new SQLConnection();          // Коннектимся к базе
  4. DBConnection.addEventListener(SQLErrorEvent.ERROR, DBError);   // Добавляем обработчик события возникающего при соединении
  5. DBConnection.addEventListener(SQLEvent.OPEN, DBOpen);          // Добавляем обработчик события возникающего при удачном соединении
  6. DBConnection.open(dbFile);                                     // Собственно инициализируем открытие базы
  7.  
  8. /**
  9. * Эта функция обрабатывает ошибки соединения
  10. */
  11. private function DBError(e:SQLErrorEvent):void
  12. {
  13.   trace("Error message: ", e.error.message);
  14.   trace("Details: ", e.error.details);
  15. }
  16.  
  17. /**
  18. * Эта функция обрабатывает удачное соединение
  19. */
  20. private function DBOpen(e:SQLEvent):void
  21. {
  22.   trace("The database was created successfully");
  23. }
* This source code was highlighted with Source Code Highlighter.


Файл БД у нас уже есть осталось только заполнить его таблицами. Создание таблиц можно привязать к событию успешного создания БД (DBOpen). Далее, мы так и поступим, а пока разберемся из чего будет состоять наша БД (на примере базы которая будут хранить дни рождения). Она будет состоять из двух таблиц:

1. groups — группы в которые будут входить люди, н.п. «Друзья», «Работа», «Семья». В таблице будет два поля (id, name);
2. и собственно peoples с полями (id, lname, fname, ffname, date, group_id)

Теперь создадим, описанные выше, таблицы для этого нам понадобится переменная которая будет содержать запрос к базе:

  1. var GroupsTable:String = "CREATE TABLE IF NOT EXISTS groups (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT)";
* This source code was highlighted with Source Code Highlighter.


И объект для управления запросами (этот код можно вставить в функцию DBOpen):

  1. var statement:SQLStatement = new SQLStatement();          // Создаем объект
  2. statement.sqlConnection = DBConnection;                   // Указываем базу по отношению к которой будем выполнять запрос
  3. statement.text = GroupsTable;                             // Указываем текст запроса
  4. statement.addEventListener(SQLErrorEvent.ERROR, DBError); // Добавляем обработчик события возникающего при соединении
  5. statement.addEventListener(SQLEvent.RESULT, TableResult); // Добавляем обработчик события возникающего при успешном создании таблицы
  6. statement.execute();                                      // Инициализируем обработку запроса
  7.  
  8. /**
  9. * Эта функция обрабатывает удачное создание таблицы
  10. */
  11. private function TableResult(e:SQLEvent):void
  12. {
  13.   trace("Table created");
  14. }
* This source code was highlighted with Source Code Highlighter.


Теперь создаем вторую таблицу, по аналогии:

  1. var PeoplesTable:String = "CREATE TABLE peoples (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, lname TEXT, fname TEXT, ffname TEXT, date TEXT, group_id INTEGER)";
  2.  
  3. var statement:SQLStatement = new SQLStatement();            // Создаем объект
  4. statement.sqlConnection = DBConnection;                     // Указываем базу по отношению к которой будем выполнять запрос
  5. statement.text = PeoplesTable;                              // Указываем текст запроса
  6. statement.addEventListener(SQLErrorEvent.ERROR, DBError);   // Добавляем обработчик события возникающего при соединении
  7. statement.addEventListener(SQLEvent.RESULT, TableResult);   // Добавляем обработчик события возникающего при успешном создании таблицы
  8. statement.execute();                                        // Инициализируем обработку запроса
* This source code was highlighted with Source Code Highlighter.


Справились. База с таблицами создана и готова к работе. Осталось только заполнить ее данными и научится их извлекать.
Рассмотрим пример добавления информации в таблицу:

  1. var InsertIntoPeoples:String = "INSERT INTO peoples (lname, fname, ffname, date, group_id) VALUES (@column0, @column1, @column2, @column3, @column4)";
  2.  
  3. var LNameArray :Array = ["Иванов", "Сидоров", "Козлов", "Игнатенко", "Борьщев", "Кольченко", "Бузякин"];
  4. var FNameArray :Array = ["Иван", "Николай", "Артем", "Игорь", "Сергей", "Борис", "Алексей"];
  5. var FFNameArray:Array = ["Алексеевич", "Борисович", "Игоревич", "Артемович", "Николаевич", "Иванович", "Сергеевич"];
  6.  
  7. var statement2:SQLStatement = new SQLStatement();
  8. statement2.sqlConnection = DBConnection;
  9. statement2.text = InsertIntoPeoples;
  10. statement2.addEventListener(SQLErrorEvent.ERROR, DBError);
  11. statement2.addEventListener(SQLEvent.RESULT, InsertResult);
  12.  
  13. for(var j:Number = 0; j < 100; j++)
  14. {
  15.   statement2.parameters["@column0"] = LNameArray[Math.round(Math.random() * 6)];
  16.   statement2.parameters["@column1"] = FNameArray[Math.round(Math.random() * 6)];
  17.   statement2.parameters["@column2"] = FFNameArray[Math.round(Math.random() * 6)];
  18.   statement2.parameters["@column3"] = (Math.round(Math.random() * 30) + 1) + ':' + (Math.round(Math.random() * 11) + 1) + ':' + (Math.round(Math.random() * 2009) + 1);
  19.   statement2.parameters["@column4"] = Math.round(Math.random() * 3);
  20.   statement2.execute();
  21. }
  22.  
  23. /**
  24. * Эта функция обрабатывает удачное добавление данных в таблицу
  25. */
  26. private function InsertResult(e:SQLEvent):void
  27. {
  28.   trace("Add to table successfully");
  29. }
* This source code was highlighted with Source Code Highlighter.


В данном примере в конструкции INSERT используется ссылки "@column0" они нужны для упрощения добавления данных при помощи цикла. Это гораздо удобнее чем использовать строку с переменными которую перед каждым добавлением приходится переопределять.

Теперь попробуем извлечь данные из таблицы:

  1. var q:String = "SELECT * FROM groups ORDER BY name";
  2.  
  3. var getGroupStat:SQLStatement = new SQLStatement();
  4. getGroupStat.sqlConnection = DBConnection;
  5. getGroupStat.text = q;
  6. getGroupStat.addEventListener(SQLErrorEvent.ERROR, DBError);
  7. getGroupStat.addEventListener(SQLEvent.RESULT, GetGroupResult);
  8. getGroupStat.execute();
  9.  
  10. /**
  11. * Обрабатывает результат выполнения функции GetGroup().
  12. */
  13. private function GetGroupResult(e:SQLEvent):void
  14. {
  15.   var result:SQLResult = e.target.getResult();
  16.   
  17.   var GroupArray:ArrayCollection = new ArrayCollection();
  18.   
  19.   if(result.data)
  20.     for(var i:Number = 0; i < result.data.length; i++)
  21.       GroupArray.addItem(result.data[i]);
  22. }
* This source code was highlighted with Source Code Highlighter.


В функции GetGroupResult() переменной result присваивается результат запроса SELECT он представляет из себя массив переменных типа Object:

  1. [[object Object],[object Object],[object Object],[object Object]]
* This source code was highlighted with Source Code Highlighter.


Его лучше всего использовать присвоив переменной типа ArrayCollection, для удобного обращения к данным по имени (GroupArray[i].name).
Для удаления и обновления данных используются конструкции подобные тем которые мы рассмотрели отличаются только строковые запросы к базе.

В завершении урока хотелось бы отметить, что если в вашем AIR приложении используется некое хранилище данных то лучше чем SQLite файла не найти, поскольку работа с ним гораздо быстрее чем с файлом TXT или даже XML.

Прилагаю исходник к уроку (проект для Flex Builder 3.2).

P.S. Может кто-нибудь подскажет хорошую подсветку кода для AS3?
Подсказали quickhighlighter.com, спасибо kutu
Tags:
Hubs:
+24
Comments 46
Comments Comments 46

Articles