Hướng dẫn xử lý database trong Spring MVC 5 với Spring Data JPA
Hướng dẫn xử lý database trong Spring MVC 5 với Spring Data JPA sẽ trình bày một cách khác để xử lý database trong Spring MVC. Đó là sử dụng Spring Data JPA thay vì sử dụng Hibernate.
Tuy nhiên, chúng tôi cũng có bài Hướng dẫn xử lý database trong Spring MVC 5 với Hibernate. Các bạn cũng nên xem để có sự so sanh giữa việc xử lý database với Hibernate và Spring Data JPA.
Hướng dẫn xử lý database trong Spring MVC 5 với Spring Data JPA – Các bước thực hiện
1/ Tạo một Maven Web Application Project
Mở eclipse -> chọn File -> chọn New -> chọn Other
Chọn Next
Chọn maven-archetype-webapp -> chọn Next
Nhập Group Id và Artifact Id -> chọn Finish
2/ Mở file pom.xml và thêm dependency
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>vn.giasutinhoc.spring5mvc.jpa</groupId>
<artifactId>SpringMVC_JPA</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>SpringMVC_JPA Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
<spring.version>5.1.0.RELEASE</spring.version>
<hibernate.version>5.2.17.Final</hibernate.version>
<hibernate.validator>5.4.1.Final</hibernate.validator>
<c3p0.version>0.9.5.2</c3p0.version>
<jstl.version>1.2.1</jstl.version>
<tld.version>1.1.2</tld.version>
<servlets.version>3.1.0</servlets.version>
<jsp.version>2.3.1</jsp.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring MVC Dependency -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring ORM -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Hibernate Validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate.validator}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!-- JSTL Dependency -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>${tld.version}</version>
</dependency>
<!-- Servlet Dependency -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlets.version}</version>
<scope>provided</scope>
</dependency>
<!-- JSP Dependency -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.20</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
<build>
<finalName>SpringMVC_JPA</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
3/ Tạo một Java class và đặt tên AppInitializer
Nhập code cho AppInitializer
4/ Tạo database.properties
Nhập code cho database.properties
5/ Tạo một Java class và đặt tên PersistenceJPAConfig
Nhập code cho PersistenceJPAConfig
package vn.giasutinhoc.spring5mvc.jpa.config;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:database.properties" })
@ComponentScan({ "vn.giasutinhoc.spring5mvc.jpa" })
@EnableJpaRepositories(basePackages = "vn.giasutinhoc.spring5mvc.jpa.repository")
public class PersistenceJPAConfig {
@Autowired
private Environment env;
public PersistenceJPAConfig() {
super();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan(new String[] { "vn.giasutinhoc.spring5mvc.jpa.model" });
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
entityManagerFactoryBean.setJpaProperties(additionalProperties());
return entityManagerFactoryBean;
}
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache",
env.getProperty("hibernate.cache.use_second_level_cache"));
hibernateProperties.setProperty("hibernate.cache.use_query_cache",
env.getProperty("hibernate.cache.use_query_cache"));
return hibernateProperties;
}
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.username"));
dataSource.setPassword(env.getProperty("jdbc.password"));
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
6/ Tạo một Java class và đặt tên WebMvcConfig
Nhập code cho WebMvcConfig
7/ Tạo một model và đặt tên Customer
Nhập code cho Customer.java
package vn.giasutinhoc.spring5mvc.jpa.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
public Customer() {
}
public int getId() {
return id;
}
public void setId(int 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;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
8/ Tạo một Repository tên CustomerRepository
Chuột phải src/main/java -> chọn New -> chọn Interface
Nhập code cho CustomerRepository.java
9/ Tạo một Custom Exception tên ResourceNotFoundException
Chuột phải src/main/java -> chọn New -> chọn Class
Nhập code cho ResourceNotFoundException.java
10/ Tạo một CustomerService
Nhập code cho CustomerService.java
11/ Tạo một controller tên CustomerController
Nhập code cho CustomerController
package vn.giasutinhoc.spring5mvc.jpa.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import vn.giasutinhoc.spring5mvc.jpa.exception.ResourceNotFoundException;
import vn.giasutinhoc.spring5mvc.jpa.model.Customer;
import vn.giasutinhoc.spring5mvc.jpa.service.CustomerService;
@Controller
@RequestMapping("/customer")
public class CustomerController {
private static final Logger LOG = LoggerFactory.getLogger(CustomerController.class);
@Autowired
private CustomerService customerService;
@GetMapping("/list")
public String listCustomers(Model theModel) {
List<Customer> theCustomers = customerService.getCustomers();
theModel.addAttribute("customers", theCustomers);
return "list-customers";
}
@GetMapping("/showForm")
public String showFormForAdd(Model theModel) {
LOG.debug("inside show customer-form handler method");
Customer theCustomer = new Customer();
theModel.addAttribute("customer", theCustomer);
return "customer-form";
}
@PostMapping("/saveCustomer")
public String saveCustomer(@ModelAttribute("customer") Customer theCustomer) {
customerService.saveCustomer(theCustomer);
return "redirect:/customer/list";
}
@GetMapping("/updateForm")
public String showFormForUpdate(@RequestParam("customerId") int theId,
Model theModel) throws ResourceNotFoundException {
Customer theCustomer = customerService.getCustomer(theId);
theModel.addAttribute("customer", theCustomer);
return "customer-form";
}
@GetMapping("/delete")
public String deleteCustomer(@RequestParam("customerId") int theId) throws ResourceNotFoundException {
customerService.deleteCustomer(theId);
return "redirect:/customer/list";
}
}
12/ Tạo một folder tên views bên trong thư mục WEB-INF
13/ Tạo một view tên customer-form.jsp bên trong thư mục views
Nhập code cho customer-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Thông tin khách hàng</title>
<link href="<c:url value="/resources/css/bootstrap.min.css" />"
rel="stylesheet">
<script src="<c:url value="/resources/js/jquery-1.11.1.min.js" />"></script>
<script src="<c:url value="/resources/js/bootstrap.min.js" />"></script>
</head>
<body>
<div class="container">
<div class="col-md-offset-2 col-md-7">
<h3 class="text-center">Spring MVC 5 + Spring Data JPA 2 + JSP + MySQL
Example - Quản lý khách hàng</h3>
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Thêm mới</div>
</div>
<div class="panel-body">
<form:form action="saveCustomer" cssClass="form-horizontal"
method="post" modelAttribute="customer">
<!-- need to associate this data with customer id -->
<form:hidden path="id" />
<div class="form-group">
<label for="firstname" class="col-md-3 control-label">Họ</label>
<div class="col-md-9">
<form:input path="firstName" cssClass="form-control" />
</div>
</div>
<div class="form-group">
<label for="lastname" class="col-md-3 control-label">Tên</label>
<div class="col-md-9">
<form:input path="lastName" cssClass="form-control" />
</div>
</div>
<div class="form-group">
<label for="email" class="col-md-3 control-label">Email</label>
<div class="col-md-9">
<form:input path="email" cssClass="form-control" />
</div>
</div>
<div class="form-group">
<!-- Button -->
<div class="col-md-offset-3 col-md-9">
<button type="submit" class="btn btn-primary">Lưu</button>
</div>
</div>
</form:form>
</div>
</div>
</div>
</div>
</body>
</html>
14/ Tạo thêm một view khác tên list-customers.jsp
Nhập code cho list-customers.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Danh sách khách hàng</title>
<link href="<c:url value="/resources/css/bootstrap.min.css" />"
rel="stylesheet">
<%@ page isELIgnored="false"%>
<script src="<c:url value="/resources/js/jquery-1.11.1.min.js" />"></script>
<script src="<c:url value="/resources/js/bootstrap.min.js" />"></script>
</head>
<body>
<div class="container">
<div class="col-md-offset-1 col-md-10">
<h3 class="text-center">Spring MVC 5 + Spring Data JPA 2 + JSP +
MySQL Example - Quản lý khách hàng</h3>
<hr />
<input type="button" value="Thêm mới"
onclick="window.location.href='showForm'; return false;"
class="btn btn-primary" /> <br />
<br />
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Danh sách khách hàng</div>
</div>
<div class="panel-body">
<table class="table table-striped table-bordered">
<tr>
<th>Họ</th>
<th>Tên</th>
<th>Email</th>
<th>Thao tác</th>
</tr>
<!-- loop over and print our customers -->
<c:forEach var="tempCustomer" items="${customers}">
<!-- construct an "update" link with customer id -->
<c:url var="updateLink" value="/customer/updateForm">
<c:param name="customerId" value="${tempCustomer.id}" />
</c:url>
<!-- construct an "delete" link with customer id -->
<c:url var="deleteLink" value="/customer/delete">
<c:param name="customerId" value="${tempCustomer.id}" />
</c:url>
<tr>
<td>${tempCustomer.firstName}</td>
<td>${tempCustomer.lastName}</td>
<td>${tempCustomer.email}</td>
<td>
<!-- display the update link --> <a href="${updateLink}">Cập nhật</a>
| <a href="${deleteLink}"
onclick="if (!(confirm('Bạn có muốn xóa thông tin khách hàng này không?'))) return false">Xóa</a>
</td>
</tr>
</c:forEach>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
15/ Chuẩn bị Bootstrap
Tạo mới 3 thư mục là resources, css và js như hình bên dưới
Tải và sao chép 3 tập tin bootstrap.min.css, bootstrap.min.js và jquery-1.11.1.min.js vào thư mục css và js
Hướng dẫn xử lý database trong Spring MVC 5 với Spring Data JPA – Build, Deploy và Run
1/ Về cách build, deploy và run các bạn tham khảo bài Hướng dẫn tạo project sử dụng Spring MVC 5 với eclipse
2/ Kết quả khi chạy http://localhost:8080/SpringMVC_JPA/customer/list
Chọn Thêm mới
Nhập đầy đủ thông tin và chọn Lưu
Thông tin khách hàng