开发常识技巧
DO/BO/DTO/VO
DO = PO
都是表示持久化对象的实体类,Persistent Object 和 Data Object
如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。通过 DAO 层向上传输数据源对象
DTO
又叫做 Data Transfer Object
业务上传输的数据对象,
例如一张数据库表有50个字段,那么PO就有50个属性,但是我们在远程服务或者页面显示只需要10个字段。这时就没有必要传输所有的字段,而是用10个属性的DTO来进行传递
BO
业务对象,具体是指由Service层内封装的临时业务逻辑的对象
通过调用 DAO 方法 , 结合 PO、VO 进行业务操作。 一个BO对象可以包括多个PO对象
除了基本的 get set 方法,BO本身也会包含很多针对自身数据进行计算的方法
VO
View Object
页面展示用的数据对象
代码举例
以一个最常见的用户注册场景,引出分层设计的模式
现在我们有一张用户表,包含 id name email password
1 |
|
try-with-resources
JDK7 引入的新特性,其作用是简化try catch
例如下面这一段
1 |
|
当try
块执行完毕后,无论是否出现异常,都会自动关闭inputStream
资源。
- 自动关闭资源:
- 任何在
try
块中声明的资源都会在try
块结束后自动关闭。这相当于在finally
块中调用了资源的close()
方法。 - 这简化了代码,使得资源管理更加安全和便捷,防止因忘记关闭资源而导致资源泄露。
- 任何在
- 可选的异常处理:
- 即使
try
块中的代码抛出异常,资源仍然会被自动关闭。 - 如果需要处理异常,可以在
try-with-resources
块后添加catch
块来捕获和处理异常。
- 即使
业务上如何进行调试
针对业务接口调试,我们主要就是从接口进入,然后看接口输出参数,出问题的字段,找到有没有被正确赋值(要么没赋值,要么错误赋值导致的)然后看下业务方法在哪里赋值合适
页面上一些接口不清楚在哪里的,有两种方式来定位:
- 问前端接口调用的是哪一个,取数怎么取的参数
- 全局搜索页面上的关键字,有文档注释的就会自动定位到核心接口
QueryDSL
动态参数解析
可以使用 Predicate 参数来绑定实体类信息进行动态参数类型传递,不需要手动进行解析
当然在实体类中还是需要进行额外的配置和映射
1 |
|
这里就绑定了 Tast 这个类的实体信息,之后前端传递的,和实体类中直接包含或者是通过复杂数据类型组合的方式实现的间接包含的数据类型,都会被自动解析和传递
代码自动生成
QueryDSL 会根据我们的实体类生成一组与之对应的查询类型。这些类型通常以 Q
开头,并且包含了一些静态字段和方法,用于帮助构建查询
这些自动生成的 java 代码都会放在 build/generated/sources/annotationProcessor/java/main
目录下而不是自己编写的源代码目录下
1 |
|
@Embedded 和 @Transient
这两个都是用于 SpringData JPA 中实体类上的注解
其中 @Embedded
注解用于将一个可嵌入的复杂数据类型 作为实体的一部分进行持久化。它表示该属性是一个嵌入类型,将其所有字段嵌入到拥有它的实体表中
而 @Transient
注解用于标记某个字段不需要持久化到数据库中。被标记的字段在ORM框架中会被忽略,不会在数据库表中生成对应的列,也不会在持久化操作中进行存取
异常抛出和处理
异常的处理时机
在工具方法中 不要 catch 处理异常并返回某种默认值,不然会导致处理逻辑调用工具方法的时候不好直接定位 BUG,要的话就直接抛出
例如下面这种就是不被允许的
1 |
|
出了 BUG 是不好直接定位的,因为这里任何异常或者是非法值都会返回 0 值,前端数据反而还有值,而且大概率和数据库的不一致,这样肯定就 BUG 了,不好排查