Spring DAO vs Spring ORM vs Spring JDBC

103

Je passais par des technologies d'accès aux données prises en charge par Spring, et j'ai remarqué qu'elle mentionne plusieurs options et je ne suis pas sûr de la différence entre elles:

Si je comprends bien, Spring JDBC fournit des modèles pour réduire le code standard pour accéder à une base de données à l'ancienne: vous écrivez vos propres requêtes SQL.

Spring-ORM fournit des modèles simplifiés pour accéder aux bases de données via les technologies ORM, telles que Hibernate, My (i) Batis, etc.

Spring-DAO selon le site Web de Spring:

La prise en charge de Data Access Object (DAO) dans Spring vise à faciliter le travail avec des technologies d'accès aux données telles que JDBC, Hibernate ou JDO de manière cohérente.

Je suis un peu clair sur ORM vs JDBC car ils visent différentes façons d'accéder à la base de données. Mais Spring-DAO est tout simplement déroutant!

Quelqu'un pourrait-il préciser quelles sont exactement les différences entre ces trois? Laquelle devrait être préférée dans quels scénarios?

En outre, il existe un autre projet Spring-DATAégalement disponible ( http://projects.spring.io/spring-data/ ) Maintenant, est-ce une sorte de projet parent pour toutes les technologies d'accès aux données prises en charge par Spring ou est-ce juste un nouveau nom pour Spring -DAO?

Tapoter
la source

Réponses:

162

Voici une introduction à chaque technologie mentionnée.

Printemps-DAO

Spring-DAO n'est pas un module spring au sens strict, mais plutôt des conventions qui devraient vous imposer d'écrire DAO, et de bien les écrire. En tant que tel, il ne fournit ni interfaces, ni implémentations, ni modèles pour accéder à vos données. Lorsque vous écrivez un DAO, vous devez les annoter @Repositoryafin que les exceptions liées à la technologie sous-jacente (JDBC, Hibernate, JPA, etc.) soient systématiquement traduites dans la DataAccessExceptionsous-classe appropriée .

Par exemple, supposons que vous utilisiez maintenant Hibernate et que votre couche de service attrape HibernateExceptionafin d'y réagir. Si vous passez à JPA, vos interfaces DAO ne devraient pas changer, et la couche de service sera toujours compilée avec des blocs qui capturent HibernateException, mais vous n'entrerez jamais ces blocs car vos DAO lancent maintenant JPA PersistenceException. En utilisant @Repositorysur votre DAO, les exceptions liées à la technologie sous-jacente sont traduites en Spring DataAccessException; votre couche de service intercepte ces exceptions et si vous décidez de changer la technologie de persistance, le même Spring DataAccessExceptionssera toujours lancé car Spring a traduit les exceptions natives.

Notez cependant que cette utilisation est limitée pour les raisons suivantes:

  1. Vous ne devez généralement pas intercepter les exceptions de persistance, car le fournisseur peut avoir annulé la transaction (en fonction du sous-type d'exception exact), et vous ne devez donc pas continuer l'exécution avec un autre chemin.
  2. La hiérarchie des exceptions est généralement plus riche dans votre fournisseur que ce que Spring fournit, et il n'y a pas de mappage définitif d'un fournisseur à l'autre. S'en remettre à cela est dangereux. C'est cependant une bonne idée d'annoter vos DAO @Repository, car les beans seront automatiquement ajoutés par la procédure d'analyse. De plus, Spring peut ajouter d'autres fonctionnalités utiles à l'annotation.

Spring-JDBC

Spring-JDBC fournit la classe JdbcTemplate, qui supprime le code de plomberie et vous aide à vous concentrer sur la requête et les paramètres SQL. Il vous suffit de le configurer avec un DataSource, et vous pouvez ensuite écrire du code comme celui-ci:

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 fournit également un JdbcDaoSupport, que vous pouvez étendre pour développer votre DAO. Il définit essentiellement 2 propriétés: un DataSource et un JdbcTemplate qui peuvent tous deux être utilisés pour implémenter les méthodes DAO. Il fournit également un traducteur d'exceptions des exceptions SQL vers Spring DataAccessExceptions.

Si vous prévoyez d'utiliser jdbc plain, c'est le module que vous devrez utiliser.

Printemps-ORM

Spring-ORM est un module parapluie qui couvre de nombreuses technologies de persistance, à savoir JPA, JDO, Hibernate et iBatis. Pour chacune de ces technologies, Spring fournit des classes d'intégration afin que chaque technologie puisse être utilisée selon les principes de configuration de Spring et s'intègre en douceur avec la gestion des transactions Spring.

Pour chaque technologie, la configuration consiste essentiellement à injecter un DataSourcebean dans une sorte de bean SessionFactoryou EntityManagerFactoryetc. Pour le JDBC pur, il n'y a pas besoin de telles classes d'intégration (à l'exception de JdbcTemplate), car JDBC ne repose que sur un DataSource.

Si vous prévoyez d'utiliser un ORM comme JPA ou Hibernate, vous n'aurez pas besoin de spring-jdbc, mais uniquement de ce module.

Spring-Data

Spring-Data est un projet parapluie qui fournit une API commune pour définir comment accéder aux données (annotations DAO +) d'une manière plus générique, couvrant à la fois les sources de données SQL et NOSQL.

L'idée initiale est de fournir une technologie pour que le développeur écrit l'interface pour un DAO (méthodes de recherche) et les classes d'entités de manière indépendante de la technologie et, en se basant uniquement sur la configuration (annotations sur les DAO & entités + configuration du ressort, que ce soit xml ou java), décide de la technologie d'implémentation, que ce soit JPA (SQL) ou redis, hadoop, etc. (NOSQL).

Si vous suivez les conventions de dénomination définies par spring pour les noms des méthodes de recherche, vous n'avez même pas besoin de fournir les chaînes de requête correspondant aux méthodes de recherche pour les cas les plus simples. Pour d'autres situations, vous devez fournir la chaîne de requête à l'intérieur des annotations sur les méthodes de recherche.

Lorsque le contexte d'application est chargé, spring fournit des proxys pour les interfaces DAO, qui contiennent tout le code standard lié à la technologie d'accès aux données, et appelle les requêtes configurées.

Spring-Data se concentre sur les technologies non SQL, mais fournit toujours un module pour JPA (la seule technologie SQL).

Et après

Sachant tout cela, vous devez maintenant décider quoi choisir. La bonne nouvelle ici est que vous n'avez pas besoin de faire un choix final définitif pour la technologie. C'est en fait là que réside la puissance de Spring: en tant que développeur, vous vous concentrez sur l'entreprise lorsque vous écrivez du code, et si vous le faites bien, changer la technologie sous-jacente est un détail d'implémentation ou de configuration.

  1. Définissez un modèle de données avec des classes POJO pour les entités et des méthodes get / set pour représenter les attributs d'entité et les relations avec d'autres entités. Vous aurez certainement besoin d'annoter les classes d'entités et les champs en fonction de la technologie, mais pour l'instant, les POJO suffisent pour commencer. Concentrez-vous simplement sur les besoins commerciaux pour le moment.
  2. Définissez des interfaces pour vos DAO. 1 DAO couvre exactement 1 entité, mais vous n'aurez certainement pas besoin d'un DAO pour chacune d'elles, car vous devriez pouvoir charger des entités supplémentaires en naviguant dans les relations. Définissez les méthodes de recherche en suivant des conventions de dénomination strictes.
  3. Sur cette base, quelqu'un d'autre peut commencer à travailler sur la couche de services, avec des simulations pour vos DAO.
  4. Vous apprenez les différentes technologies de persistance (sql, no-sql) pour trouver la meilleure solution pour vos besoins et choisissez l'une d'entre elles. Sur cette base, vous annotez les entités et implémentez les DAO (ou laissez spring les implémenter pour vous si vous choisissez d'utiliser spring-data).
  5. Si les exigences métier évoluent et que votre technologie d'accès aux données n'est pas suffisante pour la prendre en charge (par exemple, vous avez commencé avec JDBC et quelques entités, mais vous avez maintenant besoin d'un modèle de données plus riche et JPA est un meilleur choix), vous devrez modifier l'implémentation de vos DAO, ajoutez quelques annotations sur vos entités et modifiez la configuration du ressort (ajoutez une définition EntityManagerFactory). Le reste de votre code métier ne devrait pas voir d'autres impacts de votre modification.

Remarque: Gestion des transactions

Spring fournit une API pour la gestion des transactions. Si vous prévoyez d'utiliser spring pour l'accès aux données, vous devez également utiliser spring pour la gestion des transactions, car ils s'intègrent très bien ensemble. Pour chaque technologie d'accès aux données prise en charge par spring, il existe un gestionnaire de transactions correspondant pour les transactions locales, ou vous pouvez choisir JTA si vous avez besoin de transactions distribuées. Tous implémentent la même API, de sorte que (encore une fois) le choix de la technologie n'est qu'une question de configuration qui peut être modifiée sans autre impact sur le code métier.

Remarque: documentation Spring

Les liens vers la documentation Spring que vous avez mentionnés sont assez anciens. Voici la documentation de la dernière version (4.1.6, couvrant tous les sujets):

Spring-data ne fait pas partie du framework Spring. Il existe un module commun que vous devez d'abord lire pour vous habituer aux principes. La documentation peut être trouvée ici:

Gaétan
la source
J'apprécie cette réponse en utilisant le terme «parapluie» dans certaines descriptions ici (comme Spring Data), identifiant qu'il y a des sous-composants / modules à l'intérieur (plutôt qu'un parapluie étant plus spécifique au domaine). Et mentionner Spring Data est très utile dans le contexte ici, même si cela n'a pas été mentionné dans la question.
cellepo
Ne spring-jdbcfournit pas d'autres outils utiles non mentionnés ici? Par exemple, je trouve SimpleJdbcInserttrès propre et utile à la fois pour l'insertion d'une seule entrée et pour le volume (jusqu'à une échelle raisonnable, bien sûr).
Nom1fan le
3

Spring DAO ( D ata A ccess O bject ): est un objet qui fournit une interface abstraite aux cadres d'implémentation JDBC, c'est-à-dire que Spring DAO est un concept généralisé pour accéder à JDBC et Hibernate, MyBatis, JPA, JDO en utilisant ses classes de support individuelles. Et il fournit une hiérarchie d'exceptions généralisée en définissant une @Repositoryannotation. Cette annotation définit à conteneur Spring pour la traduction d'exception SQL de SQLExceptionla stratégie agnostique accès aux données de printemps DataAccessExceptionde la hiérarchie.

c'est-à-dire que les exceptions spécifiques à la plate-forme sont des captures puis des relances comme l'une des exceptions d'accès aux données non vérifiées de Spring.


Spring JDBC : Pour le JDBC ordinaire, nous utilisons ce module, qui ne dépend que des DataSourceclasses de modèle comme JdbcTemplate, NamedParameterJdbcTemplate(wraps JdbcTemplate) et SimpleJdbcTemplatepour réduire les problèmes transversaux.

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);  
}  

}  

