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

这其中的典型,就是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的。

  1. 自定义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代码才进行的修复。

  1. 主动填充字段

下面说到createdDatelastModifiedDate两个字段,其实在应用的时候,是不须要手动去设值的。这两个值,将通过审计性能主动实现。

@EntityListeners(AuditingEntityListener.class)复制代码

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

/*** 创立工夫*/@CreatedDateprivate Date createdDate;/** * 更新工夫*/@LastModifiedDateprivate Date lastModifiedDate;复制代码

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

@Configuration@EnableJpaAuditingpublic class JpaConfig {}复制代码

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

@Configuration@Slf4jpublic 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();        }    }}复制代码
  1. End

JPA写管理系统,真的是神器。当你不须要思考极限的代码效率时,是一个十分好的抉择。再看看最近的MyBatis版本,包含MyBatis Plus设计,很多货色曾经和JPA越来越像了。因为在设计上来说,JPA是最靠近面向对象编程的思维的。

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

参考:《2020最新Java根底精讲视频教程和学习路线!》
链接:https://juejin.cn/post/693856...