Весна DAO проти Spring ORM проти Spring JDBC


103

Я переглядав технології доступу до даних, що підтримуються Spring, і помітив, що в ньому згадується кілька варіантів, і я не впевнений у різниці між ними:

Як я розумію, Spring JDBC надає шаблони для зменшення коду дощової панелі для доступу до бази даних простим старим способом - ви пишете власні запити SQL.

Spring-ORM надає спрощені шаблони для доступу до баз даних за допомогою технологій ORM, таких як Hibernate, My (i) Batis тощо.

Spring-DAO згідно веб-сайту Spring:

Підтримка об’єкта доступу до даних (DAO) навесні спрямована на полегшення роботи з такими технологіями доступу до даних, як JDBC, Hibernate або JDO.

Я трохи зрозумілий щодо ORM проти JDBC, оскільки вони спрямовані на різні способи доступу до БД. Але Spring-DAO просто заплутаний!

Може хто-небудь, будь ласка, пояснить, які саме відмінності між цими трьома? Якому слід віддати перевагу в яких сценаріях?

Крім того, є ще один проект Spring-DATA( http://projects.spring.io/spring-data/ ) Тепер це вищий батьківський проект для всіх технологій доступу до даних, які підтримує Spring, або це лише нова назва для Spring -DAO?

Відповіді:


162

Ось ознайомлення з кожною згаданими технологіями.

Весна-DAO

Spring-DAO - це не пружинний модуль у строгому сенсі, а скоріше умовності, які повинні наказувати вам написати DAO та добре їх написати. Таким чином, він не надає ні інтерфейсів, ні реалізацій, ні шаблонів для доступу до ваших даних. Під час написання DAO слід анотувати їх @Repositoryтак, щоб винятки, пов'язані з базовою технологією (JDBC, Hibernate, JPA тощо), послідовно переводилися у відповідний DataAccessExceptionпідклас.

Наприклад, припустимо, що ви зараз використовуєте Hibernate, і ваш службовий шар вловлює HibernateException, щоб реагувати на нього. Якщо ви перейдете на JPA, ваші інтерфейси DAO не повинні змінюватися, і сервісний рівень все одно буде компілюватися з блоками, які ловить HibernateException, але ви ніколи не входите в ці блоки, оскільки ваші DAO тепер кидають JPA PersistenceException. Використовуючи @Repositoryсвій DAO, винятки, пов’язані з базовою технологією, перекладаються на Spring DataAccessException; ваш сервісний шар фіксує ці винятки, і якщо ви вирішите змінити технологію збереження, та сама Весна DataAccessExceptionsвсе одно буде кинута, оскільки весна переклала рідні винятки.

Однак зауважте, що це обмежене використання з наступних причин:

  1. Зазвичай, ви не повинні ловити винятки за стійкість, оскільки постачальник послуг може скасувати транзакцію (залежно від точного підтипу винятку), і, таким чином, вам не слід продовжувати виконання альтернативним шляхом.
  2. Ієрархія винятків, як правило, багатша у вашого постачальника, ніж те, що надає Spring, і немає остаточного відображення від одного постачальника до іншого. Покладатися на це небезпечно. Однак, це гарна ідея анотувати ваші DAO @Repository, оскільки квасоля буде автоматично додана процедурою сканування. Крім того, Весна може додати до примітки інші корисні функції.

Весна-JDBC

Spring-JDBC надає клас JdbcTemplate, який видаляє сантехнічний код і допомагає сконцентруватися на SQL-запиті та параметрах. Вам просто потрібно налаштувати його за допомогою "A" DataSource, а потім можете написати такий код:

int nbRows = jdbcTemplate.queryForObject("select count(1) from person", Integer.class);

Person p = jdbcTemplate.queryForObject("select first, last from person where id=?", 
             rs -> new Person(rs.getString(1), rs.getString(2)), 
             134561351656L);

Spring-JDBC також пропонує JdbcDaoSupport, який ви можете розширити, щоб розробити свій DAO. В основному він визначає 2 властивості: DataSource та JdbcTemplate, які обидва можуть бути використані для реалізації методів DAO. Він також забезпечує перекладач винятків з винятків SQL до весняних DataAccessExceptions.

Якщо ви плануєте використовувати звичайний jdbc, це модуль, який вам потрібно буде використовувати.

Весна-ОРМ

Spring-ORM - це парасольовий модуль, який охоплює багато стійких технологій, а саме: JPA, JDO, Hibernate та iBatis. Для кожної з цих технологій Spring надає класи інтеграції, так що кожна технологія може бути використана відповідно до принципів конфігурації Spring і плавно інтегрується з управлінням транзакцій Spring.

Для кожної технології конфігурація в основному полягає у введенні DataSourceбобів в якийсь боб SessionFactoryабо EntityManagerFactoryін. Для чистого JDBC немає необхідності в таких класах інтеграції (крім JdbcTemplate), оскільки JDBC покладається лише на джерело даних.

Якщо ви плануєте використовувати ORM на зразок JPA або Hibernate, вам не знадобиться spring-jdbc, а лише цей модуль.

Spring-Data

Spring-Data - це парасольовий проект, який пропонує загальний API для визначення способу доступу до даних (DAO + анотації) більш загальним способом, що охоплює і джерела даних SQL, і NOSQL.

Початкова ідея полягає в тому, щоб забезпечити технологію, щоб розробник записував інтерфейс для DAO (методів пошуку) та класів сутності технологічно-агностичним способом і, виходячи лише з конфігурації (анотації про DAO та сутності + весняна конфігурація, будь то xml- або java) визначає технологію впровадження, будь то JPA (SQL) або redis, hadoop тощо (NOSQL).

Якщо ви дотримуєтесь імен імен, визначених весною для імен методу finder, вам навіть не потрібно вводити рядки запитів, що відповідають методам пошуку для найбільш простих випадків. В інших ситуаціях вам потрібно надати рядок запиту всередині приміток до методів пошуку.

Коли завантажується контекст програми, spring надає проксі для інтерфейсів DAO, які містять весь код платформи, пов'язаний з технологією доступу до даних, і викликає налаштовані запити.

Spring-Data концентрується на не-SQL-технологіях, але все ще надає модуль для JPA (єдиної технології SQL).

Що далі

Знаючи все це, тепер вам належить вирішити, що вибрати. Хороша новина тут полягає в тому, що вам не потрібно робити остаточний остаточний вибір технології. Тут власне джерело живлення Spring: як розробник, ви зосереджуєтесь на бізнесі, коли ви пишете код, і якщо ви робите це добре, зміна базової технології є деталлю реалізації або конфігурації.

  1. Визначте модель даних з класами POJO для сутностей та отримайте / встановіть методи представлення атрибутів сутності та зв'язків з іншими сутностями. Вам, звичайно, потрібно буде коментувати класи та поля сутностей на основі технології, але поки що POJO досить для початку. Просто зосередиться на вимогах бізнесу на даний момент.
  2. Визначте інтерфейси для своїх DAO. 1 DAO охоплює рівно 1 об'єкт, але вам, звичайно, не знадобиться DAO для кожного з них, оскільки ви повинні мати можливість завантажувати додаткові об'єкти, переходячи до відносин. Визначте методи пошуку, дотримуючись строгих угод про іменування.
  3. Виходячи з цього, хтось інший може розпочати роботу над рівнем послуг, з макетами для ваших DAO.
  4. Ви дізнаєтесь різні технології збереження (sql, no-sql), щоб знайти найкраще відповідні ваші потреби, і вибираєте одну з них. Виходячи з цього, ви коментуєте сутності та реалізуєте DAO (або дозволяєте весняним чином реалізувати їх для вас, якщо ви вирішите використовувати джерельні дані).
  5. Якщо бізнес-вимоги розвиваються і вашої технології доступу до даних недостатньо для її підтримки (скажімо, ви почали з JDBC та кількома сутностями, але тепер потрібна більш багата модель даних, а JPA - кращий вибір), вам доведеться змінити реалізацію своїх DAO, додайте кілька анотацій про ваші сутності та змініть конфігурацію весни (додайте визначення EntityManagerFactory). У решті коду вашого бізнесу не повинно відображатися інших впливів на вашу зміну.

Примітка: Управління транзакціями

Spring пропонує API для управління транзакціями. Якщо ви плануєте використовувати весну для доступу до даних, ви також повинні використовувати весну для управління транзакціями, оскільки вони дуже добре інтегруються разом. Для кожної технології доступу до даних, що підтримується весною, існує відповідний менеджер транзакцій для локальних транзакцій, або ви можете вибрати JTA, якщо вам потрібні розподілені транзакції. Усі вони реалізують один і той же API, так що (вкотре) вибір технології - це лише питання конфігурації, яку можна змінити без подальшого впливу на бізнес-код.

Примітка: Весняна документація

Посилання на весняну документацію, про яку ви згадали, досить старі. Ось документація останнього випуску (4.1.6, що охоплює всі теми):

Дані Spring не є частиною весняних рамок. Існує загальний модуль, який слід спочатку прочитати, щоб звикнути до принципів. Документацію можна знайти тут:


Я оцінюю цей відповідь, використовуючи термін "парасолька" в деяких описах тут (наприклад, Spring Data), ідентифікуючи, що всередині є підкомпоненти / модулі (а не парасолька, яка має більш домен). І згадування Spring Data є дуже корисним у контексті, хоча це не було зазначено в питанні.
cellepo

Не spring-jdbcнадає інших корисних інструментів, не згаданих тут? Наприклад, я вважаю SimpleJdbcInsertдуже чистим і корисним як для одноразової вставки, так і для масової (звичайно, до розумного масштабу).
Nom1fan

3

Spring DAO ( D ata A ccess O bject): це об'єкт, що забезпечує абстрактний інтерфейс до каркасів реалізації JDBC, тобто Spring DAO - це узагальнена концепція доступу до JDBC та Hibernate, MyBatis, JPA, JDO, використовуючи індивідуальні класи підтримки. І це забезпечує узагальнену ієрархію винятків шляхом визначення @Repositoryанотації. Ця анотація визначає контейнер Spring для перекладу винятків SQL з ієрархічної SQLExceptionстратегії доступу до даних Spring DataAccessException.

тобто винятки, що стосуються певної платформи, - це вилучення та повторне викидання, як одне з винятків неперевіреного доступу до даних Spring.


Spring JDBC : Для простого JDBC ми використовуємо цей модуль, який залежить тільки від DataSourceі шаблонних класів подобаються JdbcTemplate, NamedParameterJdbcTemplate(компреси JdbcTemplate) і SimpleJdbcTemplateдля зменшення перехресних проблем різання.

public class EmployeeDao {  
private JdbcTemplate jdbcTemplate;  

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
    this.jdbcTemplate = jdbcTemplate;  
}  

public int saveEmployee(Employee e){  
    return jdbcTemplate.update(query);  
}  
public int updateEmployee(Employee e){  
    return jdbcTemplate.update(query);  
}  
public int deleteEmployee(Employee e){  
       return jdbcTemplate.update(query);  
}  

}  

