Halo, Habr! Saya mempersembahkan untuk Anda terjemahan dari panduan 
“Spring MVC + Spring Data JPA + Hibernate - CRUD Example” oleh Nam Ha Minh.
Dalam tutorial Spring Java ini, Anda akan belajar cara mengatur aplikasi Spring MVC untuk bekerja dengan Spring Data JPA dengan mengembangkan aplikasi web sederhana yang memungkinkan Anda mengelola informasi pelanggan.
Setelah menyelesaikan tutorial ini, Anda dapat membuat aplikasi web Java berdasarkan teknologi Spring MVC dan Spring Data JPA, yang terlihat seperti ini:
Program dan teknologi yang digunakan dalam panduan ini: Java 8, Apache Tomcat 9, MySQL Server 5.7, Eclipse IDE 4.7 (Oxygen), Spring Framework 5.1, Hibernate 5.4, Spring Data JPA 2.1.5, dan Servlet 3.1.
Mari kita mulai dengan membuat database.
1. Membuat database
Kami akan menggunakan MySQL. Dalam contoh kami, kami akan bekerja dengan data di tabel 
pelanggan , yang terletak di skema 
penjualan bernama. Tabel 
pelanggan memiliki 4 bidang: 
id , 
nama , 
email , dan 
alamat :
Anda dapat menjalankan skrip MySQL berikut untuk membuat skema dan tabel:
CREATE DATABASE `sales`; CREATE TABLE `customer` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) NOT NULL, `email` varchar(45) NOT NULL, `address` varchar(45) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
2. Membuat proyek di Eclipse
Buat Proyek Web Dinamis di Eclipse, dan ubah menjadi proyek Maven: untuk melakukan ini, klik kanan pada proyek tersebut, pilih 
Configure> Convert to Maven Project . Di kotak dialog 
Buat POM baru yang terbuka, masukkan informasi berikut:
- Id Grup: 
net.codejava- Id Artefak: 
CustomerManagerJuga memastikan bahwa versi JRE untuk proyek Java adalah 8 atau lebih baru.
Kemudian, buka 
pom.xml (file Maven) untuk mengonfigurasi dependensi untuk proyek ini. Deklarasikan properti versi untuk Spring dan Hibernate Frameworks:
 <properties> <spring.version>5.1.5.RELEASE</spring.version> <hibernate.version>5.4.1.Final</hibernate.version> </properties> 
Tentukan ketergantungan untuk Kerangka Kerja Pegas:
 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> 
Untuk membuat aplikasi web Spring MVC:
 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> 
Untuk menggunakan Spring Data JPA:
 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>2.1.5.RELEASE</version> </dependency> 
Kami menggunakan Hibernate sebagai implementasi JPA, jadi tambahkan dependensi berikut:
 <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> 
Agar aplikasi dapat bekerja dengan MySQL, kita membutuhkan dependensi untuk driver MySQL JDBC:
 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.14</version> <scope>runtime</scope> </dependency> 
Dan sekarang dependensi untuk Java Servlet, JSP dan JSTL:
 <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> 
Buat dua paket Java di root proyek:
- 
net.codejava.config : untuk kelas konfigurasi.
- 
net.codejava.customer : untuk kelas aplikasi.
3. Membuat file konfigurasi JPA
Karena kita menggunakan JPA, kita perlu mendefinisikan properti untuk menghubungkan ke database dalam file 
persistence.xml , dan bukan di 
hibernate.cfg.xml . Buat direktori baru bernama 
META-INF di folder sumber proyek untuk menempatkan file 
persistence.xml di dalamnya:
Dan masukkan kode di bawah ini dalam file ini:
 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="SalesDB"> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/sales" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="(password)" /> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> </properties> </persistence-unit> </persistence> 
Seperti yang Anda lihat, kami menentukan properti untuk menghubungkan ke database, seperti URL, pengguna, kata sandi, dan kelas driver JDBC. Perhatikan juga bahwa nama 
SalesDB akan digunakan oleh kami dalam kode konfigurasi.
4. Membuat Kelas Model
Buat kelas 
Customer yang memetakan ke tabel 
pelanggan dalam database sebagai berikut:
 package net.codejava.customer; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; private String address; protected Customer() { } protected Customer(String name, String email, String address) { this.name = name; this.email = email; this.address = address; }  
