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:
CustomerManager
Juga 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!