Java阶段四Day04
文章目录
- Java阶段四Day04
- 关于SLF4j日志框架
- 使用@Sql注解
- 关于DAO架构
- 关于Service
- 关于异常
关于SLF4j日志框架
-
在开发实践中,通常禁止使用
System.out.println()
这种语句输出信息,主要原因有:- 输出效率低下,特别是字符串与变量拼接时
- 在开发过程中输出的某些信息,不适合在测试环境或生产环境中被显示
-
在Spring Boot项目中,基础依赖项(spring-boot-starter)中已经包含了日志相关的依赖项,可以直接使用日志框架来输出信息
-
在添加了Lombok后,在任何类的声明之前,添加
@Slf4j
注解,则编译期会自动声明一个名为log的变量,所以可以在类中通过此变量来输出日志 -
如果没有使用Lombok,可以自行声明日志变量,例如:
private static Logger logger = LoggerFactory.getLogger(当前类的类名.class);
-
日志级别分为:
TRACE
、DEBUG
、INFO
、WARN
、ERROR
-
当配置包名时,不必把包名配置得特别具体,可以作用于其子孙包下所有的类,但是,必须至少配置1级包名,例如配置到
com
这一级包,不可以完全不配置包名,需要注意,当前项目中添加的所有依赖项,也是当前项目的一部分,不应该将包名配置得过于简单 -
提示:Mybatis框架会生成各Mapper接口的对象,这些对象在执行SQL语句时,也会输出日志,是
trace
和info
级别的日志,当把日志的显示级别设置为较低的级别时,可以看到这些日志 -
在调用日志的方法时,如果输出的信息中包含变量值,推荐使用
trace(String message,Object… args)方法(其它级别也是同样参考方法),在String message参数中,可以使用{}
作为占位符,表示此处是一个变量值,然后,通过Object. .. args
依次传入各占位符对应的值int x = 1; int y = 2; System.out.println("x = " + x + ", y = " + y + ", x + y = " + (x + y));//传统做法 log.info("x = {}, y = {},x+ y = {}", x , y , x + y);//使用日志输出变量的做法
-
SLF4j
只是一个日志框架的标准,具体的日志相关功能并不是由它实现的,常见的实现了日志相关功能的日志框架有:log4j
、logback
等,SLF4j
提供了这些日志框架向SLF4j
标准的转换
使用@Sql注解
- 是
MyBatisPlus
框架提供的注解,用于自定义SQL查询语句。使用@sql
注解,可以直接在Mapper接口中定义SQL查询语句,避免编写大量的XML配置文件。一般来说,@sql
注解比较适合一些简单的查询语句,不适合复杂、动态的查询。如果需要进行复杂的查询,建议使用MyBatisPlus
提供的QueryWrapper
或LambdaQueryWrapper
进行构建查询条件 - 还可以在测试类.上使用
@Sql
注解,可以作用于此测试类中所有测试方法,但不一定合适。如果只是需要执行测试后,数据库中的数据不会发生变化,还可以在测试方法上,添加@Transactional
注解,可以使得测试后自动回滚,表现为:测试方法对数据的修改不会被保存到数据库中,而真正想要提交的数据再添加@Commit
关于DAO架构
技术是会变化的,当下使用MyBaits / MyBaits Plus
是 非常好的选择,以后可能就不是了,如果改为使用其它框架,原本Service
调用MyBatis / MyBaits Plus
的代码就需要跟随调整。为了更好的实现解耦,DAO
层不应该对外直接暴露所使用的技术框架,则可以在Service
和MyBatis / MyBaits Plus
接口之间加一层
接口和实现类的命名有两套规则:
-
【强制】对于Service和DAO类,基于SOA的理念,暴露出来的服务-定是接口,内部的实现类用Impl的后缀与接口区别
- 正例:
CacheServiceImpl
实现CacheService
接口
- 正例:
-
【推荐】如果是形容能力的接口名称,取对应的形容词做接口名(通常是-able的形式)
- 正例:
AbstractTranslator
实现Translatable
- 正例:
关于Service
- Service是项目中用于处理业务的组件,主要职责是:组织业务流程与业务逻辑,以保障数据的完整性、有效性、安全性
- 安全性:数据会随着我们设定的规则而产生,或发生变化
- 在项目中,专门划分出
Service层
的主要原因有:- 分工明确,因为
Controller
或DAO
层均有明确的需要解决的问题,它们不应该关心业务流程与业务逻辑 - Service中的代码应该与框架无关(除了最基础的框架以外,例如Spring),无论你的项目使用什么技术框架,数据处理规则应该是不变的,而
Controller
和DAO
层都是基于某些框架的
- 分工明确,因为
- 关于Service中的业务方法的声明原则:
- 返回值类型:仅以操作成功为前提来设计返回值类型,如果视为操作失败,将通过抛出异常来表示
- 方法名称:自定义
- 参数列表:通常按照客户端或控制器(Controller) 会传递过来的参数来设计
关于异常
- 在
Service
中使用抛出异常的方式来表示某种“失败”,在调用Service
中的方法时,也会捕获对应的异常,来发现并处理这些“失败” - 如果抛出的异常是某种已经存在的异常类型,例如使用
RuntimeException
,在实际执行时,如果因为其它原因导致了RuntimeException
,对于方法的调用者而言,将无法正确的区分,最终,捕获并处理时可能不准确 - 为了解决此问题,在
Service
中抛出的异常必须是自定义异常 - 自定义的异常需要继承自
RuntimeException
,主要原因有:Spring MVC
框架有统一处理异常的机制,所以,Service
方法始终抛出异常(throw / throws) ,并不处理(不使用try…catch) ,Controller
方法也始终抛出异常,则没有必要反复通过throws关键字声明抛出异常!如果继承的父级异常不是RuntimeException
,必须在各Service
方法、Controller
方法都声明抛出异常Spring JDBC
处理事务时,只会根据RuntimeException
执行回滚
- 自定义的异常,应该包含带
String message
参数的构造方法,使得抛出异常时可以封装异常信息- 关于异常的描述文本,应该是“谁抛出,谁描述”的原则
- 【强制】不允许任何魔法值(即未经定义的常量)直接出现在代码中