Seperti yang Anda lihat, kami menggunakan anotasi @Entity untuk memetakan kelas ini ke tabel 
pelanggan (nama kelas sama dengan nama tabel). Semua nama bidang kelas identik dengan nama bidang dalam tabel. Bidang 
id memiliki anotasi 
@Id dan 
@GeneratedValue untuk menunjukkan bahwa bidang ini adalah kunci utama dan nilainya dihasilkan secara otomatis.
5. Konfigurasi Spring MVC dan Spring Data JPA
Selanjutnya, kita menulis kode Java untuk mengkonfigurasi Spring MVC dan Spring Data JPA. Kami akan menggunakan konfigurasi berbasis Java, karena lebih sederhana dari XML.
Konfigurasikan Spring Dispatcher Servlet
Untuk menggunakan Spring MVC dalam aplikasi kita, kita perlu mendaftarkan Spring Dispatcher Servlet ketika memulai aplikasi dengan menulis kelas berikut:
 package net.codejava.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class WebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); appContext.register(WebMvcConfig.class); ServletRegistration.Dynamic dispatcher = servletContext.addServlet( "SpringDispatcher", new DispatcherServlet(appContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } } 
Metode 
onStartup() dari kelas ini akan secara otomatis dipanggil oleh servlet ketika aplikasi dimuat. Spring Dispatcher Servlet memproses semua permintaan dengan mencocokkan URL "/" dan mencari konfigurasi di kelas 
WebMvcConfig , yang dijelaskan di bawah ini.
Konfigurasikan Spring MVC
Buat kelas 
WebMvcConfig di paket 
net.codejava.config yang berisi kode berikut:
 package net.codejava.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @ComponentScan("net.codejava ") public class WebMvcConfig { @Bean(name = "viewResolver") public InternalResourceViewResolver getViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } } 
Kelas ini ditandai dengan anotasi 
@Configuration memberitahu Spring bahwa itu adalah file konfigurasi. 
@ComponentScan memberi tahu Spring untuk mencari kelas konfigurasi dalam paket 
net.codejava .
Di kelas ini, kami membuat kacang yang mengenali tampilan dengan menetapkan awalan dan akhiran untuk tampilan ini. Oleh karena itu, buat direktori 
views di dalam direktori 
WebContent/WEB-INF untuk menyimpan file JSP.
Di sini Anda dapat menambahkan konfigurasi Spring MVC lainnya.
Mengkonfigurasi Spring Data JPA
Untuk bekerja dengan Spring Data JPA, kita perlu membuat dua komponen kacang: 
EntityManagerFactory dan 
JpaTransactionManager . Oleh karena itu, kita akan membuat kelas konfigurasi lain 
JpaConfig :
 package net.codejava.config; import javax.persistence.EntityManagerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableJpaRepositories(basePackages = {"net.codejava.customer"}) @EnableTransactionManagement public class JpaConfig { @Bean public LocalEntityManagerFactoryBean entityManagerFactory() { LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean(); factoryBean.setPersistenceUnitName("SalesDB"); return factoryBean; } @Bean public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory); return transactionManager; } } 
Di sini kami menggunakan dua anotasi penting:
- @EnableJpaRepositories: memberi tahu Spring Data JPA untuk mencari kelas repositori dalam paket yang ditentukan (net.codejava) untuk menyuntikkan kode yang sesuai saat dijalankan.
- @EnableTransactionManagement: memberi tahu Spring Data JPA untuk menghasilkan kode untuk mengelola transaksi saat runtime.
Di kelas ini, metode pertama membuat turunan dari 
EntityManagerFactory untuk mengontrol Unit Persistensi dari 
SalesDB kami (nama ini ditentukan dalam 
persistence.xml di atas).
Metode terakhir membuat turunan dari 
JpaTransactionManager untuk 
EntityManagerFactory , yang dibuat oleh metode sebelumnya.
Ini adalah konfigurasi minimum yang diperlukan untuk menggunakan Spring Data JPA.
Membuat Antarmuka Repositori
Buat antarmuka 
CustomerRepository yang memperluas antarmuka 
CrudRepository didefinisikan dalam Spring Data JPA:
 package net.codejava.customer; import java.util.List; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; public interface CustomerRepository extends CrudRepository<Customer, Long> {    } 
Ini hampir semua kode yang kita butuhkan untuk mengakses data. Setuju saja? Dengan Spring Data JPA, kita tidak perlu menulis kode DAO (Java Data Acces Object). Cukup deklarasikan antarmuka yang memperluas antarmuka 
CrudRepository , yang mendefinisikan metode CRUD seperti 
save() , 
findAll() , 
findById() , 
deleteById() , dll. Pada waktu berjalan, Spring Data JPA akan secara otomatis menghasilkan kode.
Harap dicatat bahwa kami harus menentukan jenis kelas model dan jenis bidang kunci utama saat memperluas 
CrudRepository : 
CrudRepository<Customer, Long> .
7. Membuat Kelas Layanan
Selanjutnya, buat kelas Layanan 
CustomerService :
 package net.codejava.customer; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional public class CustomerService { @Autowired CustomerRepository repo; public void save(Customer customer) { repo.save(customer); } public List<Customer> listAll() { return (List<Customer>) repo.findAll(); } public Customer get(Long id) { return repo.findById(id).get(); } public void delete(Long id) { repo.deleteById(id); } } 