і навесні XML:

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

Spring JDBC також JdbcDaoSupport, NamedParameterJdbcDaoSupport, SimpleJdbcDaoSupport, які є підтримка (тобто зручний ) спосіб розширити і розвинути свій власний DAO абстрактний інтерфейс наступним чином :

public interface EmployeeDao {

    public void saveEmployee(Employee emp);
}

public class EmployeeDaoImpl extends JdbcDaoSupport implements EmployeeDao{

    @Override
    public void saveEmployee(Employee emp) {

        Object[] inputs = new Object[] {emp.getName(), emp.getSalary(), emp.getDept()};
        getJdbcTemplate().update(query, inputs);
    }
}

а навесні XML:

<bean id="employeeDAO" class="EmployeeDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

Spring ORM: Підтримка інструментів ORM, таких як Hibernate, JPA, MyBatis ... легко інтегрує Spring, вводячи їх DataSourceразом із наступними класами та відповідними DaoSupportкласами.

  • SessionFactory для сплячого
  • EntityManagerFactory для JPA,
  • SqlSessionFactory для MyBatis

1

Весна-дао lib зупинилася у версії 2.0.8 (січень 2008 р.). Заняття в Spring-Dao були скопійовані в spring-tx. Отже, якщо вам потрібен клас, який ви знайдете у spring-dao, замість цього додайте залежність до spring-tx . ( Джерело .)


