Что такое dao java
Перейти к содержимому

Что такое dao java

  • автор:

Data Access Object (DAO). Уровень класса

При проектировании информационной системы выявляются некоторые слои, которые отвечают за взаимодействие различных модулей системы. Соединение с базой данных является одной из важнейшей составляющей приложения. Всегда выделяется часть кода, модуль, отвечающающий за передачу запросов в БД и обработку полученных от неё ответов. В общем случае, определение Data Access Object описывает его как прослойку между БД и системой. DAO абстрагирует сущности системы и делает их отображение на БД, определяет общие методы использования соединения, его получение, закрытие и (или) возвращение в Connection Pool.

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

public abstract class AbstractController  < public abstract ListgetAll(); public abstract E getEntityById(K id); public abstract E update(E entity); public abstract boolean delete(K id); public abstract boolean create(E entity); > 

Набор методов не является завершённым, он зависит от конкретной системы. Фиктивный тип K является ключом сущности, редкая таблица, описывающая сущность, не имеет первичного ключа. Так же, в данном классе будет логичным разместить метод закрытие экземпляра PrepareStatement.

public void closePrepareStatement(PreparedStatement ps) < if (ps != null) < try < ps.close(); >catch (SQLException e) < e.printStackTrace(); >> > 
Уровень класса


Реализация DAO на уровне класса подразумевает использование одного единственного коннекта для вызова более чем одного метода унаследованного DAO класса. В этом случае, в вершине иерархии DAO AbstractController, в качестве поля объявляется connection. Абстрактный класс будет выглядеть следующим образом.

public abstract class AbstractController  < private Connection connection; private ConnectionPool connectionPool; public AbstractController() < connectionPool = ConnectionPool.getConnectionPool(); connection = connectionPool.getConnection(); >public abstract List getAll(); public abstract E update(E entity); public abstract E getEntityById(K id); public abstract boolean delete(K id); public abstract boolean create(E entity); // Возвращения экземпляра Connection в пул соединений public void returnConnectionInPool() < connectionPool.returnConnection(connection); >// Получение экземпляра PrepareStatement public PreparedStatement getPrepareStatement(String sql) < PreparedStatement ps = null; try < ps = connection.prepareStatement(sql); >catch (SQLException e) < e.printStackTrace(); >return ps; > // Закрытие PrepareStatement public void closePrepareStatement(PreparedStatement ps) < if (ps != null) < try < ps.close(); >catch (SQLException e) < e.printStackTrace(); >> > > 

Стоит отметить, что в данном примере мы получаем экземпляр Connection из пула соединений, что соответственно стоит реализовать или воспользоваться уже готовыми решениями. Создаём методы по получению getPrepareStatement(String sql) и его закрытию closePrepareStatement(PreparedStatement ps) . Реализация конкретного DAO класса, при такой логике, никогда не должна закрывать в своих методах соединение с базой данных. Соединение закрывается в той части бизнес-логики, от куда был вызван метод. Пример конкретного DAO класса будет выглядеть следующим образом.

public class UserController extends AbstractController  < public static final String SELECT_ALL_USERS = "SELECT * FROM SHEMA.USER"; @Override public ListgetAll() < Listlst = new LinkedList<>(); PreparedStatement ps = getPrepareStatement(SELECT_ALL_PLANET); try < ResultSet rs = ps.executeQuery(); while (rs.next()) < User user = new User(); planet.setId(rs.getInt(1)); planet.setName(rs.getString(2)); lst.add(user); >> catch (SQLException e) < e.printStackTrace(); >finally < closePrepareStatement(ps); >return lst; > @Override public Planet getEntityById(Integer id) < return null; >@Override public boolean delete(Integer id) < return false; >@Override public boolean create(Planet entity) < return false; >> 
public class User implements Serializable < private int id; private String name; 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 "User'; > > 

Экземпляр Connection доступен методу getPrepareStatement(String sql), который в свою очередь доступен любому методу конкретного DAO класса. Стоит помнить, что следует закрывать экземпляр PrepareStatement сразу после его отработки в блоках finally, а возвращать соединение в пул returnConnectionInPool() в части логики системы, где был вызван метод.

Шаблон DAO примеры, достоинства и недостатки

Привет, Вы узнаете о том , что такое dao, Разберем основные из виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое dao, шаблон dao, паттерн dao , настоятельно рекомендую прочитать все из категории Проектирование веб сайта или программного обеспечения.

1. Обзор

Шаблон Data Access Object (DAO) является структурным шаблоном, который позволяет нам изолировать прикладной/бизнес-уровень от постоянного уровня (обычно это реляционная база данных, но это может быть любой другой постоянный механизм) с использованием абстрактного API . Функциональность этого API заключается в том, чтобы скрыть от приложения все сложности, связанные с выполнением операций CRUD в базовом механизме хранения. Это позволяет обоим слоям развиваться отдельно, ничего не зная друг о друге. В этом уроке мы углубимся в реализацию шаблона и узнаем, как использовать его для абстрагирования вызовов к Менеджер сущностей JPA .

2. Простая реализация

Чтобы понять, как работает шаблон dao , давайте создадим базовый пример. Допустим, мы хотим разработать приложение, которое управляет пользователями. Для того чтобы модель домена приложения не зависела от базы данных, мы создадим простой класс DAO, который позаботится о том, чтобы эти компоненты были аккуратно отделены друг от друга . 2.1. Домен Класс Поскольку наше приложение будет работать с пользователями, нам нужно определить только один класс для реализации его доменной модели:

Шаблон DAO примеры, достоинства и недостатки

Класс User представляет собой простой контейнер для пользовательских данных, поэтому он не реализует никакого другого поведения, заслуживающего внимания. Конечно, самый важный выбор дизайна, который нам нужно сделать здесь, — это как сохранить приложение, использующее этот класс, изолированным от любого механизма персистентности, который может быть реализован в какой-то момент. Ну, это именно та проблема, которую пытается решить шаблон DAO. 2.2. DAO API Давайте определим базовый уровень DAO, чтобы мы могли видеть, как он может полностью отделить модель домена от уровня постоянства. Вот API DAO:

Шаблон DAO примеры, достоинства и недостатки

С высоты птичьего полета ясно, что интерфейс Dao определяет абстрактный API, который выполняет операции CRUD над объектами типа T . Благодаря высокому уровню абстракции, который обеспечивает интерфейс, легко создать конкретную, детальную реализацию, которая работает с объектами User . 2.3. UserDao Класс Давайте определим пользовательскую реализацию интерфейса Dao :

Шаблон DAO примеры, достоинства и недостатки

Шаблон DAO примеры, достоинства и недостатки

Класс UserDao реализует все функции, необходимые для извлечения, обновления и удаления объектов User .

  • Для простоты users List действует как база данных в памяти, которая заполнена парой объектов User в конструкторе **

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

Хотя оба класса User и UserDao сосуществуют независимо в одном и том же приложении, нам все еще необходимо выяснить, как последний может использоваться для сохранения уровня персистентности скрытым от логики приложения:

Шаблон DAO примеры, достоинства и недостатки

Пример придуман, но в двух словах показывает мотивы, лежащие в основе шаблона DAO. В этом случае метод main просто использует экземпляр UserDao для выполнения операций CRUD над несколькими объектами User .

  • Наиболее значимым аспектом этого процесса является то, как UserDao скрывает от приложения все низкоуровневые сведения о том, как объекты сохраняются, обновляются и удаляются ** .

3. Об этом говорит сайт https://intellect.icu . Использование шаблона с JPA

Среди разработчиков существует общая тенденция думать, что выпуск JPA снизил до нуля функциональность шаблона DAO, поскольку шаблон становится просто еще одним уровнем абстракции и сложности, реализованным поверх уровня, предоставляемого менеджером сущностей JPA.

Безусловно, в некоторых сценариях это действительно так. Несмотря на это , иногда мы просто хотим предоставить нашему приложению только несколько доменных методов API-интерфейса менеджера сущностей. В таких случаях шаблон DAO имеет свое место.

3.1. JpaUserDao Класс

С учетом вышесказанного давайте создадим новую реализацию интерфейса Dao , чтобы мы могли увидеть, как он может инкапсулировать функциональность, предоставляемую менеджером сущностей JPA из коробки:

Шаблон DAO примеры, достоинства и недостатки

Шаблон DAO примеры, достоинства и недостатки

  • Класс JpaUserDao способен работать с любой реляционной базой данных, поддерживаемой реализацией JPA. **

Кроме того, если мы внимательно посмотрим на класс, мы поймем, как использовать https://en.wikipedia.org/wiki/Composition over inheritance[Composition]и Dependency Инъекция позволяет нам вызывать только методы менеджера сущностей, требуемые нашим приложением.

Проще говоря, у нас есть специализированный API для конкретного домена, а не весь API менеджера сущностей.

3.2. Рефакторинг класса User

В этом случае мы будем использовать Hibernate в качестве реализации по умолчанию для JPA, поэтому мы соответствующим образом проведем рефакторинг класса User :

Шаблон DAO примеры, достоинства и недостатки

3.3. Начальная загрузка JPA Entity Manager программно

Предполагая, что у нас уже есть работающий экземпляр MySQL, работающий локально или удаленно, и таблица базы данных «пользователи» , заполненная некоторыми записями пользователей, нам нужно получить диспетчер сущностей JPA, чтобы мы могли использовать класс JpaUserDao для выполнения операций CRUD в базе данных.

В большинстве случаев мы выполняем это с помощью типичного файла «persistence.xml», который является стандартным подходом

В этом случае мы воспользуемся подходом xml-less и получим менеджер сущностей с простой Java через удобный https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/ . jpa/boot/internal/EntityManagerFactoryBuilderImpl.html[EntityManagerFactoryBuilderImpl] класс.

Для получения подробного объяснения о том, как запустить реализацию JPA с помощью Java, перейдите по ссылке:/java-bootstrap-jpa[эта статья].

3.4. UserApplication Class

Наконец, давайте проведем рефакторинг исходного класса UserApplication , чтобы он мог работать с экземпляром JpaUserDao и выполнять операции CRUD с сущностями User :

Шаблон DAO примеры, достоинства и недостатки

Даже когда пример довольно ограничен, он остается полезным для демонстрации того, как интегрировать функциональность шаблона DAO с той, которую предоставляет менеджер сущностей.

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

Наиболее важный момент, на который следует обратить внимание, заключается в том, как класс JpaUserDao помогает полностью исключить независимость класса UserApplication от того, как уровень персистентности выполняет операции CRUD ** .

Кроме того, мы могли бы поменять MySQL на любую другую СУБД (и даже на плоскую базу данных) в будущем, и все же наше приложение продолжало бы работать как положено, благодаря уровню абстракции, обеспечиваемому интерфейсом Dao и менеджером сущностей ,

Преимущества использования шаблона проектирования DAO

Шаблон проектирования DAO или Data Access Object — хороший пример объектно-ориентированных принципов абстракции и инкапсуляции. Он отделяет логику сохраняемости от отдельного уровня, называемого уровнем доступа к данным, который позволяет приложению безопасно реагировать на изменения в механизме сохраняемости. Например, если вы перейдете от механизма сохранения на основе файлов к базе данных, ваше изменение будет ограничено уровнем доступа к данным и не повлияет на уровень службы или объекты домена. Объект доступа к данным или шаблон DAO в значительной степени стандартен в приложении Java, являясь ядром Java, веб-приложением или корпоративным приложением. Ниже приведены еще несколько преимуществ использования шаблона DAO в приложении Java:

