การสร้างแอพจัดการ DVD Rental ด้วย Spring Boot + Thymeleaf บน PostgreSQL dvdrental Sample DB
เมื่อสร้างแอพจัดการ DVD rental สิ่งแรกที่ตัดสินใจไม่ใช่ UI — แต่เป็น “จะใช้ข้อมูลอะไรเป็นฐาน”
แทนที่จะออกแบบ table ตั้งแต่ต้น ฉันดำเนินการโดยใช้ dvdrental ซึ่งเป็น PostgreSQL sample database เป็นฐานและสร้างหน้าจัดการทับขึ้นไป
บทความนี้รวบรวมวิธีการแมพ dvdrental เป็นแอพจัดการโดยใช้ Java / Spring Boot / Thymeleaf / PostgreSQL
Sample DB ที่ใช้เป็นฐานสามารถดูได้ที่หน้านี้:
สิ่งที่จะเรียนรู้จากบทความนี้
- ทำไมถึงใช้ PostgreSQL sample DB
dvdrentalเป็นฐานสำหรับ business app - ขั้นตอนการสร้าง admin app ด้วย Spring Boot + Thymeleaf
- วิธีการแมพ customers, stores, staff, inventory, rentals, และ payments เป็นหน้าจอโดยอิงจาก ER diagram
- วิธีการใช้ JPA และ SQL ต่างกัน
- เทคนิคทำให้ใช้งานได้เป็น business app เช่น การเก็บ search condition และหน้ายืนยัน
ฟีเจอร์หลักที่สร้างครั้งนี้ได้แก่:
- Login
- Dashboard
- Customer management
- Store management
- Staff management
- Inventory management
- Payment management
- Rental management
- Sales report
ทำไมถึงใช้ PostgreSQL dvdrental Sample DB เป็นฐาน
สิ่งแรกสุดที่กำหนดในแอพนี้คือการใช้ PostgreSQL sample DB เป็นฐาน
dvdrental มา pre-loaded พร้อม tables ที่จำเป็นสำหรับ DVD rental operations: stores, staff, customers, films, inventory, rentals, และ payments
สิ่งนี้ค่อนข้างสำคัญ — สามารถเริ่มพัฒนาพร้อม subject matter ต่อไปนี้ทันที:
- Search screens เช่น customer lists และ staff lists
- Reference screens เช่น customer details และ payment details
- Aggregations จาก rentals และ payments
- CRUD screens สำหรับ stores, inventory, และ customers
รู้สึกว่าง่ายกว่าที่จะเข้าใจ existing schema และข้อมูลก่อน จากนั้นสร้างหน้าจอทับ แทนที่จะออกแบบ business tables ตั้งแต่ต้น
ก่อนอื่น ทำให้ Sample DB ใช้งานได้
ใน repository นี้ docker/postgres/init/01-dvdrental-full.sql ถูก load เมื่อเริ่ม local PostgreSQL
นอกจากนี้ docker/postgres/init/02-convert-currency-to-jpy.sql ก็ถูก apply เพื่อให้ verify หน้าจอได้ด้วยจำนวนเงินที่แปลงเป็น JPY
จัดระเบียบ dvdrental ER Diagram และความสัมพันธ์ Table หลัก
ก่อนเริ่มสร้างหน้าจอ ฉันจัดระเบียบคร่าวๆ ความสัมพันธ์ระหว่าง tables ที่เป็นศูนย์กลางของ admin screen นี้
dvdrental มีหลาย tables แต่การพยายาม trace ทั้งหมดในรายละเอียดตั้งแต่ต้นมักทำให้ความคิดกระจาย จึงโฟกัสที่ tables หลักที่เชื่อมโยงโดยตรงกับหน้าจอก่อน: customers, staff, stores, films, inventory, rentals, และ payments
ความสัมพันธ์หลักที่เป็นศูนย์กลางของ admin screen นี้เมื่อทำให้เรียบง่าย:
erDiagram
STORE ||--o{ STAFF : has
STORE ||--o{ CUSTOMER : has
STORE ||--o{ INVENTORY : stocks
STAFF ||--o{ RENTAL : handles
STAFF ||--o{ PAYMENT : handles
CUSTOMER ||--o{ RENTAL : rents
CUSTOMER ||--o{ PAYMENT : pays
FILM ||--o{ INVENTORY : stocked_as
INVENTORY ||--o{ RENTAL : rented_as
RENTAL ||--o{ PAYMENT : billed_by
แอพจัดการแบบไหนที่สร้างด้วย Spring Boot + Thymeleaf
แอพหลักเป็น admin screen แบบ server-rendered โดยใช้ Spring Boot + Thymeleaf
Tech stack หลักได้แก่:
- Java 21
- Spring Boot 4
- Thymeleaf
- Spring Security
- Spring Data JPA
- NamedParameterJdbcTemplate
- PostgreSQL
- Flyway
- Docker
แทนที่จะเอียงไปทาง SPA ฉันสร้างโดยซ้อน search, details, registration, updates, และ confirmation ตามลำดับ วิธีนี้สร้าง business screens ได้ง่ายกว่า และการจัดการ state ก็คิดง่ายกว่า
ก่อนอื่นมีหน้า login เป็น entry point ไปยังแต่ละ function

หลัง login dashboard ทำหน้าที่เป็น entry point สำหรับดูสถานะ rental และ sales

แบ่ง Spring Boot + Thymeleaf Admin Screen ตาม Business Unit
โดยดูจาก dvdrental schema ฉันแบ่งบทบาทหน้าจอตาม business unit ก่อน
หน้าจอหลักที่เตรียมครั้งนี้ได้แก่:
- Login
- Dashboard
- Customer management
- Store management
- Staff management
- Inventory management
- Payment management
- Rental management
- Sales report
Dashboard
Dashboard ทำหน้าที่เป็น entry point ของ admin screen ทั้งหมด ให้ภาพรวมว่าแต่ละ function จัดการอะไร แทนที่จะเป็นแค่รายการ links มันให้ความเข้าใจเริ่มต้นว่า staff, inventory, rentals, customers, payments, stores, และ reports แต่ละอย่างเป็นหน้าจอเกี่ยวกับอะไร
Customer Management
Customer management ช่วยให้ดูไม่เพียงแค่ข้อมูลพื้นฐานของ customer แต่ยังรวม store ที่สังกัด, active status, จำนวน rental ที่เหลือ, และยอดชำระสะสม



Staff Management
Staff management ช่วยให้ยืนยัน store ที่สังกัด, active status, จำนวน assignment, และยอดที่เก็บได้



Store Management
Store management ช่วยให้ดู managers, locations, inventory counts, customer counts, และ sales รวมกัน



Inventory Management
Inventory management ช่วยให้ cross-check films, categories, descriptions, languages, และ store inventory

Payment Management
Payment management ช่วยให้ track ไม่เพียงแค่ payment history ตาม customer และ store แต่ยังรวม average unit price และยอดรวม

Rental Management
Rental management ช่วยให้สลับระหว่าง in-rental, returned, และ overdue states ขณะตรวจสอบ rental history ตาม customer และ film

Sales Report
Sales report ช่วยให้ยืนยัน sales ตาม category และ KPIs ตาม store

วิธีการแปลง Sample DB เป็นรูปแบบแอพ
เนื่องจากใช้ existing tables โดยตรงในแอพ ฉันจึง map table structure เป็น Java entities อย่างตรงไปตรงมาก่อน
JPA และ SQL ถูกพิจารณาแยกกัน
เมื่อ implementation ดำเนินไป ชัดเจนว่า registration/update processing และ list/aggregation processing มีรูปแบบการเขียนที่เหมาะสมต่างกัน
ดังนั้นแอพนี้ใช้แบ่งคร่าวๆ ดังนี้:
- Registration, updates, และ reference foundation: JPA
- Dashboards และ aggregations: เขียน SQL โดยตรง
Search Condition Retention ฝั่ง Server
Search condition retention สำหรับ customer management ถูก implement โดยใช้ @SessionAttributes ของ Spring MVC
@Controller
@SessionAttributes("customerSearchForm")
public class CustomerController {
@GetMapping("/functions/customers")
public String customers(Model model, @ModelAttribute("customerSearchForm") CustomerSearchForm form) {
return renderCustomers(form, model);
}
@ModelAttribute("customerSearchForm")
public CustomerSearchForm customerSearchForm() {
return new CustomerSearchForm();
}
@PostMapping("/functions/customers")
public String customers(@ModelAttribute("customerSearchForm") CustomerSearchForm form, Model model) {
return renderCustomers(form, model);
}
}
Dashboard Aggregation ด้วย SQL
Map<String, Object> summary = jdbcTemplate.queryForMap(
"""
select
count(*) filter (where return_date is null) as open_rentals,
count(*) filter (
where return_date is null
and rental_date < current_timestamp - (interval '1 day' * 3)
) as overdue_rentals,
(select count(*) from inventory) as inventory_count,
(select count(*) from customer where activebool) as active_customers,
(select coalesce(sum(amount), 0) from payment where payment_date >= current_date - interval '30 day') as monthly_sales
from rental
""",
new MapSqlParameterSource());
สิ่งที่ดีเกี่ยวกับการสร้างบน Sample DB
ในทางปฏิบัติ สิ่งที่ดีคือเนื่องจากความสัมพันธ์ของข้อมูลมีอยู่แล้วตั้งแต่ต้น จึงไม่ขาดแคลน subject matter เมื่อเพิ่มหน้าจอ
สรุป
สำหรับการสร้างแอพจัดการ DVD rental สิ่งแรกสุดที่กำหนดคือการใช้ PostgreSQL sample DB เป็นฐาน
การใช้ dvdrental หมายความว่า customers, stores, staff, inventory, rentals, และ payments พร้อมตั้งแต่ต้น ทำให้ง่ายต่อการขยายเป็น screen design, authentication, lists, details, updates, และ aggregations
การ configure และ thinking เมื่อวางบน AWS ได้สรุปไว้ในบทความต่อไปนี้: