Как добиться слабой связи между драйверами JDBC и исходным кодом?

Я не хочу, чтобы мой код был тесно связан с каким-либо драйвером JDBC (например, MySql). Я хочу сделать универсальный код, который может работать со многими реализациями баз данных. И я не совсем понимаю, как достичь этой цели при использовании JDBC.

Я думаю, что для этого мне нужно только экспортировать имя класса драйвера (и строку подключения) в .properties файл (например "com.mysql.jdbc.Driver"), а затем в коде используйте это так Class.forName(PROPERTIES.getDriverName()).newInstance(); Поэтому, когда я решаю изменить свою базу данных, все, что мне нужно изменить, это имя драйвера jdbc в .properties файл (например, для "COM.ibm.db2.jdbc.app.DB2Driver"), строка подключения и изменение драйвера .jar файл в classpath.

Это правильно?

4 ответа

Решение

Слабое сцепление может быть достигнуто несколькими способами -

A. Используйте Hibernate, но это может быть излишним для ваших нужд и снизить производительность (если ваше приложение выполняет в основном операции записи)

Б. Используйте Spring-JDBC или любую другую инфраструктуру, которая служит оболочкой JDBC - обычно они предоставляют какую-то абстракцию

C. Если ваш код является кодом Java EE, вы можете работать с источниками данных и настраивать их на сервере приложений Java - вы будете искать источник данных по имени и не будете знать подробности реализации

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

Ваш класс Data Engine может считывать информацию о драйвере jdbc из конфигурации (свойства файлов XML) - это, в основном, то, что делает, например, Hibernate.

Вы правильно поняли. Выведите на экран имя класса драйвера, URL базы данных, пользователя и пароль, и все готово. В любом случае это то, что делается большинством "фреймворков": серверы Java EE позволяют настраивать источники данных на сервере и получать к ним доступ с помощью JNDI. Для этого Hibernate имеет записи в своем файле конфигурации, пулы соединений обычно используют XML или файл свойств для хранения своей конфигурации.

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

Это может сработать для вас, конечно. Я буду немного более полон для будущих читателей вопроса, хотя:

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

MySQL:

select * from products LIMIT 0,10

затем для следующих 10 строк:

select * from products LIMIT 10,10

и т.п.

Фантастика, поэтому пользователи могут использовать MySQL для базы данных. А что если они используют postgres, еще одну бесплатную и очень популярную базу данных? Этот запрос не будет работать:

SELECT * FROM product LIMIT 10 OFFSET 10

Таким образом, ваш код не так переносим, ​​как вы думаете.

Один из способов обойти это - создать свои собственные интерфейсы (интерфейс Query, интерфейс Access) для всех запросов / обращений, которые вы планируете делать, и затем создать фабрику запросов, которую можно создать на основе базы данных Dialect (MySQL, postgres). и т. д.) и создайте MySQLQueryImpl и PostGresQueryImpl (оба реализуют интерфейс Query).

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

Или же...

Другой вариант, который, вероятно, более элегантен и защищен от ошибок (ну... может быть), это позволить кому-то другому сделать это за вас. Hibernate - это очень распространенный инструмент, который абстрагирует для вас чтение и запись базы данных, и его можно настроить на использование другой базы данных так, как вы хотите, только он имеет многолетний опыт и исправляет ошибки. Это не самая простая вещь для изучения (для сложных запросов и объединений и т. Д.), Но для базовых моделей и сопоставления с базой данных она даст вам все, что вы хотите, и даже больше, в том числе возможность очень легко и лениво включать / выключать кэширование. загрузка данных, чтобы вы не вносили тысячи записей, которые вы не будете использовать. Создание и укрепление системы, подобной этой, заняло бы много времени.

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

Использовать источник данных вместо соединения. Это дает вам возможность создавать соединения разными способами, используя JNDI, из пула соединений и т. Д.

Больше на Datasource, прямо из javax.sql.DataSource javadoc

Фабрика для соединений с физическим источником данных, который представляет этот объект DataSource. Альтернатива средству DriverManager, объект DataSource является предпочтительным средством получения соединения.

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

Такие библиотеки, как Mybatis, Hibernate, которые поддерживают парадигму ORM, автоматизируют эти шаги для вас.

Другие вопросы по тегам