Java阶段四Day04

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);
  • 日志级别分为:TRACEDEBUGINFOWARNERROR

  • 当配置包名时,不必把包名配置得特别具体,可以作用于其子孙包下所有的类,但是,必须至少配置1级包名,例如配置到com这一级包,不可以完全不配置包名,需要注意,当前项目中添加的所有依赖项,也是当前项目的一部分,不应该将包名配置得过于简单

  • 提示:Mybatis框架会生成各Mapper接口的对象,这些对象在执行SQL语句时,也会输出日志,是traceinfo级别的日志,当把日志的显示级别设置为较低的级别时,可以看到这些日志

  • 在调用日志的方法时,如果输出的信息中包含变量值,推荐使用
    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只是一个日志框架的标准,具体的日志相关功能并不是由它实现的,常见的实现了日志相关功能的日志框架有: log4jlogback等,SLF4j提供了这些日志框架向SLF4j标准的转换

使用@Sql注解

  • MyBatisPlus框架提供的注解,用于自定义SQL查询语句。使用@sql注解,可以直接在Mapper接口中定义SQL查询语句,避免编写大量的XML配置文件。一般来说,@sql注解比较适合一些简单的查询语句,不适合复杂、动态的查询。如果需要进行复杂的查询,建议使用MyBatisPlus提供的QueryWrapperLambdaQueryWrapper进行构建查询条件
  • 还可以在测试类.上使用@Sql注解,可以作用于此测试类中所有测试方法,但不一定合适。如果只是需要执行测试后,数据库中的数据不会发生变化,还可以在测试方法上,添加@Transactional注解,可以使得测试后自动回滚,表现为:测试方法对数据的修改不会被保存到数据库中,而真正想要提交的数据再添加@Commit

关于DAO架构

技术是会变化的,当下使用MyBaits / MyBaits Plus是 非常好的选择,以后可能就不是了,如果改为使用其它框架,原本Service调用MyBatis / MyBaits Plus的代码就需要跟随调整。为了更好的实现解耦,DAO层不应该对外直接暴露所使用的技术框架,则可以在ServiceMyBatis / MyBaits Plus接口之间加一层

Java阶段四Day04_第1张图片

接口和实现类的命名有两套规则:

  • 【强制】对于Service和DAO类,基于SOA的理念,暴露出来的服务-定是接口,内部的实现类用Impl的后缀与接口区别

    • 正例:CacheServiceImpl实现CacheService接口
  • 【推荐】如果是形容能力的接口名称,取对应的形容词做接口名(通常是-able的形式)

    • 正例:AbstractTranslator实现Translatable

关于Service

  • Service是项目中用于处理业务的组件,主要职责是:组织业务流程与业务逻辑,以保障数据的完整性、有效性、安全性
  • 安全性:数据会随着我们设定的规则而产生,或发生变化
  • 在项目中,专门划分出Service层的主要原因有:
    • 分工明确,因为ControllerDAO层均有明确的需要解决的问题,它们不应该关心业务流程与业务逻辑
    • Service中的代码应该与框架无关(除了最基础的框架以外,例如Spring),无论你的项目使用什么技术框架,数据处理规则应该是不变的,而ControllerDAO层都是基于某些框架的
  • 关于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参数的构造方法,使得抛出异常时可以封装异常信息
    • 关于异常的描述文本,应该是“谁抛出,谁描述”的原则
  • 【强制】不允许任何魔法值(即未经定义的常量)直接出现在代码中

你可能感兴趣的:(Java之旅,java,mybatis,spring)