et dans Spring XML:

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

Spring JDBC fournit également JdbcDaoSupport, NamedParameterJdbcDaoSupport, SimpleJdbcDaoSupportqui sont le soutien (c. -à- pratique moyen) d'étendre et de développer notre propre OAC interface abstraite comme suit:

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);
    }
}

et au printemps XML:

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

Spring ORM: Pour le support des outils ORM tels que Hibernate, JPA, MyBatis ... intègre facilement Spring en injectant DataSourceavec les classes suivantes et les DaoSupportclasses respectives .

  • SessionFactory pour Hibernate
  • EntityManagerFactory pour JPA,
  • SqlSessionFactory pour MyBatis
Premraj
la source
1

La bibliothèque spring-dao s'est arrêtée dans la version 2.0.8 (janvier 2008). Les classes de spring-dao ont été copiées dans spring-tx. Donc, si vous avez besoin d'une classe que vous trouvez dans spring-dao, ajoutez plutôt la dépendance à spring-tx . ( Source .)

Paulo Merson
la source
0

Vous créez une interface comme SomeObjectDaopuis créer différentes implémentations de cette interface comme JdbcSomeObjectDao, HibernateSomeObjectDao. Ensuite dans votre SomeObjectServiceclasse vous opérerez sur l' SomeObjectDaointerface, et y injecterez une des implémentations concrètes. Ainsi, chaque implémentation de SomeObjectDaomasquera les détails, que vous utilisiez JDBC, ORM, etc.

