Страницы

Поиск по вопросам

четверг, 23 января 2020 г.

Дайте грамотный совет. Занимаюсь разработкой своего ORM

#jdbc #java #orm


Всем привет. 
Занимаюсь по-тихоньку развитием своей библиотеки объектно-реляционного отображения
для Java на основе JDBC. Сразу говорю: я не профессиональный программист, я всего лишь
студент 4 курса, но интерес к данной теме есть и хочется сделать что-то стоящее (разбираюсь
в новых темах по мере необходимости). Есть желание сделать библиотеку такой, чтобы
она была интересна не только мне. 
В данный момент уже реализовано:

Представление записей в виде объектов сущностных классов, один объект = одна запись.
Один сущн. класс = одна таблица;
Транзакции;
Автоматическая обработка исключений внутри класса EntityClass (обработка вынесена
в отдельный скрытый метод, там происходит вызов rollback() или метода для переподключения,
в зависимости от ситуации, а так же прочие действия);
Автоматическое переподключение в случае потери соединения (выполняется только если
не используется транзакция);
Подгрузка настроек из properties-файла;
Подгрузка подготовленных запросов из файла (будет ещё дорабатываться, хочу что-то
вроде хранимых процедур, но на стороне клиента, желательно даже с параметрами);
Набор методов в классе Functions для автоматической выборки и прочих вещей (будет
ещё дорабатываться);
Что-то вроде кеширования, но я не знаю, кеширование ли это. Помимо того, что можно
значения полей получать напрямую из ResultSet'а, есть возможность вызвать метод initialization()
и тогда содержимое ResultSet'а перегонится в Map, хранимый в объекте EntityClass. После
этого нужно вызывать отдельный метод для получения значений из Map'а, отображение не
зависят от состояния подключения к БД.
Несколько методов для связывания объектов. Например, метод insertObject(fieldName
: String, object : EntityClass) : void вставляет в указанное поле объект сущн. класса
(а на самом деле просто записывает в это поле внешний ключ). Ещё метод returnObject(fieldName
: String, tableName : String) : EntityClass извлекает из указанного поля объект сущн.
класса, принадлежащий указанной таблице. Методы для прочих связей в РБД пока не реализованы.

В принципе, это всё, что пока есть. Хочу обратить внимание на то, что в данный момент
есть два способа работы с сущн. классами: создание экземпляра класса EntityClass с
передачей ему в качестве параметра имени таблицы, с которой он связан и наследование
от EntityClass. При наследовании нужно класс-предок оформлять по строгому шаблону. Такому:
package entity;
import java.sql.SQLException;
import java.util.ArrayList;
import db_and_orm.EntityClass;
import db_and_orm.Functions;
import db_and_orm.Transaction;

public class Кафедра extends EntityClass {

    private final static String TABLE_NAME = "кафедры";

    //конструкторы для добавления новой записи 
    //после их вызова нужно вызывать "сеттеры", а затем insertRow)
    //полная выборка
    public Кафедра(Transaction trans) {
        super(trans, TABLE_NAME);
    }

    //частичная выборка
    public Кафедра(Transaction trans, String... поля) {
        super(trans, TABLE_NAME, поля);
    }

    //конструкторы для извлечения готовых записей
    //полная выборка
    public Кафедра(Transaction trans, int id) {
        super(trans, TABLE_NAME, id);
    }

    //частичная выборка
    public Кафедра(Transaction trans, int id, String... поля) {
        super(trans, TABLE_NAME, id, поля);
    }

Как видно, поля там не определены, потому что они определяются сами с помощью метаданных
(доступ к полям у меня осуществляется исключительно по имени, передаваемому методу
get().  То есть POJO классы не используются. Сейчас думаю, а может всё таки попытаться
адаптировать всё на POJO классы? Но тогда вопрос, если я буду наследоваться от EntityClass,
то откуда базовый класс будет знать, какие конкретно поля я определил в дочернем? Делать
абстрактный метод я не хочу, это не дело. 
Хочу позже ещё реализовать следующие вещи:


Хранимые процедуры и функции;


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


Допиливание связей;


Применение аннотаций для упрощения работы с библиотекой;


Автоматическое составление структуры БД и отправка запросов на создание таблиц по
составленной объектной модели на уровне ЯП. Хочу без использования всяких XML, чтобы
составление схемы БД происходило только по сущн. классам;


Поддержка составных ключей;


Какой-нибудь контейнер, где будут выполняться операции над группой объектов сущн.
классов. Ну, в общем, хранение объектов и их обработка. Но тут вопрос: какие конкретно
операции могут производиться над группой объектов?


Рефлексивные отношения (вот это под вопросом, я честно говоря, не понимаю зачем они
вообще нужны). 


Вроде всё, до чего додумался. Ещё вопрос: как происходит реализация наследования,
если в РБД его нет. Я думаю, что если класс Б наследуется от А, то должна быть таблица,
которая содержит поля и класса А и класса Б. В классе А нужно как-то ограничивать кол-во
полей.
Цель этого поста: чтобы его прочитали и написали грамотный комментарий и ответы на
вопросы. 
Так же, ответьте на вопрос: что должна иметь ORM-библиотека, чтобы называться полноценной?
Я всё перечислил или что-то упустил? И что нужно, чтобы библиотека была интересна не
только мне?
Заранее спасибо :)    


Ответы

Ответ 1



Я не великий специалист в разработке ORM, как говорится: чукча не писатель, чукча читатель Уберите русскоязычные названия классов, я знаю, что javac и IDE умеют не ругаться на не ASCII идентификаторы, но что более важно, на это ругаются 99.9% девелоперов. Здесь дело не в неуважении к собственной стране, а в правилах. Почему то ведь вся медицина на латыни работает и ничего... Здесь то же самое. Логгирование. Недавно здесь обсуждались системы логгирования и народ сошелся, что наиболее продвинутым будет использование библиотеки логгирования SLF4J - позволяющей присоединять более-менее любую систему логгирования. Можно и старый добрый Log4J. Обычно в логи ORM выдают (в зависимости от уровня логгирования) - SQL запросы которые лежат в основе экзерсисов ORM. Получение JDBC коннекта через JNDI имена/ресурсы (javax.sql.DataSource) Кэширование JDBC коннектов, в частности реализация JDBC Pool Кэширование SQL запросов (PreparedStatement/CallableStatement) Кэширование результатов SQL запросов - ResultSet Реализация разных моделей кэширования, например классический LRU (Least Recently Used) и проч. - вагон и маленькая тележка Ну и т.д.

Комментариев нет:

Отправить комментарий