Tóm tắt Trong thời đại phát triển nhanh chóng của công nghệ thông tin, hệ thống gợi ý cá nhân hóa đã đóng vai trò quan trọng trong thương mại điện tử, giáo dục trực tuyến và đọc kỹ thuật số. Phương pháp gợi ý sách truyền thống thường dựa trên hành vi lịch sử của người dùng hoặc các nhãn phân loại đơn giản, không đáp ứng được nhu cầu về gợi ý chính xác cao. Thuật toán lọc cộng tác (Collaborative Filtering) có khả năng phân tích sở thích của người dùng và hành vi của những người dùng tương tự, từ đó cải thiện đáng kể chất lượng gợi ý và giải quyết vấn đề "quá tải thông tin". Hệ thống gợi ý sách này tập trung vào việc thiết kế và thực hiện một hệ thống gợi ý dựa trên thuật toán lọc cộng tác, kết hợp kiến trúc tách biệt giữa frontend và backend, cung cấp dịch vụ gợi ý cá nhân hóa cho độc giả.
Hệ thống sử dụng Java SpringBoot làm khung backend, Vue3 làm khung frontend, MyBatis để thực hiện sự bền vững của dữ liệu và MySQL làm cơ sở dữ liệu lưu trữ. Frontend tận dụng đặc điểm phản hồi và phát triển theo mô hình thành phần của Vue3 để tạo giao diện tương tác thân thiện với người dùng; Backend sử dụng lợi thế nhẹ nhàng và mô-đun hóa của SpringBoot để xử lý logic kinh doanh hiệu quả; MyBatis giúp đơn giản hóa các thao tác cơ sở dữ liệu, tăng cường hiệu suất phát triển.
Thiết kế bảng dữ liệu
Bảng thông tin người dùng Bảng thông tin người dùng được sử dụng để lưu trữ thông tin đăng ký của người dùng hệ thống, bao gồm ID người dùng, tên đăng nhập, mật khẩu và các thẻ ưu tiên để phục vụ phân tích gợi ý sau này. ID người dùng là khóa chính của bảng này, được hệ thống tự động tạo ra.
| Tên trường | Kiểu dữ liệu | Mô tả |
|---|---|---|
| user_id | BIGINT | ID duy nhất của người dùng, khóa chính |
| username | VARCHAR(50) | Tên đăng nhập của người dùng |
| password_hash | VARCHAR(100) | Mật khẩu đã mã hóa |
| VARCHAR(100) | Email của người dùng | |
| preference_tags | TEXT | Các thẻ ưu tiên của người dùng (định dạng JSON) |
| create_time | DATETIME | Thời gian đăng ký tài khoản |
Bảng thông tin sách Bảng thông tin sách lưu trữ các chi tiết cơ bản và đặc điểm nội dung của từng cuốn sách, bao gồm ID sách, tiêu đề, tác giả, nhà xuất bản và các nhãn phân loại để phục vụ phân tích thuật toán gợi ý. ID sách là khóa chính của bảng này, cũng được hệ thống tự động tạo ra.
| Tên trường | Kiểu dữ liệu | Mô tả |
|---|---|---|
| book_id | BIGINT | ID duy nhất của cuốn sách, khóa chính |
| title | VARCHAR(100) | Tiêu đề sách |
| author | VARCHAR(50) | Tác giả của sách |
| publisher | VARCHAR(50) | Tên nhà xuất bản |
| publish_date | DATE | Ngày xuất bản |
| category_tags | TEXT | Các nhãn phân loại sách (định dạng JSON) |
| description | TEXT | Mô tả ngắn gọn về sách |
Bảng ghi nhận hành vi người dùng Bảng ghi nhận hành vi người dùng lưu trữ các dữ liệu liên quan đến việc duyệt, đánh giá, hoặc lưu trữ sách của người dùng, cung cấp cơ sở phân tích cho thuật toán lọc cộng tác. ID hành vi là khóa chính của bảng này, cũng được hệ thống tự động tạo ra.
| Tên trường | Kiểu dữ liệu | Mô tả |
|---|---|---|
| behavior_id | BIGINT | ID ghi nhận hành vi, khóa chính |
| user_id | BIGINT | ID người dùng liên quan |
| book_id | BIGINT | ID sách liên quan |
| behavior_type | VARCHAR(20) | Loại hành vi (dựng/xếp hạng/lưu trữ) |
| rating_value | FLOAT | Điểm xếp hạng của người dùng (từ 1-5) |
| behavior_time | DATETIME | Thời gian xảy ra hành vi |
Mã nguồn chính
package com.library;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(basePackages = {"com.mapper"})
public class LibraryApplication {
public static void main(String[] args) {
SpringApplication.run(LibraryApplication.class, args);
}
}
package com.library.controller;
import java.util.Date;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.library.service.UserService;
import com.library.utils.TokenUtil;
import com.library.entity.UserEntity;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private TokenUtil tokenUtil;
/**
* Đăng nhập người dùng
*/
@PostMapping("/login")
public Map<String, Object> login(@RequestParam String username, @RequestParam String password) {
UserEntity user = userService.findUserByUsername(username);
if (user == null || !user.getPassword().equals(password)) {
return Map.of("status", "error", "message", "Tài khoản hoặc mật khẩu không đúng");
}
String token = tokenUtil.generateToken(user.getUserId(), username);
return Map.of("status", "ok", "token", token);
}
/**
* Đăng ký người dùng mới
*/
@PostMapping("/register")
public Map<String, Object> register(@RequestBody UserEntity newUser) {
if (userService.findUserByUsername(newUser.getUsername()) != null) {
return Map.of("status", "error", "message", "Tên người dùng đã tồn tại");
}
newUser.setUserId(new Date().getTime());
userService.saveUser(newUser);
return Map.of("status", "ok", "message", "Đăng ký thành công");
}
/**
* Thoát khỏi phiên làm việc
*/
@PostMapping("/logout")
public Map<String, Object> logout() {
return Map.of("status", "ok", "message", "Thoát thành công");
}
}