Menulis aplikasi web sederhana menggunakan Spring MVC, Spring Data JPA dan Hibernate

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:

gambar

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 :

gambar

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:

gambar

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; } //       .       IDE,  . } 

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:

gambar

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:

gambar

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!

Source: https://habr.com/ru/post/id479286/


All Articles