STACKJAVA

Code ví dụ Spring MVC JPA (Hibernate EntityManager) + MySQL + Maven

Code ví dụ Spring MVC JPA (Hibernate EntityManager) + MySQL + Maven

Ở bài này mình sẽ kết hợp Spring MVC với Hibernate để thực hiện ví dụ thêm, sửa, xóa dữ liệu với database.

(Bài này sử dụng JPA EntityManager nhé, các bạn có thể xem thêm ví dụ Spring MVC với Hibernate Session)

(Xem lại: So sánh Hibernate Session với JPA EntityManager)

Các công nghệ sử dụng:

 Tạo Database

Tạo database demo-spring-mvc-jpa với table customer

CREATE SCHEMA `demo-spring-mvc-jpa` ;
CREATE TABLE `demo-spring-mvc-jpa`.`customer` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `address` VARCHAR(255) NULL,
  PRIMARY KEY (`id`));

Tạo Maven Project

 

Thư viện sử dụng:

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>stackjava.com</groupId>
  <artifactId>SpringMvcJpa</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <properties>
    <spring.version>5.0.2.RELEASE</spring.version>
    <hibernate.version>5.2.12.Final</hibernate.version>
    <jstl.version>1.2</jstl.version>
  </properties>
  <dependencies>

    <!-- Spring Web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- Hibernate -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>${hibernate.version}</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>${hibernate.version}</version>
    </dependency>
    <!-- MySQL -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.45</version>
    </dependency>

    <!-- jsp-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency>

    <!-- jstl -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>${jstl.version}</version>
    </dependency>
  </dependencies>
</project>

File thông tin kết nối database:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/demo-spring-mvc-jdbc
jdbc.username=root
jdbc.password=admin1234

File cấu hình jpa:

hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true

File Spring config:

<?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:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

  <context:annotation-config />
  <context:component-scan base-package="stackjava.com.springmvcjpa" />
  <bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/jsp/" />
    <property name="suffix" value=".jsp" />
  </bean>

  <bean
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:jdbc.properties" />
  </bean>


  <!-- This produces a container-managed EntityManagerFactory; rather than 
    application-managed EntityManagerFactory as in case of LocalEntityManagerFactoryBean -->
  <bean id="entityManagerFactoryBean"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <!-- This makes /META-INF/persistence.xml is no longer necessary -->
    <property name="packagesToScan" value="stackjava.com.springmvcjpa.entities" />
    <!-- JpaVendorAdapter implementation for Hibernate EntityManager. Exposes 
      Hibernate's persistence provider and EntityManager extension interface -->
    <property name="jpaVendorAdapter">
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties" value="classpath:hibernate.properties" />
  </bean>

  <!-- Simple implementation of the standard JDBC DataSource interface, configuring 
    the plain old JDBC DriverManager via bean properties -->
  <bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
  </bean>

  <!-- This transaction manager is appropriate for applications that use a 
    single JPA EntityManagerFactory for transactional data access. JTA (usually 
    through JtaTransactionManager) is necessary for accessing multiple transactional 
    resources within the same transaction. -->
  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactoryBean" />
  </bean>

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

</beans>

File entity

package stackjava.com.springmvcjpa.entities;

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
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  @Column(name = "name")
  private String name;

  @Column(name = "address")
  private String address;

  // getter - setter

}

File DAO

package stackjava.com.springmvcjpa.dao;


import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import stackjava.com.springmvcjpa.entities.Customer;

@Repository(value = "customerDAO")
@Transactional(rollbackFor = Exception.class)
public class CustomerDAO {

    @PersistenceContext
    private EntityManager entityManager;


  public void persist(final Customer customer) {
    entityManager.persist(customer);
  }


  public Customer findById(final int id) {
    return entityManager.find(Customer.class, id);
  }

  public void delete(final Customer customer) {
    entityManager.remove(customer);
  }

  public List<Customer> findAll() {
    return entityManager.createQuery("FROM Customer", Customer.class).getResultList();
  }
}

File Service

package stackjava.com.springmvcjpa.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import stackjava.com.springmvcjpa.dao.CustomerDAO;
import stackjava.com.springmvcjpa.entities.Customer;

@Service
@Transactional
public class CustomerService {

  @Autowired
  private CustomerDAO customerDAO;

  public List<Customer> findAll() {
    return customerDAO.findAll();
  }

  public Customer findById(final int id) {
    return customerDAO.findById(id);
  }

  public void save(final Customer customer) {
    // check if customer exist -> throw exception
    customerDAO.persist(customer);
  }

  public void update(final Customer customer) {
    // if customerDB = null -> throw Exception
    Customer customerDB = customerDAO.findById(customer.getId());
    customerDB.setName(customer.getName());
    customerDB.setAddress(customer.getAddress());
    customerDAO.persist(customerDB);
  }

  public void delete(final int id) {
    Customer customer = customerDAO.findById(id);
    if (customer != null) {
      customerDAO.delete(customer);
    }
  }
}