Шаблон DAO примеры, достоинства и недостатки

  1. Шаблон проектирования DAO также обеспечивает низкую связь между различными частями приложения. При использовании шаблона проектирования DAO ваш уровень представления полностью независим от уровня DAO, и только уровень сервиса зависит от него, который также абстрагируется с помощью интерфейса DAO.
  2. Шаблон проектирования DAO позволяет тесту JUnit работать быстрее, поскольку он позволяет создавать Mock и избегать подключения к базе данных для запуска тестов. Это улучшает тестирование, потому что проще написать тест с Mock-объектами, а не тест интеграции с базой данных. В случае возникновения каких-либо проблем при запуске модульного теста вам нужно проверять только код, а не базу данных. Также защищает от проблем с подключением к базе данных и окружающей среды.
  3. Поскольку шаблон DAO основан на интерфейсе, он также продвигает принцип объектно-ориентированного проектирования «программирование для интерфейса, а не реализация», что приводит к гибкому и качественному коду.
  4. Сила шаблона DAO состоит в том, что они позволяют вам создать хороший уровень абстракции реальной системы хранения. Они обеспечивают более объектно-ориентированное представление уровня сохраняемости и четкое разделение между доменом и кодом, который фактически будет выполнять доступ к данным (прямой JDBC, структуры сохраняемости, ORM или даже JPA).
  5. Общие вызовы для получения объектов.
  6. После того, как вы настроили общий поток создания / чтения / обновления / удаления, общий макет можно повторить для других DAO.
  7. Он также консолидирует, где может идти конкретная часть вашего кода. Отделяет бизнес-логику от других компонентов вашего кода.
  8. абстрактное разделение
  9. единая точка определения для таблицы БД — Отображение атрибутов объекта
  10. прозрачная возможность реализации DAO для других типов хранилищ
  11. разработать шаблон интерфейса, которому следуют все DAO
  12. разработка более или менее стандартного тестового класса JUnit для результатов DAO в лучшем тестовом покрытии
  13. полный контроль над спецификой
  14. нет потери производительности из-за слишком общего решения
  15. Абстракция для реальной реализации доступа к базе данных отделяет стратегию доступа к данным от бизнес-логики пользователя. Это позволило нам выбрать краткосрочную стратегию реализации (шаблон Spring JDBC) для начальной фазы проекта с возможностью перехода на IBATIS или Hibernate позже. (Выбор, который мы не можем сделать в настоящее время.)
  16. Такое разделение дает значительные преимущества тестируемости, так как вся реализация доступа к данным может быть смоделирована в модульном тестировании. (Это, наверное, самое большое преимущество)
  17. Объединение этого со Spring позволяет нам внедрить любую реализацию БД в выбранную нами систему (хотя это, возможно, больше говорит о DI, чем о шаблоне DAO).

Недостатки использования шаблона DAO

  1. это еще один слой, который усложняет системы . Но я думаю, это цена, которую нужно заплатить за то, чтобы не привязывать свой код к базовому API сохраняемости.
  2. Это не самая гибкая вещь.
  3. Если вы хотите отложить загрузку некоторых дочерних объектов, вам придется либо смешивать DAO с другими слоями, либо принимать меры предосторожности при попытке получить ленивые объекты.
  4. Если вы напишете DAO от руки, код может стать утомительным и повторяющимся.
  5. много шаблонного кода

4. Заключение

В этой статье мы подробно рассмотрели ключевые концепции шаблона DAO, как реализовать его в Java и как использовать его поверх менеджера сущностей JPA.

Вау!! �� Ты еще не читал? Это зря!

  • Row Data Gateway (Шлюз к данным записи)
  • Active Record ( Активная запись)
  • Table Data Gateway (Шлюз к данным таблицы)
  • Data Mapper
  • orm , object-relational mapping , объектно-реляционное отображение , active record ,
  • паттерны архитектуры источников данных , row data , gateway , active record ,

Исследование, описанное в статье про dao, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое dao, шаблон dao, паттерн dao и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Проектирование веб сайта или программного обеспечения

Spring и Data Access Object (DAO)

Поддержка объекта доступа к данным (Data Access Object/DAO) в Spring направлена на упрощение работы с технологиями доступа к данным (такими как JDBC, Hibernate или JPA). Это позволяет легко переключаться между вышеупомянутыми технологиями поддержки постоянного хранения, а также не беспокоиться о перехвате исключений, характерных для каждой технологии.

Согласованная иерархия исключений

Spring обеспечивает удобный переход от специфичных для технологии исключений, таких как SQLException , к собственной иерархии классов исключений, в которой корневым исключением является DataAccessException . Эти исключения обертывают исходное исключение, поэтому отсутствует риск того, что вы можете утратить какую-либо информацию о том, что могло пойти не так.

В дополнение к исключениям JDBC, Spring также может обернуть специфические исключения JPA и Hibernate, преобразуя их в набор организованных исключений времени выполнения. Это позволяет обрабатывать большинство невосстанавливаемых исключений постоянного хранения только на соответствующих уровнях, не прибегая к раздражающим стереотипным блокам «catch-and-throw» и объявлениям исключений в ваших DAO. (Однако вы все равно можете отлавливать и обрабатывать исключения везде, где это необходимо). Как упоминалось выше, исключения JDBC (включая диалекты, специфичные для баз данных) также преобразуются в ту же самую иерархию, что означает, что вы можете выполнять некоторые операции с JDBC в рамках модели согласованного программирования.

