在软件开发中,实体类(Entities)是对象关系映射(ORM)的核心组成部分。它们定义了应用程序的数据模型,并将这些数据映射到数据库表。在本篇文章中,我们将探讨实体类设计的基本原则,以及如何在项目开发初期确定所需的实体类。这里,我进行了entities的设计,在我们进行项目的开发时,应当去想想这个项目有哪些实体类。
一.Lombok插件的妙用
Lombok 是一个 Java 库,它通过注解耦合(annotation processing)技术自动生成常用的 Java 代码,如构造函数、getter 和 setter 方法、equals()
、hashCode()
和 toString()
方法等。Lombok 旨在减少样板代码的编写,让开发者能够专注于业务逻辑的实现。
主要特性
-
减少样板代码:自动生成常用的方法,减少手动编写的样板代码量。
-
提高开发效率:通过减少代码量,加快开发速度,提高开发效率。
-
易于维护:自动生成的方法在 Lombok 升级时可以自动更新,降低维护成本。
-
兼容性:Lombok 与大多数 IDE 和构建工具兼容,如 IntelliJ IDEA、Eclipse 和 Maven、Gradle 等。
-
通俗点讲,就是我们在编写实体类时,不用自己去写setter,getter等方法,方便维护。
具体利用
- 添加 Lombok 依赖: 将 Lombok 库添加到项目的依赖中。对于 Maven 项目,可以在
pom.xml
文件中添加 Lombok 的依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version> <!-- 请检查最新版本 -->
<scope>provided</scope> <!-- 或者 compile -->
</dependency>
- 编写实体类:
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class User {
private Long id;
private String name;
private String email;
private String password;
}
上面是一个简单的示例,我们只需要编写类的属性,而通过:
@Setter @Getter
就可以自动生成set&get方法!
二.数据库实体创建
在MYSQL中,依此执行下列语句来创建实体表。
-- 创建用户表
CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
password_hash VARCHAR(128) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建故事表
CREATE TABLE stories (
story_id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
difficulty_level ENUM('easy', 'medium', 'hard') NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建故事学习记录表
CREATE TABLE story_learning_records (
record_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
story_id INT NOT NULL,
learning_date DATE NOT NULL,
completion_status BOOLEAN NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(user_id),
FOREIGN KEY (story_id) REFERENCES stories(story_id)
);
-- 创建语音练习记录表
CREATE TABLE voice_practice_records (
record_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
practice_date DATE NOT NULL,
audio_file_path VARCHAR(255) NOT NULL,
score FLOAT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
-- 创建翻译练习记录表
CREATE TABLE translation_practice_records (
record_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
practice_date DATE NOT NULL,
original_text TEXT NOT NULL,
translated_text TEXT NOT NULL,
grammar_feedback TEXT,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
-- 创建学习进度表
CREATE TABLE learning_progress (
progress_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
total_stories_read INT DEFAULT 0,
avg_voice_score FLOAT DEFAULT 0.0,
avg_grammar_score FLOAT DEFAULT 0.0,
personalized_suggestions TEXT,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
创建成功后,可以运行:
SHOW TABLES;
来检查是否创建成功,创建成功后显示:
三.代码编写
-
User
package entity; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; import java.sql.Timestamp; @Setter @Getter @Entity @Table(name = "users") public class User { // Getters and Setters @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long userId; @Column(nullable = false, length = 50) private String username; @Column(nullable = false, length = 100) private String email; @Column(nullable = false, length = 128) private String passwordHash; @Column(name = "created_at") private Timestamp createdAt; }
-
Story
package entity; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; import java.sql.Timestamp; @Setter @Getter @Entity @Table(name = "stories") public class Story { // Getters and Setters @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long storyId; @Column(nullable = false) private String title; @Column(nullable = false) private String content; @Enumerated(EnumType.STRING) @Column(nullable = false) private DifficultyLevel difficultyLevel; @Column(name = "created_at") private Timestamp createdAt; // 枚举类型 public enum DifficultyLevel { EASY, MEDIUM, HARD } }
-
LearningProgress
package entity; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; import java.sql.Timestamp; @Setter @Getter @Entity @Table(name = "learning_progress") public class LearningProgress { // Getters and Setters @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long progressId; @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User user; @Column(name = "last_updated") private Timestamp lastUpdated; @Column(name = "total_stories_read", nullable = false) private int totalStoriesRead; @Column(name = "avg_voice_score", nullable = false) private float avgVoiceScore; @Column(name = "avg_grammar_score", nullable = false) private float avgGrammarScore; @Column(name = "personalized_suggestions") private String personalizedSuggestions; }
-
StoryLearningRecord
package entity; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; import java.sql.Date; @Setter @Getter @Entity @Table(name = "story_learning_records") public class StoryLearningRecord { // Getters and Setters @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long recordId; @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User user; @ManyToOne @JoinColumn(name = "story_id", nullable = false) private Story story; @Column(name = "learning_date", nullable = false) private Date learningDate; @Column(name = "completion_status", nullable = false) private boolean completionStatus; }
-
TranslationPracticeRecord
package entity; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; import java.sql.Date; @Setter @Getter @Entity @Table(name = "translation_practice_records") public class TranslationPracticeRecord { // Getters and Setters @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long recordId; @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User user; @Column(name = "practice_date", nullable = false) private Date practiceDate; @Column(name = "original_text", nullable = false) private String originalText; @Column(name = "translated_text", nullable = false) private String translatedText; @Column(name = "grammar_feedback") private String grammarFeedback; }
-
VoicePracticeRecord
package entity; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; import java.util.Date; @Setter @Getter @Entity @Table(name = "voice_practice_records") public class VoicePracticeRecord { // Getters and Setters @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long recordId; @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User user; @Column(name = "practice_date", nullable = false) private Date practiceDate; @Column(name = "audio_file_path", nullable = false, length = 255) private String audioFilePath; @Column(name = "score", nullable = false) private float score; }
四.总结
实体类设计是项目架构的基础,它直接影响到数据库设计、业务逻辑实现和应用程序的可维护性。通过遵循最佳实践和原则,我们可以创建一个健壮、灵活且易于扩展的数据模型。在项目初期,花时间仔细考虑和设计实体类,将为项目的长期成功奠定基础。