File Controller

package stackjava.com.springmvcjpa.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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import stackjava.com.springmvcjpa.entities.Customer;
import stackjava.com.springmvcjpa.service.CustomerService;

@Controller
public class CustomerController {

  @Autowired
  private CustomerService customerService;

  @RequestMapping(value={"/", "/customer-list"})
  public String listCustomer(Model model) {
    model.addAttribute("listCustomer", customerService.findAll());
    return "customer-list";
  }

  @RequestMapping("/customer-save")
  public String insertCustomer(Model model) {
    model.addAttribute("customer", new Customer());
    return "customer-save";
  }

  @RequestMapping("/customer-view/{id}")
  public String viewCustomer(@PathVariable int id, Model model) {
    Customer customer = customerService.findById(id);
    model.addAttribute("customer", customer);
    return "customer-view";
  }
  
  @RequestMapping("/customer-update/{id}")
  public String updateCustomer(@PathVariable int id, Model model) {
    Customer customer = customerService.findById(id);
    model.addAttribute("customer", customer);
    return "customer-update";
  }

  @RequestMapping("/saveCustomer")
  public String doSaveCustomer(@ModelAttribute("Customer") Customer customer, Model model) {
    customerService.save(customer);
    model.addAttribute("listCustomer", customerService.findAll());
    return "customer-list";
  }

  @RequestMapping("/updateCustomer")
  public String doUpdateCustomer(@ModelAttribute("Customer") Customer customer, Model model) {
    customerService.update(customer);
    model.addAttribute("listCustomer", customerService.findAll());
    return "customer-list";
  }
  
  @RequestMapping("/customerDelete/{id}")
  public String doDeleteCustomer(@PathVariable int id, Model model) {
    customerService.delete(id);
    model.addAttribute("listCustomer", customerService.findAll());
    return "customer-list";
  }
}

Các file views:

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Helo Spring MVC + JPA</title>
<style>
table, th, td {
  border: 1px solid black;
}
td {
  padding-right: 30px;
}
</style>
</head>
<body>
  <c:url value="/customer-save" var="urlSave"/>
  <c:url value="/customer-view/" var="urlView"/>
  <c:url value="/customer-update/" var="urlUpdate"/>
  <c:url value="/customerDelete/" var="urlDelete"/>
  <h1>List Customer:</h1>
  <a href="${urlSave}">Add Customer</a>
  <br />
  <br />


  <table>
    <tr>
      <th>Id</th>
      <th>Name</th>
      <th>Address</th>
      <th>View</th>
      <th>Edit</th>
      <th>Delete</th>
    </tr>
    <c:if test="${not empty listCustomer}">
      <c:forEach var="customer" items="${listCustomer}">
        <tr style="border: 1px black solid">
          <td>${customer.id}</td>
          <td>${customer.name}</td>
          <td>${customer.address}</td>
          <td> <a href="${urlView}/${customer.id}">View</a></td>
          <td> <a href="${urlUpdate}/${customer.id}">Edit</a></td>
          <td> <a href="${urlDelete}/${customer.id}">Delete</a></td>
        </tr>
      </c:forEach>
    </c:if>
  </table>

</body>
</html>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<html>
<head>
<title>Helo Spring MVC + JPA</title>
</head>
<body>
  <a href="<c:url value="/customer-list" />" >List Customer</a><br />

  <h1>Add new Customer:</h1>
  <c:url value="/saveCustomer" var="saveCustomer"/>
  <form:form action="${saveCustomer}" method="POST"
    modelAttribute="customer">
    	Name: <form:input path="name" /> <br/> <br/>
    	Address: <form:input path="address" /> <br/> <br/>
    <button type="submit">Submit</button>
  </form:form>

</body>
</html>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<html>
<head>
<title>Helo Spring MVC + JPA</title>
</head>
<body>
  <a href="<c:url value="/customer-list" />">List Customer</a>
  <br />

  <h1>Edit Customer:</h1>
  <c:url value="/updateCustomer" var="updateCustomer" />
  <form:form action="${updateCustomer}" method="POST" modelAttribute="customer">
      Id: <form:input path="id" readonly="true" /> <br/> <br/>
    	Name: <form:input path="name" /> <br/> <br/>
    	Address: <form:input path="address" /> <br/> <br/>
    <button type="submit">Submit</button>
  </form:form>

</body>
</html>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Helo Spring MVC + JDBC</title>
</head>
<body>
  <a href="<c:url value="/customer-list" />" >List Customer</a><br />
  <h1>View Customer:</h1>	
  Customer ID: ${customer.id} <br/>
  Customer Name: ${customer.name} <br/>
  Customer Address: ${customer.address} <br/>
</body>
</html>

Demo:

Thêm mới customer

Update Customer

Xóa customer

Okay, Done!

Download code ví dụ trên tại đây

 

References:

https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html