Halo 开源项目学习(二):实体类与数据表
基本介绍
Halo 项目中定义了一些实体类,用于存储博客中的关键数据,如用户信息、文章信息等。在深入学习 Halo 的设计理念与实现过程之前,不妨先学习一下一个完整的博客系统都由哪些元素组成。
实体类
Halo 中的除 BaseEntity 外的每一个实体类都对应着一个数据表,以 User 类为例,每一个 User 对象都对应 users 表中的一条记录,每一个对象属性的值也等于数据表中对应字段的值。
User 类定义如下:
@Data // Lombok 注解, 自动生成 get()、set()、toString() 等方法
@Entity // JPA 注解, 声明该类为一个实体类, 必须与 @Id 搭配使用
@Table(name = "users") // JAP 注解, 声明该类映射到数据库的 users 数据表
@ToString(callSuper = true) // Lombok 注解, callSuper = true 表示调用 toString() 方法时输出父类的属性
@EqualsAndHashCode(callSuper = true) // 自动生成 equals() 和 hashCode() 方法, 默认 callSuper 为 false, 为 true 表示 equals() 方法比较时会调用父类的 equals() 方法
public class User extends BaseEntity {
@Id // JPA 注解, 声明主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // JPA 注解, 声明主键的生成策略, IDENTITY 表示使用自增 id
@Column(name = "id") // JPA 注解, 声明实体类的属性 id 映射到数据表中的字段 id
private Integer id;
/**
* User name.
*/
@Column(name = "username", columnDefinition = "varchar(50) not null")
private String username;
/**
* User nick name,used to display on page.
*/
@Column(name = "nickname", columnDefinition = "varchar(255) not null")
private String nickname;
/**
* Password.
*/
@Column(name = "password", columnDefinition = "varchar(255) not null")
private String password;
/**
* User email.
*/
@Column(name = "email", columnDefinition = "varchar(127) default ''")
private String email;
/**
* User avatar.
*/
@Column(name = "avatar", columnDefinition = "varchar(1023) default ''")
private String avatar;
/**
* User description.
*/
@Column(name = "description", columnDefinition = "varchar(1023) default ''")
private String description;
/**
* Expire time.
*/
@Column(name = "expire_time", columnDefinition = "timestamp default CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date expireTime;
@Override
public void prePersist() {
super.prePersist();
id = null;
if (email == null) {
email = "";
}
if (avatar == null) {
avatar = "";
}
if (description == null) {
description = "";
}
if (expireTime == null) {
expireTime = DateUtils.now();
}
}
}
注解解释:
@Data:Lombok 注解,自动生成 get()、set()、toString() 等方法。
@Entity:JPA 注解,声明该类为一个实体类, 必须与 @Id 搭配使用。
@Table:JAP 注解,声明该类对应数据库中的某个数据表,name 指明表名。
@ToString:lombok 注解,callSuper = true 表示调用 toString() 方法时会输出父类的属性。
@EqualsAndHashCode:自动生成 equals() 和 hashCode() 方法,默认 callSuper 为 false, 为 true 表示 equals() 在方法比较时会调用父类的 equals()(如果父类的 equals() 返回 false,则直接返回 false,否则继续比较)。
@Id:JPA 注解,声明主键。
@GeneratedValue:JPA 注解,声明主键的生成策略,IDENTITY 表示使用自增 id。
@Column:JPA 注解,声明实体对象的属性映射到数据表中的哪一个字段,name 指定字段名,columnDefinition 指定字段的定义。
User 类中定义了用户名、昵称、邮箱等用户数据,Halo 使用 JPA 将实体对象持久化到数据库中,也就是将 User 对象的各个属性存储到数据表 users 的各个字段中。JPA 支持自动创建数据表,所以启动项目前无需建表,关于 JPA 的使用,可以参考 SpringBoot 整合 Spring Data JPA。
User 类继承了 BaseEntity,BaseEntity 类中定义了一些通用的属性,如 createTime、updateTime 以及 deleted 等,分别指用户的创建时间、修改时间以及是否被删除,users 表中有对应的字段。此外,BaseEntity 类还定义了三个方法,分别为 prePersist()、preUpdate() 和 preRemove():
prePersist() 方法在对象持久化到数据库之前被调用。
preUpdate() 方法在对象的某个属性发生变动时被调用,如更新实体的 update_time。
preRemove() 方法在对象从数据库删除前被调用。
BaseEntity 并没有对应某一个数据表,它被 @MappedSuperclass 修饰, @MappedSuperclass 属于 JPA 注解,应用于实体类的父类中, 该注解作用的类不会映射到数据表,但其属性都将映射到子类所对应的数据表。也就是说不同实体类的通用属性可在相同的父类中定义,子类继承父类后,父类中的这些通用属性会持久化到子类对应的数据表中。
BaseEntity 类定义如下:
@Data
@ToString
@MappedSuperclass // JPA 注解, 应用于实体类的父类中, 该注解作用的类不会映射到数据表,但其属性都将映射到子类的数据表
@EqualsAndHashCode
public class BaseEntity {
/**
* Create time.
*/
@Column(name = "create_time", columnDefinition = "timestamp default CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date createTime;
/**
* Update time.
*/
@Column(name = "update_time", columnDefinition = "timestamp default CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;
/**
* Delete flag.
*/
@Column(name = "deleted", columnDefinition = "TINYINT default 0")
private Boolean deleted = false;
@PrePersist // @PrePersist 事件在实体对象插入到数据库的过程中发生
protected void prePersist() {
deleted = false;
Date now = DateUtils.now();
if (createTime == null) {
createTime = now;
}
if (updateTime == null) {
updateTime = now;
}
}
@PreUpdate // @PreUpdate 事件在实体的状态同步到数据库之前触发
protected void preUpdate() {
updateTime = new Date();
}
@PreRemove // @PreRemove 事件在实体从数据库删除之前触发
protected void preRemove() {
updateTime = new Date();
}
}
数据表
项目启动成功后,JPA 会为实体类自动生成对应的数据表。可以使用 Navicat 查看 MySQL 中库名为 'halodb' 的数据库(自己配置的库名),发现自动创建了如下数据表:
下面介绍不同数据表的作用以及对应的字段含义,由于许多实体类都继承自 BaseEntity,所以不同数据表中会有一些通用的字段,如:
id
:主键(虽不在 BaseEntity 中定义,但每个子类中都存在)。crate_time
:创建时间。deleted
:是否已经删除。update_time
:更新时间。
下面介绍各个数据表中,特定字段的具体含义:
1. attachments:附件表,用于存放图片和文件。
file_key
:文件的 key,可以根据 file_key 删除文件。height
:图片高度。media_type
:媒体类型,如 text/html、image/jpeg 等。name
:附件的名字。path
:附件的存储路径。size
:附件的大小。suffix
:附件的后缀,如 png、html 等。thumb_path
:缩略图的访问路径,该路径指定的资源可用作为封面图。type
:附件的上传类型,如上传到本地(type 为 0)、阿里云(type 为 4)。width
:图片宽度。
2. categories:文章分类目录表,发布文章时可设置文章所属的分类。
decryption
:描述。name
:分类名。parent_id
:父目录 id。password
:密码。slug
:别名。slug_name
:项目中没有用到。thumbnail
:分类的封面图。
3. comment_black_list:评论黑名单表,用于禁止某个 ip 进行评论。
ban_time
:封禁时间。ip_address
:封禁的 ip。
4. comments:评论表,可对文章进行评论,也可对评论进行回复,还可以对页面(友情链接、图库、日志等)进行评论。
type
:给文章进行评论时 type 为 0,给页面进行评论时 type 为 1。allow_notification
:是否允许通知。author
:评论者的姓名。author_url
:评论者的 url。content
:评论内容。email
:评论者的 email。gravatar_md5
:评论者的头像。ip_address
:评论者的 ip。is_admin
:评论者是否为博主。parent_id
:如果回复某个评论,则 parent_id 为该评论的 id;如果评论文章,则 parent_id 为 0。post_id
:哪篇文章或哪个页面的评论。status
:评论的状态,0 表示已发布,1 表示待发布,2 表示添加到了回收站。top_priority
:是否置顶。user_agent
:用户代理,例如浏览器。
5. journals:用户日志表,在 Halo 中用户可以对外分享日志(记录生活的日志),日志的信息存储在 journals 表中。
content
:日志内容。likes
:点赞量。source_content
:原始内容。type
:日志类型,公开日志的 type 为 0,私密日志的 type 为 1。
6. links:友情链接表,用于访问其他博客或资源。
description
:描述。logo
:标志。name
:名称。priority
:排序编号。team
:所属分组。url
:链接。
7. logs:系统日志表,记录用户的操作。
content
:日志内容。ip_address
:操作者的 ip。log_key
:log_key 通常为操作对象的标识,例如发布文章时 log_key 是文章的 id,用户登录时 log_key 是用户的 userName。type
:日志类型,例如发表文章时 type 为 5,登录时 type 为 25。
8. menus:菜单表,博客的主页有多个菜单,且每个菜单都可以是多级菜单。
icon
:图标。name
:名称parent_id
:父级菜单的 id。priority
:优先级,用于博客首页上菜单的排序。target
:可选 _self 和 _blank,_self 表示在当前页面打开菜单所指向的链接;_blank 表示在新的页面打开链接。team
:所属分组。url
:菜单所指向的链接。
9. metas:元数据表,用于设置文章或页面的属性,可在发布文章或页面时的 "高级" 选项中进行操作。
type
:设置文章的元数据时 type 为 0,设置页面的元数据时 type 为 1。mate_key
:元数据 key 可以设置文章是否支持点赞、是否支持复制等。mate_value
:key 对应的值post_id
: 文章或页面的 id。
10. options:博客设置表,或者称为选项表,用于存储系统设置的相关信息。用户可在 Dashboard 界面的 "系统" -> "博客设置" 中进行配置。
option_key
:博客的选项,例如博客标题 blog_title、主题 theme、是否已安装 is_installed 等。type
:博客的内部选项的 type 为 0,自定义选项的 type 为 1。option_value
:选项对应的值。
11. photos:图片表,Halo 可以设置图库,图库页面的图片存放在 photos 表中。
description
:描述。likes
:点赞量。location
:拍摄地点。name
:名称。take_time
:拍摄日期。team
:所属分组。thumbnail
:缩略图地址。url
:图片链接。
12. post_categories:文章 - 分类的关系表,记录每个文章属于哪个分类。
category_id
:分类 id。post_id
:文章 id。
13. post_tags:文章标签表,记录文章的标签。
post_id
:文章 id。tag_id
:标签 id。
14. posts:文章表,也用来存储页面。
type
:文章的 type 为 0,页面的 type 为 1。disallow_comment
:是否关闭评论。edit_time
:编辑时间。editor_type
:编辑器类型。format_content
:格式化后的内容。likes
:点赞量。meta_description
:自定义描述。meta_keywords
:自定义关键词。original_content
:原始内容。password
:密码。slug
:别名。status
:状态,0 表示已发布,1 表示待发布,2 表示位于回收站,3 表示私密文章或页面。summary
:文章摘要。template
:自定义的模板,新增页面时可设置模板。thumbnail
:封面图。title
:标题。top_priority
:是否置顶。url
:链接。visits
:访问量。word_count
:字数统计。
15. tags:标签表,发布文章时,可为文章设置标签。
name
:标签名称。slug
:别名。slug_name
:项目中没有用到。thumbnail
:标签的封面图。
16. theme_settings:主题设置表,设置博客主题。
setting_key
:主题中可设置的选项,例如文章标题是否大写 post_title_uppper、博客首页的邮箱 email 等。theme_id
:主题的 id。setting_value
:setting_key 对应的值。
17. users:用户表,记录用户信息。
avatar
:头像。decription
:描述。email
:邮箱。expire_time
:过期时间,严格来说应该称为账号的起始有效时间,当前时间超过 expire_time 时,该账号才能正常登录。maf_key
:两步验证码的 key。maf_type
:是否开启了两步验证码,0 表示未开启(默认),1 表示开启。nickname
:昵称。password
:密码。username
:用户名。
Halo 开源项目学习(二):实体类与数据表的更多相关文章
- Halo 开源项目学习(七):缓存机制
基本介绍 我们知道,频繁操作数据库会降低服务器的系统性能,因此通常需要将频繁访问.更新的数据存入到缓存.Halo 项目也引入了缓存机制,且设置了多种实现方式,如自定义缓存.Redis.LevelDB ...
- Halo 开源项目学习(四):发布文章与页面
基本介绍 博客最基本的功能就是让作者能够自由发布自己的文章,分享自己观点,记录学习的过程.Halo 为用户提供了发布文章和展示自定义页面的功能,下面我们分析一下这些功能的实现过程. 管理员发布文章 H ...
- Halo 开源项目学习(五):评论与点赞
基本介绍 博客系统中,用户浏览文章时可以在文章下方发表自己的观点,与博主或其他用户进行互动,也可以为喜欢的文章点赞.下面我们一起分析一下 Halo 项目中评论和点赞功能的实现过程. 发表评论 评论可以 ...
- php开源项目学习二次开发的计划
开源项目: cms 国内 dedecms cmstop 国外 joomla, drupal 电商 国内 ecshop 国外 Magento 论坛 discuz 博客 wordpress 学习时 ...
- 实体类和数据表的映射异常(XXX is not mapping[ ])
在使用SSH框架开发过程,使用hibernate框架提供的工具类实现与数据库数据交互,在执行cmd操作时,如果出现以下异常: org.hibernate.hql.ast.QuerySyntaxExce ...
- Halo 开源项目学习(一):项目启动
项目简介 Halo 是一个优秀的开源博客发布应用,在 GitHub 上广受好评,正好最近在练习写博客,借此记录一下学习 Halo 的过程. 项目下载 从 GitHub 上拉取项目源码,Halo 从 1 ...
- Halo 开源项目学习(三):注册与登录
基本介绍 首次启动 Halo 项目时需要安装博客并注册用户信息,当博客安装完成后用户就可以根据注册的信息登录到管理员界面,下面我们分析一下整个过程中代码是如何执行的. 博客安装 项目启动成功后,我们可 ...
- Halo 开源项目学习(六):事件监听机制
基本介绍 Halo 项目中,当用户或博主执行某些操作时,服务器会发布相应的事件,例如博主登录管理员后台时发布 "日志记录" 事件,用户浏览文章时发布 "访问文章" ...
- android 开源项目学习<二>
roottools: RootTools gives Rooted developers easy access to common rooted tools... https://code.g ...
随机推荐
- 不会真有人还不会调用Excel吧?
哈喽,大家好!我是指北君. 大家有没有过这样的经历:开发某个项目,需要调用Excel控件去生成Excel文件.填充数据.改变格式等等,常常在测试环境中一切正常,但在生产环境却无法正常调用Excel,不 ...
- Vscode的使用小技巧
命令行启动code 如果你的系统是Linux系统(我使用的是Ubuntu 16.04)这样就可以直接使用 code + filename来编辑文件(就像vi + filename) 如果你的系统是Ma ...
- C++ cout 数字之间进制的转换
转换一个数变成8进制,则为 cout << oct << x << endl; 转换一个数变为16进制,为 cout << hex << x ...
- Maria DB数据库基础知识
Maria DB连接 与MariaDB建立连接的一种方法是在命令提示符下使用mysql二进制文件. Maria DB命令行登录数据库服务: mysql -u root -p -- 换行输入密码 上面给 ...
- 面试问题之C++语言:如何避免内存泄漏?
转载于:https://www.php.cn/csharp-article-416104.html 1.不要手动管理内存,可以尝试在适用的情况下使用智能指针. 2.使用string而不是char*.s ...
- 分布式集群中为什么会有 Master?
在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机 器可以共享这个结果,这样可以大大减少重复计算,提高性能,于是就需要进行 leader 选举.
- Spring ModelAttribute注解失效原因
public String test(@RequestParam(value = "test") @ModelAttribute("test") String ...
- ArrayList、LinkedList、Vector、Array
ArrayList 本质是一个数组. 优势:追加元素到数组末尾的时候速度快,同时检索元素的速度也快. 劣势:如果要插入一个元素到数组之间慢:如果要追加的元素数量多于数组的容量,则需要频繁扩容使用Arr ...
- 学习FastDfs(三)
FASTDFS是什么 FastDFS是由国人余庆所开发,其项目地址:https://github.com/happyfish100 FastDFS是一个轻量级的开源分布式文件系统,主要解决了大容量的文 ...
- 学习zabbix(三)
前言: 学习zabbix之前,不得不了解的是SNMP协议 SNMP:简单网络管理协议(Simple Network Protocol) Snmp由两部分组成,监控端和被监控端 监控模式: 主动模式:N ...