Tech Blog

การสร้างแอพจัดการ DVD Rental ด้วย Spring Boot + Thymeleaf บน PostgreSQL dvdrental Sample DB

by Tech Writer
Spring Boot Thymeleaf PostgreSQL Java

เมื่อสร้างแอพจัดการ DVD rental สิ่งแรกที่ตัดสินใจไม่ใช่ UI — แต่เป็น “จะใช้ข้อมูลอะไรเป็นฐาน”

แทนที่จะออกแบบ table ตั้งแต่ต้น ฉันดำเนินการโดยใช้ dvdrental ซึ่งเป็น PostgreSQL sample database เป็นฐานและสร้างหน้าจัดการทับขึ้นไป

บทความนี้รวบรวมวิธีการแมพ dvdrental เป็นแอพจัดการโดยใช้ Java / Spring Boot / Thymeleaf / PostgreSQL

Sample DB ที่ใช้เป็นฐานสามารถดูได้ที่หน้านี้:

PostgreSQL Sample Database

สิ่งที่จะเรียนรู้จากบทความนี้

  • ทำไมถึงใช้ 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

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

ภาพ Dashboard

แบ่ง 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 ที่เหลือ, และยอดชำระสะสม

ภาพหน้าจอ Customer management

ภาพหน้า Customer registration

ภาพหน้า Customer registration confirmation

Staff Management

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

ภาพหน้าจอ Staff management

ภาพหน้า Staff registration

ภาพหน้า Staff registration confirmation

Store Management

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

ภาพหน้าจอ Store management

ภาพหน้า Store registration

ภาพหน้า Store registration confirmation

Inventory Management

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

ภาพหน้าจอ Inventory management

Payment Management

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

ภาพหน้าจอ Payment management

Rental Management

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

ภาพหน้าจอ Rental management

Sales Report

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

ภาพหน้าจอ Sales report

วิธีการแปลง 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 ได้สรุปไว้ในบทความต่อไปนี้:

การ Configure, Operations, และ Security สำหรับ Deploy Spring Boot + Thymeleaf Admin App ไปยัง AWS ECS/Fargate

ส่งข้อความได้ตามสบาย

กรุณาส่งข้อความ หากมีคำปรึกษาด้านเทคนิค ความคิดเห็น หรือคำถาม