AbstractEntity需要准备的有哪些

62次阅读
没有评论

共计 3286 个字符,预计需要花费 9 分钟才能阅读完成。

本篇内容主要讲解“AbstractEntity 需要准备的有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“AbstractEntity 需要准备的有哪些”吧!

关系型数据库其实很讨人厌,尤其是在你使用数据库驱动的开发模式时。需要首先把表给创建好了,然后再使用代码生成器反向生成一堆几乎无法可读的代码。当字段有变更的时候,又是一番折腾。

这其中的典型,就是 MyBatis,所以催生了更加简洁的 MyBatis Plus。

了解到一些大厂(阿里、腾讯、抖音等),JPA 的使用也越来越广泛了,包括我们公司,这是把合适的工具放到了合适的地方。如果想要快速开发,JPA 无疑是一个比较好的选择。你无需关注数据库表的结构,使用代码驱动即可完成工作,管它后面是 MySQL 还是 Oracle。JPA 把数据库相关的知识给弱化了,让你专注于业务开发。

我个人曾是非常排斥 JPA 这种弱化 SQL 的工具的,这源于对早起 Hibernate 版本的错误认识。但尝试过 mybatis、spring-data-jdbc、jooq 后,发现这个东西是真的香! 一个迟到的赞,送给 JPA。

这对一些管理系统来说,非常合适。因为性能并不是这些系统主要的痛点,业务复杂性才是。

本文将介绍一个简单的实体类,需要准备哪些基本字段。这些字段,又是如何在代码中被使用的。

1. 基本字段介绍

首先看一下我们的基础定义类。

代码不多,信息却不少。

下面来一行行解析。

@Data

Data 注解是属于 lombok 类的,lombok 是地球人都知道的代码简化工具,提供了非常多的注解。如果你不想记忆太多的注解,直接加上一个 Data,是最偷懒的选择。

@MappedSuperclass

这个注解是 JPA 的,用来标识父类。标注为 @MappedSuperclass 的类将不是一个完整的实体类,不会映射到数据库表,但是它的属性都将映射到子类的数据库字段中。放在这里再合适不过了。

@EntityListeners(AuditingEntityListener.class)

开启自动审计功能,这个和下面的两个日期字段是相互配合的,我们稍后介绍。

@JsonIgnoreProperties(value = { hibernateLazyInitializer ,  handler}) // 直接使用 bean 时,避免 json 序列号失败

有时候,我们想要再 controller 层直接使用 JPA 的实体。但 JPA 内部其实是有很多附加变量的,比如 hibernateLazyInitializer。

为了让实体在 json 序列化的时候能够正常进行,需要忽略这两个字段。所以这个注解,是属于 jackson json 的。

2.   自定义 ID 生成器

JPA 其实提供了非常多的 ID 生成策略。不过,在互联网应用下,应用较多的还是雪花算法,因为它有着良好的扩展性,在数据迁移的时候也不会有很多冲突。

为了指定雪花算法,我们需要下面几行代码。

static final String ID_GEN =  cn.xjjdog.bcmall.utils.db.DistributedId  @Id @GenericGenerator(name =  IdGen , strategy = ID_GEN) @GeneratedValue(generator =  IdGen)

其中的一个关键,就是使用我们名称叫做 IdGen 的 ID 生成器。这里的代码,是有一点小遗憾的。由于 JVM 类加载的缘故,我们无法在注解中直接使用类的名称(*.class.getName())   来获取它的包路径,只能作为字符串写死在这里。

下面我们就来看一下这个 ID 生成器的处理。

public class DistributedId implements IdentifierGenerator { @Override public Serializable generate(SharedSessionContractImplementor sharedSessionContractImplementor, Object obj) throws HibernateException { if (obj == null) throw new HibernateException(new NullPointerException()) ; if ((((AbstractEntity) obj).getId()) == null) { return String.valueOf(Snowflake.createId()); } else { return ((AbstractEntity) obj).getId(); } } }

代码如上。在直接使用之前,我们还做了一点小处理。当我们判断实体的 ID 为空的时候,才使用雪花算法构造一个新的 ID; 否则使用实体原来设置好的 ID,保持不变。

为什么这样做? 因为这是有需求的。像订单这种业务,你需要先生成一个订单号,然后再更新一些数据库信息,发布一些消息等; 而不是在保存动作出发的时候才生成一个。

如果你不做上面代码的处理。JPA 将每次保存的时候都自动生成一个,覆盖了你原有的。我就在这里吃过亏,通过 debug 代码才进行的修复。

3.   自动填充字段

上面说到 createdDate 和 lastModifiedDate 两个字段,其实在使用的时候,是不需要手动去设值的。这两个值,将通过审计功能自动完成。

@EntityListeners(AuditingEntityListener.class)

当然,我们还要用特有的注解,来标识这两个字段。

/** *  创建时间  */ @CreatedDate private Date createdDate; /** *  更新时间  */ @LastModifiedDate private Date lastModifiedDate;

最后,不要忘了在全局配置中通过 Config 开启这个功能。

@Configuration @EnableJpaAuditing public class JpaConfig { }

当然,审计是不能没有用户的。所以这个系列还有 @CreatedBy 注解,用来标注是谁创建的。你需要在代码中组装它们,比如下面的代码,就是从 Spring  Sercurity 中获取用户信息。

@Configuration @Slf4j public class UserAuditor implements AuditorAware String  { @Override public Optional String  getCurrentAuditor() { UserDetails user; try { user = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); return Optional.ofNullable(user.getUsername()); }catch (Exception e){ return Optional.empty(); } } }

4. End

JPA 写管理系统,真的是神器。当你不需要考虑极限的代码效率时,是一个非常好的选择。再看看最近的 MyBatis 版本,包括 MyBatis  Plus 设计,很多东西已经和 JPA 越来越像了。因为在设计上来说,JPA 是最接近面向对象编程的思想的。

B 端复杂业务的技术栈,并不需要和 C 端的技术栈相雷同。JPA 显然通过极少的代码和约定,就能把事情搞定,让开发者真正的把重点关注到业务开发上来。后面的文章,我们还会用到 MyBatis 和 MyBatis  Plus,到时候,我们再详细分析它们使用的场景。

到此,相信大家对“AbstractEntity 需要准备的有哪些”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-27发表,共计3286字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)