基本介绍

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 开源项目学习(二):实体类与数据表的更多相关文章

  1. Halo 开源项目学习(七):缓存机制

    基本介绍 我们知道,频繁操作数据库会降低服务器的系统性能,因此通常需要将频繁访问.更新的数据存入到缓存.Halo 项目也引入了缓存机制,且设置了多种实现方式,如自定义缓存.Redis.LevelDB ...

  2. Halo 开源项目学习(四):发布文章与页面

    基本介绍 博客最基本的功能就是让作者能够自由发布自己的文章,分享自己观点,记录学习的过程.Halo 为用户提供了发布文章和展示自定义页面的功能,下面我们分析一下这些功能的实现过程. 管理员发布文章 H ...

  3. Halo 开源项目学习(五):评论与点赞

    基本介绍 博客系统中,用户浏览文章时可以在文章下方发表自己的观点,与博主或其他用户进行互动,也可以为喜欢的文章点赞.下面我们一起分析一下 Halo 项目中评论和点赞功能的实现过程. 发表评论 评论可以 ...

  4. php开源项目学习二次开发的计划

      开源项目: cms 国内 dedecms cmstop 国外 joomla, drupal 电商 国内 ecshop 国外 Magento 论坛 discuz 博客 wordpress   学习时 ...

  5. 实体类和数据表的映射异常(XXX is not mapping[ ])

    在使用SSH框架开发过程,使用hibernate框架提供的工具类实现与数据库数据交互,在执行cmd操作时,如果出现以下异常: org.hibernate.hql.ast.QuerySyntaxExce ...

  6. Halo 开源项目学习(一):项目启动

    项目简介 Halo 是一个优秀的开源博客发布应用,在 GitHub 上广受好评,正好最近在练习写博客,借此记录一下学习 Halo 的过程. 项目下载 从 GitHub 上拉取项目源码,Halo 从 1 ...

  7. Halo 开源项目学习(三):注册与登录

    基本介绍 首次启动 Halo 项目时需要安装博客并注册用户信息,当博客安装完成后用户就可以根据注册的信息登录到管理员界面,下面我们分析一下整个过程中代码是如何执行的. 博客安装 项目启动成功后,我们可 ...

  8. Halo 开源项目学习(六):事件监听机制

    基本介绍 Halo 项目中,当用户或博主执行某些操作时,服务器会发布相应的事件,例如博主登录管理员后台时发布 "日志记录" 事件,用户浏览文章时发布 "访问文章" ...

  9. android 开源项目学习<二>

    roottools:   RootTools gives Rooted developers easy access to common rooted tools...  https://code.g ...

随机推荐

  1. spring学习三:Spring的Aop、代理

    ref:https://mp.weixin.qq.com/s/J77asUvw8FcnF-6YlX6AAw AOP相关术语:    Joinpoint(连接点):类里面可以被增强的方法,这些方法称为连 ...

  2. 什么是Spring IOC 容器?

    Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期.

  3. SpringSecurity集成启动报 In the composition of all global method configuration, no annotation support was actually activated 异常

    异常内容: Caused by: java.lang.IllegalStateException: In the composition of all global method configurat ...

  4. Netty学习摘记 —— 初识编解码器

    本文参考 本篇文章是对<Netty In Action>一书第十章"编解码器框架"的学习摘记,主要内容为解码器和编码器 编解码器实际上是一种特殊的ChannelHand ...

  5. 攻防世界shrine

    shrine import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.environ.pop('FLAG' ...

  6. Linux基础学习 | gcc、g++的安装和使用

    安装gcc 1.apt-get命令是debain Linux发新版的APT软件包管理工具. dabian.ubuntu.deepin等Linux系统通过以下命令: 安装gcc:Shell输入sudo ...

  7. Numpy实现多项式曲线拟合

    Numpy实现多项式曲线拟合 这里可以对比matlab中的拟合方式看看matlab拟合函数的三种方法,和第一种方式很像 问题定义:对于一堆数据点(x, y),能否只根据这些数据,找出一个函数,使得函数 ...

  8. React 可视化开发工具 Shadow Widget 非正经入门(之五:指令式界面设计)

    本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点.本篇解释 Shadow Widget 中类 Vue 的控制指令,与指令式界面设计相关. 1. 指令式界面设计 Vue 与 A ...

  9. css布局基础总结

    前端css布局知识繁杂,实现方式多种多样.想写出高效.合理的布局,必须以深厚的css基础为前提.为了方便记忆和复习,将css布局要点记录如下.内容较多,应用方面说的不太详细,但都是很实用的点. 所谓布 ...

  10. 认识 Function.prototype.bind()

    欢迎前端爱好者加入QQ群:112916679 答疑解惑,且可获取更多前端资料! bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个 ...