Perhatikan anotasi 
@Transactional yang 
@Transactional kelas kita. Ini berarti bahwa semua metode kelas ini akan dicegat oleh Spring Data JPA untuk manajemen transaksi. Dan instance antarmuka 
CustomerRepository akan tertanam di kelas ini:
 @Autowired CustomerRepository repo; 
Ini sepertinya ajaib karena kita tidak menulis kode DAO, tetapi Spring Data JPA akan secara otomatis membuat implementasi saat runtime.
Seperti yang Anda lihat, semua metode di kelas ini adalah untuk operasi CRUD. Itu hanya mendelegasikan seluruh panggilan ke objek 
CustomerRepository . Kelas ini mungkin tampak berlebihan bagi Anda, tetapi perlu untuk memisahkan tingkat bisnis / layanan dari tingkat repositori / DAO.
8. Membuat Spring MVC Controller
Buat 
CustomerContoroller kelas untuk menangani semua permintaan dari pelanggan:
 package net.codejava.customer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class CustomerController { @Autowired private CustomerService customerService;  
Ini adalah kelas Kontroler MVC Musim Semi yang dianotasi menggunakan 
@Controller . Anda dapat melihat bahwa instance 
CustomerService sedang disuntikkan ke objek ini menggunakan anotasi 
@Autowired .
Kami akan menulis metode pemrosesan di bagian berikut.
9. Menambahkan daftar pelanggan
Semua pelanggan akan ditampilkan di beranda aplikasi kami. Untuk melakukan ini, tambahkan metode pemrosesan yang sesuai ke kelas 
CustomerController kami:
 @RequestMapping("/") public ModelAndView home() { List<Customer> listCustomer = customerService.listAll(); ModelAndView mav = new ModelAndView("index"); mav.addObject("listCustomer", listCustomer); return mav; } 
Halaman beranda perambanan ( 
index.jsp ) akan terlihat seperti ini:
 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Customer Manager</title> </head> <body> <div align="center"> <h2>Customer Manager</h2> <form method="get" action="search"> <input type="text" name="keyword" />  <input type="submit" value="Search" /> </form> <h3><a href="/new">New Customer</a></h3> <table border="1" cellpadding="5"> <tr> <th>ID</th> <th>Name</th> <th>E-mail</th> <th>Address</th> <th>Action</th> </tr> <c:forEach items="${listCustomer}" var="customer"> <tr> <td>${customer.id}</td> <td>${customer.name}</td> <td>${customer.email}</td> <td>${customer.address}</td> <td> <a href="/edit?id=${customer.id}">Edit</a>   <a href="/delete?id=${customer.id}">Delete</a> </td> </tr> </c:forEach> </table> </div> </body> </html> 
Sekarang Anda dapat memulai aplikasi web. Tambahkan beberapa baris ke tabel 
pelanggan dan buka 
http://localhost:8080/CustomerManager/ dan Anda akan melihat sesuatu yang serupa:
10. Menambahkan pengguna baru
Untuk mengimplementasikan fungsi menciptakan klien baru, kita perlu menulis dua metode penangan. Dan yang pertama akan menampilkan formulir baru untuk menambahkan klien:
 @RequestMapping("/new") public String newCustomerForm(Map<String, Object> model) { Customer customer = new Customer(); model.put("customer", customer); return "new_customer"; } 
Mari kita menulis formulir JSP itu sendiri dengan nama 
new_customer.jsp :
 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"    pageEncoding="ISO-8859-1"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>     <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"    "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>New Customer</title> </head> <body>    <div align="center">        <h2>New Customer</h2>        <form:form action="save" method="post" modelAttribute="customer">            <table border="0" cellpadding="5">                <tr>                    <td>Name: </td>                    <td><form:input path="name" /></td>                </tr>                <tr>                    <td>Email: </td>                    <td><form:input path="email" /></td>                </tr>                <tr>                    <td>Address: </td>                    <td><form:input path="address" /></td>                </tr>                   <tr>                    <td colspan="2"><input type="submit" value="Save"></td>                </tr>                               </table>        </form:form>    </div> </body> </html> 
Sekarang di halaman utama Anda akan melihat tautan 
Pelanggan Baru , ketika Anda mengkliknya Anda akan melihat formulir baru:
Metode penangan kedua akan memproses tombol 
Simpan dalam formulir ini:
 @RequestMapping(value = "/save", method = RequestMethod.POST) public String saveCustomer(@ModelAttribute("customer") Customer customer) { customerService.save(customer); return "redirect:/"; } 
Seperti yang Anda lihat, itu mengarahkan klien ke beranda, setelah berhasil menyimpan pengguna.
11. Ubah data pengguna
Untuk menerapkan fungsi pengeditan klien, tambahkan metode penangan berikut ke kelas 
CustomerController :
 @RequestMapping("/edit") public ModelAndView editCustomerForm(@RequestParam long id) {    ModelAndView mav = new ModelAndView("edit_customer");    Customer customer = customerService.get(id);    mav.addObject("customer", customer);    return mav; } 
Mari kita menulis formulir 
edit_customer.jsp , yang dipanggil dengan metode ini:
 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Edit Customer</title> </head> <body> <div align="center"> <h2>Edit Customer</h2> <form:form action="save" method="post" modelAttribute="customer"> <table border="0" cellpadding="5"> <tr> <td>ID: </td> <td>${customer.id} <form:hidden path="id"/> </td> </tr> <tr> <td>Name: </td> <td><form:input path="name" /></td> </tr> <tr> <td>Email: </td> <td><form:input path="email" /></td> </tr> <tr> <td>Address: </td> <td><form:input path="address" /></td> </tr> <tr> <td colspan="2"><input type="submit" value="Save"></td> </tr> </table> </form:form> </div> </body> </html> 
Klik pada hyperlink 
Edit di sebelah klien pada halaman beranda, formulir pengeditan klien akan dipanggil, yang akan terlihat seperti ini:
Metode handler masih memproses tombol 
Simpan .
12. Menghapus klien
Untuk mengimplementasikan fungsi hapus, tulis metode penangan berikut di kelas 
CustomerController :
 @RequestMapping("/delete") public String deleteCustomerForm(@RequestParam long id) { customerService.delete(id); return "redirect:/"; } 
Klik tautan 
Hapus di sebelah klien di halaman utama. Klien akan dihapus, dan daftar akan diperbarui.
13. Cari berdasarkan pelanggan
Akhirnya, mari kita terapkan fungsi pencarian yang memungkinkan pengguna untuk mencari pelanggan dengan memasukkan kata kunci. Fungsi pencarian mencari kata kunci dalam tiga bidang: nama, email dan alamat, yang mana kita perlu menulis metode kita sendiri di antarmuka 
CustomerRepository :
 package net.codejava.customer; import java.util.List; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; public interface CustomerRepository extends CrudRepository<Customer, Long> { @Query(value = "SELECT c FROM Customer c WHERE c.name LIKE '%' || :keyword || '%'" + " OR c.email LIKE '%' || :keyword || '%'" + " OR c.address LIKE '%' || :keyword || '%'") public List<Customer> search(@Param("keyword") String keyword); } 
Metode 
search() hanyalah metode abstrak yang dianotasi dengan 
@Query . Permintaan pencarian adalah permintaan JPA.
Kemudian tambahkan metode ke kelas 
CustomerService :
 public List<Customer> search(String keyword) { return repo.search(keyword); } 
Sekarang tambahkan metode handler ke kelas 
CustomerController :
 @RequestMapping("/search") public ModelAndView search(@RequestParam String keyword) { List<Customer> result = customerService.search(keyword); ModelAndView mav = new ModelAndView("search"); mav.addObject("result", result); return mav; } 
Dan buat 
search.jsp hasil pencarian 
search.jsp :
 <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Search Result</title> </head> <body> <div align="center"> <h2>Search Result</h2> <table border="1" cellpadding="5"> <tr> <th>ID</th> <th>Name</th> <th>E-mail</th> <th>Address</th> </tr> <c:forEach items="${result}" var="customer"> <tr> <td>${customer.id}</td> <td>${customer.name}</td> <td>${customer.email}</td> <td>${customer.address}</td> </tr> </c:forEach> </table> </div> </body> </html> 
Untuk menguji fungsi pencarian, masukkan kata kunci di bidang pencarian di halaman rumah, dan tekan Enter. Anda akan melihat halaman hasil pencarian:
Kesimpulan
Dalam panduan ini, Anda belajar bagaimana mengembangkan aplikasi web Spring MVC menggunakan Spring Data JPA untuk mengakses data. Seperti yang Anda lihat, Spring Data JPA sangat mengurangi dan menyederhanakan kode yang perlu kita tulis.
Sebagai perbandingan, berikut adalah struktur proyek di Eclipse IDE:
Terima kasih sudah membaca!