Java SQLite ORM – Devcolibri – Android для начинающих

Java SQLite ORM

БД имеют неприятную особенность, когда нужно создавать множество запросов, контролировать связи, формировать все вручную. Для облегчения жизни программиста есть ORM (Object Relation Mapping).

В данном уроке мы познакомимся с такой библиотекой как ORMLite. Эта библиотека позволяет создать представление таблиц и их отношений в виде обычных классов. Таким образом, мы уйдем от написания тяжелый и затрудняющих чтение и понимание классов к управлению объектами.

Шаг 1

Начнем с поставления задачи.  На картинке ниже представлено 3 класса. 2  с них находятся внутри 1 (Question). Такой тип связи называется агрегацией. Создадим такие ж 3 таблички в базе и свяжем их между собой. Category – Question , Answer – Question

Diagram1

Шаг 2

На протяжении урока будем использовать базу SQLite. Создаем ее с помощью специального ПО. Можно использовать Navicat или другие подобные программы для работы с базой. Я буду использовать плагин для Firefox -> SQLite Manager. Создаем базу под именем main.sqlite. Создаем таблички:

Создание таблички question:

CREATE  TABLE "main"."question" 
("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "category" INTEGER, "text" VARCHAR, "img" VARCHAR)

Создание таблички category:

CREATE  TABLE "main"."category" 
("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "name" VARCHAR)

Создание таблички answer:

CREATE  TABLE "main"."answer" 
("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "id_q" INTEGER, "value" VARCHAR, "correct" BOOL)

Шаг 3

После создания табличек, их нужно заполнить данными. Заполним полноценных 2 объекта. 1 question, 1 category, 2 answer.

category:

INSERT INTO "main"."category" ("name") VALUES ("category1")
INSERT INTO "main"."category" ("name") VALUES ("category2")

question:

INSERT INTO "main"."question" ("category","text","img") VALUES (1,"One?","Not img now");
INSERT INTO "main"."question" ("category","text","img") VALUES (2,"Four?","Not img now");

answer:

INSERT INTO "main"."answer" ("id_q","value","correct") VALUES (1,"One","1");
INSERT INTO "main"."answer" ("id_q","value","correct") VALUES (1,"Two","0");
INSERT INTO "main"."answer" ("id_q","value","correct") VALUES (2,"Three","0");
INSERT INTO "main"."answer" ("id_q","value","correct") VALUES (2,"Four","1");

Шаг 4

Теперь создадим соответствующие классы в нашем проекте. Классы должны содержать сеттеры, геттеры и конструктор по умолчанию.

1

Question:

package org.knowledgechecker.entity;

import java.util.List;

public class Question {

    private int id;
    private Category category;
    private String text;
    private String img;
    private List<Answer> answers;

    public Question() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }

    public List<Answer> getAnswers() {
        return answers;
    }

    @Override
    public String toString() {
        return "Question{" +
                "id=" + id +
                ", category=" + category +
                ", text='" + text + '\'' +
                ", img='" + img + '\'' +
                ", answers=" + answers +
                '}';
    }

    public void setAnswers(List<Answer> answers) {
        this.answers = answers;
    }
}

Category:

package org.knowledgechecker.entity;

public class Category {
    private int id;
    private String name;

    public Category() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Category{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Answer:

package org.knowledgechecker.entity;

public class Answer {
    private int id;
    private Question question;
    private String value;
    private boolean correct;

    public Answer() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Question getQuestion() {
        return question;
    }

    public void setQuestion(Question question) {
        this.question = question;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public boolean isCorrect() {
        return correct;
    }

    public void setCorrect(boolean correct) {
        this.correct = correct;
    }

    @Override
    public String toString() {
        return "Answer{" +
                "id=" + id +
                ", idQuestion=" + idQuestion +
                ", value='" + value + '\'' +
                ", corect=" + corect +
                '}';
    }
}

Шаг 5

Подключаем нашу библиотеку ORMLite. Ее можно взять с офф. сайта по ссылке: http://ormlite.com/releases/ или, подключить с помощью Maven.

<dependency>
    <groupId>com.j256.ormlite</groupId>
    <artifactId>ormlite-core</artifactId>
    <version>4.47</version>
</dependency>

<dependency>
    <groupId>com.j256.ormlite</groupId>
    <artifactId>ormlite-jdbc</artifactId>
    <version>4.47</version>
</dependency>

<dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.7.2</version>
</dependency>

Для того чтобы проверять правильность настройки можно использовать библиотеку Junit:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
</dependency>

Шаг 6

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

Category:

@DatabaseTable
public class Category {
    @DatabaseField(generatedId = true)
    private int id;
    @DatabaseField
    private String name;

//getters and setters...
}

@DatabaseTable – для указание на табличку с базы.  

tableName – eсли имя класса не совпадает с именем таблички

@DatabaseField – указывает что поле является столбцом.

    columnName – указать имя колонки самостоятельно. (Если имя колонки не совпадает с именем поля класса)
    Id – поле является идентификатором
    generatedId – идентификатор генерируется автоматиески
    foreign – ссылается на другой класс, который также хранит в себе таблицу

Answer:

@DatabaseTable (tableName = "answer")
public class Answer {
    @DatabaseField(generatedId = true)
    private int id;
    @DatabaseField(columnName = "id_q", foreign = true)
    private Question question;
    @DatabaseField
    private String value;
    @DatabaseField
    private boolean correct;
//getter and setters...
}

Question:

@DatabaseTable(tableName = "question")
public class Question {
    @DatabaseField(generatedId = true)
    private int id;
    @DatabaseField(columnName = "category", foreign = true)
    private Category category;
    @DatabaseField
    private String text;
    @DatabaseField
    private String img;

    @ForeignCollectionField
    private ForeignCollection<Answer> answers;

//getters and setters
}

Обратите внимание, что в 13 строке был изменен List на ForeignColliection<Answer>.

@ForeignCollectionField – получает коллекцию данных зависимой таблички.

Шаг 7

После создания сущностей и связывания их с табличками в БД создаем сервис, для управления их поведением. ORMLite дает легкий способ создания DAO (Data Accsess Object) который мы используем для построения нашего сервиса. Чтобы урок не разростался и дальше, приведу код одного из сервиса.

public class QuestionService {
    private final String url = "jdbc:sqlite:main.sqlite";
    private ConnectionSource source;
    private Dao<Question, String> dao;

    public QuestionService() throws SQLException {
        source = new JdbcConnectionSource(url);
        dao = DaoManager.createDao(source,Question.class);
    }

    public List<Question> getAll() throws SQLException {
        return dao.queryForAll();
    }
}

url – путь к нашей бд

source = new JdbcConnectionSource(url) – создаем подключение к нашей базе по url

dao = DaoManager.createDao(source,Question.class) – создание DAO для класса. Он будет использоваться
для того чтобы управлять объектом, выполнять над ним операции чтения, сохранения, удаления, изменения и т.д в базе.

dao.queryForAll() – возвращает все данные с таблички query и зависимых табличек.

Пример выполнения метода getAll() с тестового набора для класса Questions:

34_38_2

1 – это лог наших запросов, информация о работе библиотеки

2 – наш результат, который мы ждали. вывод с таблички answer есть корректным. Для вывода его в “человеческом” виде, достаточно сделать обработку этой коллекции.

В заключение, можно выполнять аналогичным образом операции CRUD (Create Read Update Delete), а также, есть пара дополнительных методов, которые добавят возможностей. Об этом, по необходимости, в следующем уроке.

Спасибо.

ПОХОЖИЕ ПУБЛИКАЦИИ

    None Found

22177
13/11/2013

6 комментариев к статье "Java SQLite ORM"

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

Сайт использует cookie-файлы для того, чтобы вам было удобнее им пользоваться. Для продолжения работы с сайтом, вам необходимо принять использование cookie-файлов.

Я ознакомлен(а)