Vous êtes sur la page 1sur 31

TUTORIAL

SPRING MVC
CRUD WITH
SPRING DATA &
PostrgreSQL

Par
TECHNOLOGIES UTILISEES
JDK 1.7 + JDK 1.8
Tomcat 6
Eclipse STS
PostgresSQL4
Spring 4
JPA2
Hibernate 5
NOTE :
- Une connexion internet est obligatoire pour le fonctionnement de Maven
- La structure finale du projet est présentée à la fin du tutorial
- Il est fortement recommandé d’utiliser une version de Microsoft Office
autre que 2006 pour une bonne lisiblité du document

OBJECTIF
Créer une application de gestion des employés avec :
- Spring MVC côté présentation
- Spring CORE côté couche service
- Spring DATA côté repository
- JPA côté persistance
- PostgreSQL comme SGBD

MISE EN PLACE DE L’ENVIRONNEMENT DE DEVELOPPEMENT


(1) Télécharger « Eclipse STS »
(2) Décompresser l’archive dans un dossier proche de la racine ; exemple
« C:\soft »

MISE EN PLACE DE LA BASE DE DONNEES


(1) Télécharger et installer « PostgresSQL »
(2) Accéder à pgAdmin PostgresSQL Tool
(3) Créer un nouvelle base de données « spring »

1
(4) Créer la table « EMPLOYEE » avec une clé primaire et un
séquenceur avec l’outil « pgAdmin » de postgreSQL
a. Table : EMPLOYEE
b. Clé primaire : PK_EMPLOYEE_ID
c. Sequenceur : EMPLOYEE_SEQ
-- Table: "EMPLOYEE"

-- DROP TABLE "EMPLOYEE";

CREATE TABLE "EMPLOYEE"


(
"ID" numeric NOT NULL,
"FIRST_NAME" character(100),
"LAST_NAME" character(100),
CONSTRAINT "PK_EMPLOYEE_ID" PRIMARY KEY ("ID")
)
WITH (
OIDS=FALSE
);
ALTER TABLE "EMPLOYEE"
OWNER TO postgres;

-- Constraint: "PK_EMPLOYEE_ID"

-- ALTER TABLE "EMPLOYEE" DROP CONSTRAINT "PK_EMPLOYEE_ID";

ALTER TABLE "EMPLOYEE"


ADD CONSTRAINT "PK_EMPLOYEE_ID" PRIMARY KEY("ID");

2
-- Sequence: "EMPLOYEE_SEQ"

-- DROP SEQUENCE "EMPLOYEE_SEQ";

CREATE SEQUENCE "EMPLOYEE_SEQ"


INCREMENT 1
MINVALUE 1
MAXVALUE 999999999999999999
START 22
CACHE 1;
ALTER TABLE "EMPLOYEE_SEQ"
OWNER TO postgres;

MISE EN PLACE DU SERVEUR D’APPLICATION


(1) Télécharger « Tomcat »
(2) Décompresser l’archive dans un dossier proche de la racine ; exemple
« C:\soft »

CREATION DU PROJET
(1) Créer un projet « maven » sous STS :
a. Choisir un nouveau projet Spring

3
b. Choisir un nouveau projet Spring : « Spring Legacy Project »

(2) Créer un projet « Spring MVC Project »

4
(3) Spécifier la structure des paquets du projet « com.training.spring » :

(4) Mettre en place l’arborecence de packets suivantes :

(5) Ajouter les dépendances nécessaires :


a. Spring context API : core du framework Spring
b. Spring MVC API : framework MVC de Spring
c. Spring ORM API : framework d’accès DB Spring
d. Spring DATA API : framework Spring Data
e. Hibernate API : JPA provider implémentation
f. Hibernate Validator API : implémentation de Beans Validation
g. PostgresSQL JDBC API : implémentation PostgresSQL de JDBC
h. Apache Common Lang API : API utilitaire

