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 ...
随机推荐
- bzoj2989 数列(KDTree)
bzoj2989 数列(KDTree) bzoj 该说不愧是咱,一个月才水一篇题解然后还水的一批 题目描述: 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和 ...
- vue集成CKEditor构建框架的使用,遇到富文本框不出现工具栏等操作
官方关于Vue集成CKEditor富文本框的文档:https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/framew ...
- Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?
Redisson.Jedis.lettuce 等等,官方推荐使用 Redisson.
- springmvc组件组成以及springmvc的执行过程
springmvc三大组件 处理器映射器:用户请求路径到Controller方法的映射 处理器适配器:根据handler(controlelr类)的开发方式(注解开发/其他开发) 方式的不同区寻找不同 ...
- it-术语
QPS:每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准. 因特网上,经常用每秒查询率来衡量域名系统服务器的机器的性能,其即为QPS. 对应fetches/sec,即每秒的 ...
- selenium 模块使用
selenium 概念:基于浏览器自动化的一个模块,可以模拟浏览器行为 环境的安装:下载selenium模块 selenium和爬虫之间的关联是什么? 便捷的获取页面中动态加载的数据 requests ...
- css技术之用最高和最宽的限制“max-height和max-width”做图片同比例缩放,达到图片不变形目的,做出批量打印图片功能,页面打印“window.print()”
一.简介 他们是为流而生的,像width/height这种定死的砖头式布局,min-width/max-width就没有存在的意义 ,min-width/max-width一定是自适应布局或流体布局中 ...
- 【Visual Studio】VS 提示图标的含义
一.前言 vs 中提示图标是什么意思 二.正文 信号图标 以下信号图标应用于所有原有的图标并指示它们的辅助功能. 图标 描述 <No Signal Icon> Public. 可从此组件中 ...
- DIANA算法
DIANA算法 DIANA算法示例 DIANA算法练习
- translate3d 对 z-index 居然有影响
在 Mobile 端需要注意. 安卓 默认浏览器 当中如果 div1 div2 如果 div1 有 translate3d 而 div2 没有 那么 div2 的 z-index 会无效. 解决办法: ...