ObjectDB — система управления базами данных для Java приложений

в 14:45, , рубрики: dbms, java, Песочница, метки: ,

ObjectDB является объектно-ориентированной, написанной на Java СУБД, которая при всех своих впечатляющих тестах на скорость и используемая (как следует из рекламы на официальном сайте) такими организациями как HP и Novell малознакома для многих программистов (Сам я об этой базе узнал буквально месяц назад, и использовал ее только один раз в рамках учебного проекта, да и мой препод узнал о ней как раз из моего проекта). За продолжением прошу под кат.

Для начала неприятная новость — ObjectDB является коммерческой СУБД и за ее использование нужно платить, правда в том случае если если количество записей объектов превышает 1.000.000 единиц, а количество классов 10 единиц на один файл базы данных, что означает что в одном файле можно хранить до миллиона объектов 10 разных классов не приобретаяя никаких лицензий, в том числе и при коммерческом использовании.

Физические же ограничения:

  • Размер файла до 128 ТВ
  • До 9,223,372,036,854,775,808 объектов на файл
  • До 2,147,483,648 классов на файл

Теперь о приятном:
Основные возможности и ключевые особенности:

  • 100% pure Java
  • Управляется стандартными Java APIs (JPA 2 / JDO 2)
  • Экстремально быстрая (Первые места на различных бенчмарках)
  • Работает как клиент-сервер(в том числе через SSL) или как подключаемая библиотека
  • Поставляется в виде одного .jar файла без внешних зависимостей

и многие другие кунштюки, такие как: управление соединениями, восстановление БД, несколько механизмов кэширования, простые и композитные индексы, поддержка JPQL и JDOQL и т.д.

Как следует из названия, ObjectDB работает с объектами, то есть хранит в себе не таблицы, а java-объекты целиком, действия над объектами в базе осуществляются привычными CRUD-операциями. Полный список типов объектов доступных для хранения можно посмотреть на официальном сайте.

Как это работает:

Рассмотрим использование СУБД на примере очень простой базы хранения данных пользователей.
Для работы нам потребуется создать 2 класса: класс представляющий пользователя и класс выполняющий над ним операции.

Класс User.java

Этот класс будет храниться в нашей базе

package db;

import java.io.Serializable;
import javax.jdo.annotations.Unique;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

&#64Entity
public class User {
&#64Id &#64GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

public User() {
}

public User(String name, String pass) {
this.name = name;
this.pass = pass;
}

public Long getId() {
return id;
}

&#64Unique private String name;
private String pass;

public String getName() {
return name;
}

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

public String getPass() {
return pass;
}

public void setPass(String pass) {
this.pass = pass;
}

}

Класс представляет собой вполне привычный Java-bean за исключением нескольких аннотаций, которые собственно и делают возможным его использование в качестве элемента БД, остановимся на них подробней.

&#64Entity
Аннотоция &#64Entity указывает, что класс используется как элемент хранения данных в БД.
&#64Id &#64GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

Аннотация &#64Id помечает элемент id как Primary key, а &#64GeneratedValue(strategy=GenerationType.AUTO) определяет для него способ генерации значений. GenerationType.AUTO в том числе означает, что если значение ключа не указанно явно, то оно будет создано автоматически.
&#64Unique private String name; Аннотация &#64Unique помечает поле, которое должно иметь уникальное значение, при попытке записать в БД объект, у которого значение поля помеченного этой аннотацией будет совпадать с ранее записанным объектом СУБД выбросит исключение. Таким образом мы делаем невозможной регистрацию нескольких пользователей с одним именем.

Класс UserDBAdapter.java

Этот класс осуществляет операции с базой данных пользователей.
package db;

import javax.persistence.*;

public class UserDBAdapter {
EntityManagerFactory emf;
EntityManager em;

public UserDBAdapter() {
emf = Persistence.createEntityManagerFactory("$objectdb/db/usr.odb");
em = emf.createEntityManager();
}

&#64Override
protected void finalize(){
em.close();
emf.close();
}

public boolean persistUser(User u) {
try {
em.getTransaction().begin();
em.persist(u);
em.getTransaction().commit();
em.clear();
return true;
}
catch(PersistenceException e){
System.out.println(e.getMessage());
em.clear();
em.close();
emf.close();
return false;
}
}

public User getUserById(long id) {
User u1 = em.find(User.class, id);
return u1;
}

public User getUserByName(String name) {
TypedQuery q = em.createQuery("SELECT u FROM User u WHERE u.name = :name", User.class);
User u1 = (User) q.setParameter("name", name).getSingleResult();
return u1;
}

public boolean autentificate(String name, String pass) throws PersistenceException{
TypedQuery q = em.createQuery("SELECT u FROM User u WHERE u.name = :name AND u.pass = :pass", User.class);
try {
User u1 = (User)q.setParameter("name", name).setParameter("pass", pass).getSingleResult();
return true;
}
catch(PersistenceException e) {
em.clear();
em.close();
emf.close();
throw new PersistenceException("username not found or password is invalid");
}
}
}

В конструкторе класса создается подключение к базе данных (если файл базы данных не обнаружен, то он будет создан).

Метод public boolean persistUser(User u) служит для добавления нового пользователя в базу. Операции изменяющие состояние объектов в базе данных, такие как добавление нового объекта, должны быть выполнены внутри транзакции которая открывается методом em.getTransaction().begin(), а закрывается методом em.getTransaction().commit() (именно тогда объект физически сохраняется в БД).
Методы, которые состояние БД не изменяют, такие как операции чтения из БД, активной транзакции не требуют.

Для получения объектов из БД используется SQL-подобный JPQL использующийся в этом примере в методах
public User getUserByName(String name) и public boolean autentificate(String name, String pass)
или встроенные методы класса Entitymanager, такие как em.find(User.class, id) позволяющий найти здесь объект класса User по его primary key (id).

Это был очень простой пример использования ObjectDB, который не отражает всех ее возможностей, но, как я надеюсь, может быть полезным для людей, незнакомых с этой СУБД в качестве первого знакомства.
Подробная информация и тьюториалы доступны на официальном сайте проекта.

Автор: el_gato

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js