Предшествующее пояснение справедливо и в отношении различных классов шаблонов в средствах поддержки Spring для различных ORM-фреймворков. Если вы используете классы на основе перехватчиков, приложение должно само заниматься обработкой HibernateExceptions и PersistenceExceptions , предпочтительно делегируя её методам convertHibernateAccessException(..) или convertJpaAccessException(..) утилиты SessionFactoryUtils , соответственно. Эти методы преобразуют исключения в исключения, совместимые с исключениями в иерархии исключений org.springframework.dao . Поскольку PersistenceExceptions непроверяемые, они тоже могут быть сгенерированы (при этом, правда, жертвуя типизированной абстракцией DAO в плане исключений).

На следующем изображении показана иерархия исключений, которую предлагает Spring. (Обратите внимание, что иерархия классов, представленная на рисунке, показывает только часть всей иерархии DataAccessException ).

Аннотации, используемые для настройки классов DAO или репозитория

Лучший способ обеспечить, чтоб ваши объекты доступа к данным (DAO) или репозитории гарантированно преобразовывали (транслировали) исключения, – это использовать аннотацию @Repository . Эта аннотация также позволяет средствам поддержки сканирования компонентов находить и настраивать ваши DAO и репозитории без необходимости предоставлять для них XML-записи конфигурации. В следующем примере показано, как использовать аннотацию @Repository :

@Repository public class SomeMovieFinder implements MovieFinder < // . >
  1. Аннотация @Repository .
@Repository class SomeMovieFinder : MovieFinder < // . >
  1. Аннотация @Repository .

Любой реализации DAO или репозиторию требуется доступ к ресурсу постоянного хранения, в зависимости от используемой технологии постоянного хранения. Например, репозиторию на основе JDBC необходим доступ к DataSource из JDBC, а хранилищу на основе JPA – доступ к EntityManager . Самый простой способ добиться этого – внедрить зависимость ресурса с помощью одной из аннотаций @Autowired , @Inject , @Resource или @PersistenceContext . Следующий пример рабочий в отношении репозитория JPA:

@Repository public class JpaMovieFinder implements MovieFinder < @PersistenceContext private EntityManager entityManager; // . >
@Repository class JpaMovieFinder : MovieFinder < @PersistenceContext private lateinit var entityManager: EntityManager // . >

Если используются классические API-интерфейсы Hibernate, можно внедрить SessionFactory , как показано в следующем примере:

@Repository public class HibernateMovieFinder implements MovieFinder < private SessionFactory sessionFactory; @Autowired public void setSessionFactory(SessionFactory sessionFactory) < this.sessionFactory = sessionFactory; >// . >
@Repository class HibernateMovieFinder(private val sessionFactory: SessionFactory) : MovieFinder < // . >

Последний пример, который мы продемонстрируем, относится к типичному средству поддержки JDBC. DataSource можно внедрить в метод инициализации или конструктор, где вы создадите JdbcTemplate и другие классы поддержки доступа к данным (такие как SimpleJdbcCall и т.д.), используя этот DataSource . В следующем примере выполняется автоматическое обнаружение и связывание DataSource :

@Repository public class JdbcMovieFinder implements MovieFinder < private JdbcTemplate jdbcTemplate; @Autowired public void init(DataSource dataSource) < this.jdbcTemplate = new JdbcTemplate(dataSource); >// . >
@Repository class JdbcMovieFinder(dataSource: DataSource) : MovieFinder < private val jdbcTemplate = JdbcTemplate(dataSource) // . >

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

Data Access Object (DAO) в Java

При разработке приложений часто встает вопрос организации доступа к данным. В реальных приложениях данные могут быть размещены в различных источниках — это могут быть различные базы данных, файлы, веб-сервисы и т.д. Для удобства работы с такими различными источниками данных был разработан шаблон проектирования DAO (Data Access Object).

Основная идея DAO заключается в том, что создается интерфейс (или абстрактный класс), который описывает все возможные операции с данными. Это может быть операции добавления, удаления, обновления и извлечения данных. Затем для каждого конкретного источника данных создается своя реализация этого интерфейса, в которой эти операции выполняются конкретным для этого источника данных способом.

public interface Dao<T>

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

В зависимости от требований приложения, DAO может быть довольно простым и содержать только базовые операции CRUD (создание, чтение, обновление, удаление), а может быть и довольно сложным и включать в себя сложные запросы к данным, связанные с бизнес-логикой приложения.

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

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

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

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