0

Ви можете створити інтерфейс , як SomeObjectDaoі потім створювати різні реалізації цього інтерфейсу , як JdbcSomeObjectDao, HibernateSomeObjectDao. Тоді у своєму SomeObjectServiceкласі ви будете працювати над SomeObjectDaoінтерфейсом і вводити туди одну з конкретних реалізацій. Таким чином, кожна реалізація SomeObjectDaoбуде приховувати деталі, чи ви використовуєте JDBC, або ORM тощо.

Зазвичай JDBC і різні реалізації ORM викидають різного роду винятки. Підтримка DAO Spring може відображати різні, винятки, що стосуються конкретних технологій, до звичайних винятків Spring DAO. Таким чином, ви більше відмежовуєтесь від фактичної реалізації. Також підтримка Spring DAO Spring пропонує набір абстрактних *DataSupportкласів, які ще більше допомагають у розвитку DAO. Таким чином, крім реалізації вашого SomeObjectDaoінтерфейсу, ви можете розширити один *DataSupportклас Spring .


значить, ви маєте на увазі, Spring-Dao абстрагує винятки, характерні для Hibernate / JDO / JDBC, та забезпечує стандартний набір винятків? Чи має templatesдоступ до db? або це просто абстракція, яку слід використовувати з іншими пружинними компонентами? Наприклад, чи можна написати код, який використовує лише spring-dao для доступу до db (не використовуючи spring-jdbc, spring-orm, hibernate чи будь-який інший фреймворк)?
Пат

0

В якості додаткової інформації. Пропоную використовувати Spring Data JPA. Використання анотацій, таких як: @Repository, @Service. Я показую вам приклад:

@Repository("customerEntitlementsRepository")
public interface CustomerEntitlementsRepository extends CrudRepository<BbsExerul, BbsExerulPK> {

  @Query(value = "SELECT " + "CONTRACT_NUMBER, EXECUTIVE_NUMBER, " + "GROUP_VALUE, " + "CODE, "
      + "SUBCODE, " + "CURRENCY " + "FROM BBS_EXERUL " + "WHERE CONTRACT_NUMBER =:clientId AND "
      + "EXECUTIVE_NUMBER =:representativeId", nativeQuery = true)
  Collection<CustomerEntitlementsProjection> getFieldsExerul(@Param("clientId") String clientId,
      @Param("representativeId") String representativeId);

}

Якщо CustomerEntitlementsProjection - це весняна проекція, пов'язана з вами сутністю або DTO pojo;

@Projection(name = "customerEntitlementsProjection", types = { BbsExerul.class })
public interface CustomerEntitlementsProjection {

  String getContractNumber();

  String getExecutiveNumber();

1
Будь ласка, відформатуйте свій код у кодових блоках, щоб він був читабельним.
CertainPerformance
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.