Spring DATA Présentation Spring Data est un projet de Spring créé pour répondre aux besoins de : écrire plus simplement l'accès aux données et avoir une couche d'abstraction commune à de multiples sources de données. Spring Data Commons contient : les classes pour fonctionner, les interfaces que l'utilisateur aura à étendre (directement ou pas) : Repository, CrudRepository et PagingAndSortingRepository Interfaces de base En fonction des méthodes de base que le développeur voudra utiliser, ce dernier étendra une des trois interfaces. Repository ne sert qu'à dire que l'interface qui l'étend est un repository CrudRepository fournie les méthodes CRUD pour la source de données sous-jacente (save, findOne, findAll, etc.). PagingAndSortingRepository (cette dernière étend CrudRepository qui étend Repository) accorde l’accès, en plus des méthodes CRUD, à un ensemble de méthodes permettant de faire de la pagination et du tri. Ces interfaces prennent deux types paramétrés : le type de l'entité que l'on manipule et le type de l'identifiant de l'entité. CrudRepository<T, ID> public interface CrudRepository<T, ID> extends Repository<T, ID> { <S extends T> S save(S entity); <S extends T> Iterable<S> saveAll(Iterable<S> entities); Optional<T> findById(ID id); boolean existsById(ID id); Iterable<T> findAll(); Iterable<T> findAllById(Iterable<ID> ids); long count(); void deleteById(ID id); void delete(T entity); void deleteAll(Iterable<? extends T> entities); void deleteAll(); } Exemple public interface PersonneRep extends CrudRepository<Personne, Long> { } public class PersonneRepTest { @Autowired private PersonneRep personneRep; public void setup() { personneRep.deleteAll(); } public void testSave() { ... Personne personneSauvee = personneRep.save(personne); ... } } PagingAndSortingRepository public abstract interface PagingAndSortingRepository extends CrudRepository { public Iterable findAll(Sort sort); public Page findAll(Pageable pageable); } Exemple public interface PersonnePaginationRep extends PagingAndSortingRepository<Personne, Long>{} public class PersonnePaginationRepTest { @Autowired private PersonnePaginationRep personnePaginationRep; public void testTriDesc(){ ... Iterable<Personne> personnesTrouvees = personnePaginationRep.findAll(new Sort(Sort.Direction.DESC, "nom")); ... } } Méthodes requêtes Spring Data permet d'écrire des requêtes à partir des noms de méthode : vous écrivez la méthode avec certains mots-clés (And, Or, Containing, StartingWith, etc., définis dans les documentations de référence, par exemple celle-là) Spring se charge de traduire ce nom de méthode en requête puis de l'exécuter au moment voulu, comme un grand Exemple public interface PersonneRep extends CrudRepository { // recherche une personne par son attribut "nom" Personne findByNom(String nom); // ici, par son "nom" ou "prenom" Personne findByNomOrPrenom(String nom, String prenom); List<Personne> findByNomAndPrenomAllIgnoreCase(String nom, String prenom); List<Personne> findByNomOrderByPrenomAsc(String nom) } La requête @Query Bien que pratiques, les méthodes-requêtes peuvent devenir très longues et donc peu commodes pour les requêtes un peu complexes. Spring Data possède une annotation @Query dans laquelle on peut mettre en paramètre la requête sous forme de String. Dans ce cas, le nom de la méthode n'est pas pris en compte. Exemple @Query("from Personne p where p.nom = ?1 and p.prenom = ?2") public Personne maRequêteAvecQueryDeRechercheParNomEtPreno m(String nom, String prenom); Si la requête fait des modifications sur les entités, il faut ajouter l'annotation @Modifying. @Query("update Personne p set p.nom = :nom where p.id = :id") @Modifying public int metAJourNom(@Param("nom")String nom, @Param("id") Long id); Configuration Pour utiliser Spring Data, nous devons configurer les beans: DataSource LocalContainerEntityManagerFactoryBean. Nous avons besoin de ce bean pour contrôler les entités. Dans ces beans, nous devons spécifier le fournisseur de persistance, à l’image de HibernatePersistence Nous devons aussi configurer le bean pour la gestion des transactions à l’image de JpaTransactionManager (pour pouvoir utiliser l'annotation @Transactional. Nous devons en outre ajouter les dépendances maven : <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> </dependency> Exemple Créer un fichier property de configuration de la base de données database.properties Créer une classe de configuration des données pour configurer les beans DataSource , LocalContainerEntityManagerFactoryBean et JpaTransactionManager Créer la classe Entity Créer la classe repository Créer la classe controleur Créer la classe service Etape 1 : signaler le projet Spring <servlet> <servlet-name>sample</servlet-name> <servletclass>org.springframework.web.servlet.DispatcherServlet</servle t-class> <init-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext </param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <param-value>com.ipsas.spring.config.WebConfig</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>sample</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> Etape 2: Créer le fichier de configuration Web @Configuration @EnableWebMvc @ComponentScan("com.ipsas.spring") public class WebConfig extends WebMvcConfigurerAdapter { } Dépendances nécessaires <properties> <spring.framework>5.0.0.RELEASE</spring.framework> </properties> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.framework}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.framework}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.framework}</version> </dependency> Etape 3 : Configuration des données @Configuration @EnableTransactionManagement @EnableJpaRepositories("com.ipsas.spring.repository") @PropertySource("classpath:database.properties") public class DataConfig { private final String PROPERTY_DRIVER = "driver"; private final String PROPERTY_URL = "url"; private final String PROPERTY_USERNAME = "user"; private final String PROPERTY_PASSWORD = "password"; private final String PROPERTY_SHOW_SQL = "hibernate.show_sql"; private final String PROPERTY_DIALECT = "hibernate.dialect"; @Autowired Environment environment; Etape 4 : Configuration de l’EntityManagerFactoryBean et DataSource @Bean LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean lfb = new LocalContainerEntityManagerFactoryBean(); lfb.setDataSource(dataSource()); lfb.setPersistenceProviderClass(HibernatePersistence.class); lfb.setPackagesToScan("com.ipsas.spring.model"); lfb.setJpaProperties(hibernateProps()); return lfb; } Properties hibernateProps() { Properties properties = new Properties(); properties.setProperty(PROPERTY_DIALECT, environment.getProperty(PROPERTY_DIALECT)); properties.setProperty(PROPERTY_SHOW_SQL, environment.getProperty(PROPERTY_SHOW_SQL)); return properties; } Etape 4 : Configuration du DataSource et du TransactionManager @Bean DataSource dataSource() { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setUrl(environment.getProperty(PROPERTY_URL)); ds.setUsername(environment.getProperty(PROPERTY_USERNAME)); ds.setPassword(environment.getProperty(PROPERTY_PASSWORD)); ds.setDriverClassName(environment.getProperty(PROPERTY_DRIVER)); return ds; } @Bean JpaTransactionManager transactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory().getO bject()); return transactionManager; } Dépendances nécessaires <properties> <spring.data>1.3.4.RELEASE</spring.data> <hibernate.manager>5.0.0.Final</hibernate.manager> </properties> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>${spring.data}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.manager}</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.0.2</version> </dependency> Etape 5 : database.properties driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/test user=root password= hibernate.dialect=org.hibernate.diale ct.MySQLDialect hibernate.show_sql=true