Généralement, JDBC et différentes implémentations d'ORM génèrent différents types d'exceptions. Le support DAO de Spring peut mapper ces différentes exceptions spécifiques à la technologie aux exceptions Spring DAO courantes. Vous êtes donc davantage découplé de la mise en œuvre réelle. Le support DAO de Spring offre également un ensemble de *DataSupportclasses abstraites qui aident encore plus au développement DAO. Ainsi, en plus de l'implémentation de votre SomeObjectDaointerface, vous pouvez étendre l'une des *DataSupportclasses de Spring .

mike_m
la source
donc vous voulez dire, spring-dao supprime les exceptions spécifiques à Hibernate / JDO / JDBC et fournit un ensemble standard d'exceptions? En a-t-il templatespour accéder à la base de données? ou est-ce juste une abstraction à utiliser avec d'autres composants de ressort? Par exemple, est-il possible d'écrire du code qui utilise uniquement spring-dao pour accéder à db (sans utiliser spring-jdbc, spring-orm, hibernate ou tout autre framework)?
Pat
0

Comme info supplémentaire. Je vous suggère d'utiliser Spring Data JPA. En utilisant des annotations telles que: @Repository, @Service. Je vous montre un exemple:

@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);

}

Où CustomerEntitlementsProjection est une projection Spring, liée à votre entité ou DTO pojo;

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

  String getContractNumber();

  String getExecutiveNumber();
Brandon Osorio
la source
1
Veuillez formater votre code en blocs de code afin qu'il soit lisible.
CertainPerformance