5
<properties>
<java-version>1.8</java-version>
<org.springframework-
version>3.1.1.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
<org.hibernate-version>5.2.16.Final</org.hibernate-version>
<org.hibernate-validator-
version>5.2.5.Final</org.hibernate-validator-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j --
>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>

6
<!-- Database access dependencies - START -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>

<!--
https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${org.hibernate-version}</version>
</dependency>

<!--
https://mvnrepository.com/artifact/org.hibernate/hibernate-validator
-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${org.hibernate-validator-version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --
>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1212.jre7</version>
</dependency>

7
<!-- Spring Data -->
<!--
https://mvnrepository.com/artifact/org.springframework.data/spring-
data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>

<!--
https://mvnrepository.com/artifact/org.springframework/spring-beans
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework-version}</version>
</dependency>

<!-- Database access dependencies - END -->

8
CREATION DU MODELE

Créer une nouvelle entité modèle « Employee.java »


package com.training.spring.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.annotations.Formula;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;

@Entity
@Table(name = "\"EMPLOYEE\"")
@NamedQueries({
@NamedQuery(name="Employee.findAll",
query="SELECT emp FROM Employee emp"),
@NamedQuery(name="Employee.findByName",
query="SELECT emp FROM Employee emp WHERE emp.firstName
= :firstName")})
public class Employee implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@SequenceGenerator(name = "\"EMPLOYEE_GENERATOR\"", sequenceName =
"\"EMPLOYEE_SEQ\"")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"\"EMPLOYEE_GENERATOR\"")
@Column(name = "\"ID\"")
private Integer id;

9
@Column(name = "\"FIRST_NAME\"")
@Size(min=1, max=100)
@NotNull
@NotBlank
@NotEmpty
private String firstName;

@Column(name = "\"LAST_NAME\"")
@Size(min=1, max=100)
private String lastName;

@Formula("firstName" + "_" + "lastName")


private transient String completeName;

public Integer getId() {


return id;
}

public void setId(Integer id) {


this.id = id;
}

public String getFirstName() {


return firstName;
}

public void setFirstName(String firstName) {


this.firstName = firstName;
}

public String getLastName() {


return lastName;
}

public void setLastName(String lastName) {


this.lastName = lastName;
}

10
COUCHE REPOSITORY

Dans la couche Repository on va développer les classes Repository


de l’EMPLOYEE

DEVELOPPER L’INTERFACE REPOSITORY EMPLOYEE


« EMPLOYEEREPOSITORY.JAVA »

Source : EmployeeRepository.java
package com.training.spring.repository;

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.training.spring.domain.Employee;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee,
Integer>{

List<Employee> findByFirstName(String firstName);

@Query("SELECT emp FROM Employee emp WHERE emp.firstName


LIKE :firstNameLike")
Page<Employee>
performSearchByFirstName(@Param("firstNameLike") String
firstNameLike,
Pageable pageable);

11
DEVELOPPER LA COUCHE SERVICE

Dans la couche Service on va développer les classes Service de


l’EMPLOYEE qui fait de simples appels aux méthodes de
« EmployeeRepository » pré-définies.

DEVELOPPER L’INTERFACE SERVICE EMPLOYEE


« EMPLOYEESERVICE.JAVA »

Source : EmployeeService.java
package com.training.spring.service;

import java.util.List;

import com.training.spring.domain.Employee;

public interface EmployeeService {

public List<Employee> list();

public Employee get(int id);

public void saveOrUpdate(Employee employee);

public void delete(int id);

12
DEVELOPPER L’IMPLEMENTATION SERVICE EMPLOYEE
« EMPLOYEESERVICEIMPL.JAVA

Service : EmployeeServiceImpl.java

package com.training.spring.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.training.spring.domain.Employee;
import com.training.spring.repository.EmployeeRepository;

@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeRepository employeeRepository;
@Override
public List<Employee> list() {
return employeeRepository.findAll();
}
@Override
public Employee get(int id) {
return employeeRepository.findOne(id);
}
@Override
public void saveOrUpdate(Employee employee) {
employeeRepository.saveAndFlush(employee);
}
@Override
public void delete(int id) {
employeeRepository.delete(id);

}
}

13
CONFIGURER L’ACCES A LA BASE DE DONNEES DANS LE FICHIER
« ROOT-CONTEXT.XML »

La Configuration de l’accès à la base de données sera mise dans « root-


context.xml » le ficher root car le même projet peut exposer un Web service et
un module web en même temps en partageant le même accès à la base de
données

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/bea
ns http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- Root Context: defines shared resources visible to all


other web components -->
<!-- Database access configuration -->
<bean id="entityManagerFactoryBean"
name="entityManagerFactoryBean"
class="org.springframework.orm.jpa.LocalContainerEntityManage
rFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan"
value="com.training.spring.domain" />
<property name="persistenceProvider">
<bean
class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>

14
<property name="jpaProperties">
<props>
<prop
key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</p
rop>
<prop key="hiberate.show_sql">true</prop>
</props>
</property>
</bean>

<bean id="dataSource" name="dataSource"


class="org.springframework.jdbc.datasource.DriverManagerDataSource
">
<property name="driverClassName"
value="org.postgresql.Driver"/>
<property name="url"
value="jdbc:postgresql://localhost:5432/spring4"/>
<property name="username" value="postgres"/>
<property name="password" value="sayo"/>
</bean>
<bean id="transactionManager" name="transactionManager"

class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactoryBean"/>
</bean>

15
<tx:annotation-driven transaction-manager="transactionManager"/>

<jpa:repositories base-
package="com.training.spring.repository"
entity-manager-factory-
ref="entityManagerFactoryBean"
transaction-manager-
ref="transactionManager"/>

<context:component-scan base-
package="com.training.spring.service" />

</beans>

Note : il faut remplacer le mot de passe de la DB « sayo » par celui


que vous avez saisie lors de l’installation de postgreSQL.

16
DEVELOPPER LA COUCHE PRESENTATION
Dans ce tutorial on va utiliser la notion de ModelAttribute

DEVELOPPER LE CONTROLEUR « HOMECONTROLLER.JAVA »

Source : HomeController.java

package com.training.spring.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.training.spring.domain.Employee;
import com.training.spring.service.EmployeeService;

/**
* Handles requests for the application home page.
*/
@Controller
public class EmployeeController {

@Autowired
private EmployeeService employeeService;

@RequestMapping("/")
public String handleRequest(Model model) throws Exception {
List<Employee> listEmployees = employeeService.list();
model.addAttribute("employeeList", listEmployees);
return "employeeList";
}

17
/**
* load new user form
*
* @param model
* @return
*/
@RequestMapping(value = "/new", method = RequestMethod.GET)
public String newEmployee(Model model) {
model.addAttribute("employee", new Employee());
return "employeeForm";
}

/**
* delete user
*
* @param id
* @param model
* @return
*/
@RequestMapping(value = "/delete", method =
RequestMethod.POST)
public String deleteEmployee(@RequestParam("id") Integer id,
Model model) {
employeeService.delete(id);
return "redirect:/";
}

18
/**
* save or create user
*
* @param employee
* @return
*/
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveEmployee(@ModelAttribute Employee employee)
{
employeeService.saveOrUpdate(employee);
return "redirect:/";
}
}

19
DEVELOPPER LE CONTROLEUR « EMPLOYEEINFOCONTROLLER.JAVA »

Source : EmployeeInfoController

package com.training.spring.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.training.spring.domain.Employee;
import com.training.spring.service.EmployeeService;

/**
* Handles requests for the application home page.
*/
@Controller
public class EmployeeInfoController {

@Autowired
private EmployeeService employeeService;

@ModelAttribute
public Employee loadEmployee(@RequestParam("id") Integer id)
{
return employeeService.get(id);
}

20
/**
* edit user form
*
* @param employee
* @param model
* @return
*/
@RequestMapping(value = "/edit", method = RequestMethod.GET)
public String editEmployee(@ModelAttribute Employee employee,
Model model) {
model.addAttribute("employee", employee);
return "employeeForm";
}

/**
* User info
*
* @param employee
* @param model
* @return
*/
@RequestMapping(value = "/info", method = RequestMethod.GET)
public String findEmployee(@ModelAttribute Employee employee,
Model model) {
model.addAttribute("employee", employee);
return "employeeInfo";
}

21
DEVELPPER LES PAGES JSP

EMPLOYEELIST.JSP

Source : employeeList.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-
8">
<title>Home</title>
</head>
<body>
<c:url var="newEmployeeURL" value="/new" />
<div align="center">
<h1>Employees List</h1>
<h2>
<a href="${newEmployeeURL}">New Employee</a>
</h2>

<table border="1">
<th>No</th>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Actions</th>

22
<c:forEach var="employee" items="${employeeList}"
varStatus="status">
<tr>
<td>${status.index + 1}</td>
<td>${employee.id}</td>
<td>${employee.firstName}</td>
<td>${employee.lastName}</td>
<td>
<c:url var="editEmployeeURL"
value="/edit">
<c:param name="id"
value="${employee.id}" />
</c:url>
<c:url var="deleteEmployeeURL"
value="/delete">
<c:param name="id"
value="${employee.id}" />
</c:url>
<a href="${editEmployeeURL}">Edit</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<form action="${deleteEmployeeURL}"
method="post"
name="deleteEmployee">
<input type="hidden" name="id"
value="${employee.id}" /> <input
type="submit"
value="Delete" />
</form></td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>

23
EMPLOYEEFORM.JSP
Source : employeeForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"


pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="form"
uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>New or Edit User</title>
</head>
<body>
<c:url var="saveEmployeeURL" value="/save" />
<div align="center">
<h1>New/Edit User</h1>
<table>
<form:form action="${saveEmployeeURL}" method="post"
modelAttribute="employee">
<form:hidden path="id" />
<tr>
<td>First Name:</td>
<td><form:input path="firstName"
maxlength="100"/></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName"
maxlength="100"/></td>
</tr>

24
<tr>
<td colspan="2" align="center"><input
type="submit"
value="Save"></td>
</tr>
</form:form>
</table>
</div>

</body>
</html>

25
CONFIGURER LE MODULE WEB

CONFIGURER LE WEB CONTEXT SPRING « SEVLET-CONTEXT.XML »

Dans ce fichier de configuration, on va configurer le module WEB :

- Activer le Spring MVC


- Indiquer l’emplacement des contrôleurs
- Décrire la technologie de la couche présentation (VIEW) qui est dans ce
tutoriels les JSP.

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/bea
ns http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd"
default-autowire="byName">
<!-- DispatcherServlet Context: defines this servlet's request-
processing infrastructure -->

<!-- Enables the Spring MVC @Controller programming model -->


<mvc:annotation-driven />

26
<!-- Handles HTTP GET requests for /resources/** by efficiently
serving up static resources in the ${webappRoot}/resources
directory -->
<mvc:resources mapping="/resources/**" location="/resources/"
/>

<!-- Resolves views selected for rendering by @Controllers


to .jsp resources in the /WEB-INF/views directory -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewRe
solver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>

<context:component-scan base-
package="com.training.spring.controller" />

</beans>

27
CONFIGURER LE « WEB.XML »

Dans le fichier « web.xml » on va :

- Indiquer l’emplacement des fichiers de configuration


- Configurer le composant qui va charger le module
- Configurer le MVC2 de Spring MVC

<?xml version="1.0" encoding="UTF-8"?>


<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- The definition of the Root Spring Container shared by


all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-
value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and


Filters -->
<listener>
<listener-
class>org.springframework.web.context.ContextLoaderListener</liste
ner-class>
</listener>

28
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-
class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-
context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

</web-app>

29
DEPLOIEMENT

Ajouter « Tomcat » dans STS

Déployer le projet dans le serveur d’application

STRUCTURE FINALE FU PORJET

30

Vous aimerez peut-être aussi