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
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"
-- Constraint: "PK_EMPLOYEE_ID"
2
-- Sequence: "EMPLOYEE_SEQ"
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 »
4
(3) Spécifier la structure des paquets du projet « com.training.spring » :
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>
8
CREATION DU MODELE
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 {
@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;
10
COUCHE REPOSITORY
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>{
11
DEVELOPPER LA COUCHE SERVICE
Source : EmployeeService.java
package com.training.spring.service;
import java.util.List;
import com.training.spring.domain.Employee;
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 »
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>
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>
16
DEVELOPPER LA COUCHE PRESENTATION
Dans ce tutorial on va utiliser la notion de ModelAttribute
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
<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>
<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
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
26
<!-- Handles HTTP GET requests for /resources/** by efficiently
serving up static resources in the ${webappRoot}/resources
directory -->
<mvc:resources mapping="/resources/**" location="/resources/"
/>
<context:component-scan base-
package="com.training.spring.controller" />
</beans>
27
CONFIGURER LE « WEB.XML »
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
30