【SpringBoot】整合篇

发布于:2024-12-06 ⋅ 阅读:(94) ⋅ 点赞:(0)

1、log4j2

  • 第一步,导入依赖

    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-web</artifactId>  
        <exclusions><!-- 去掉springboot默认配置 -->  
            <exclusion>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-logging</artifactId>  
            </exclusion>  
        </exclusions>  
    </dependency> 
    
    <dependency> <!-- 引入log4j2依赖 -->  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-log4j2</artifactId>  
    </dependency> 
    

    如果用到 Mybatis-Plus 也需要排除默认日志依赖,不然会报错:

    SLF4J: Class path contains multiple SLF4J providers.
    SLF4J: Found provider [ch.qos.logback.classic.spi.LogbackServiceProvider@e874448]
    SLF4J: Found provider [org.apache.logging.slf4j.SLF4JServiceProvider@29b5cd00]
    SLF4J: See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual provider is of type [ch.qos.logback.classic.spi.LogbackServiceProvider@e874448]
    
  • 第二步,配置文件

    在项目的 resource 目录下新建文件 log4j2-spring.xml,如果自定义其他名称需在 application.yml中配置:

    logging:
      config: classpath:log4j2.xml
    

    配置文件 log4j2-spring.xml 模版:

    <?xml version="1.0" encoding="UTF-8"?>
    <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
    <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
    <configuration monitorInterval="5">
      <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
    
      <!--变量配置-->
      <Properties>
        <!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
        <!-- %logger{36} 表示 Logger 名字最长36个字符 -->
        <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
        <!-- 定义日志存储的路径 -->
        <property name="FILE_PATH" value="更换为你的日志路径" />
        <property name="FILE_NAME" value="更换为你的项目名" />
      </Properties>
    
      <appenders>
    
        <console name="Console" target="SYSTEM_OUT">
          <!--输出日志的格式-->
          <PatternLayout pattern="${LOG_PATTERN}"/>
          <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
          <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
        </console>
    
        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
        <File name="Filelog" fileName="${FILE_PATH}/test.log" append="false">
          <PatternLayout pattern="${LOG_PATTERN}"/>
        </File>
    
        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
          <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
          <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
          <PatternLayout pattern="${LOG_PATTERN}"/>
          <Policies>
            <!--interval属性用来指定多久滚动一次,默认是1 hour-->
            <TimeBasedTriggeringPolicy interval="1"/>
            <SizeBasedTriggeringPolicy size="10MB"/>
          </Policies>
          <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
          <DefaultRolloverStrategy max="15"/>
        </RollingFile>
    
        <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
          <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
          <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
          <PatternLayout pattern="${LOG_PATTERN}"/>
          <Policies>
            <!--interval属性用来指定多久滚动一次,默认是1 hour-->
            <TimeBasedTriggeringPolicy interval="1"/>
            <SizeBasedTriggeringPolicy size="10MB"/>
          </Policies>
          <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
          <DefaultRolloverStrategy max="15"/>
        </RollingFile>
    
        <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
          <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
          <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
          <PatternLayout pattern="${LOG_PATTERN}"/>
          <Policies>
            <!--interval属性用来指定多久滚动一次,默认是1 hour-->
            <TimeBasedTriggeringPolicy interval="1"/>
            <SizeBasedTriggeringPolicy size="10MB"/>
          </Policies>
          <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
          <DefaultRolloverStrategy max="15"/>
        </RollingFile>
    
      </appenders>
    
      <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
      <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
      <loggers>
    
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.mybatis" level="info" additivity="false">
          <AppenderRef ref="Console"/>
        </logger>
        <!--监控系统信息-->
        <!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
        <Logger name="org.springframework" level="info" additivity="false">
          <AppenderRef ref="Console"/>
        </Logger>
    
        <root level="info">
          <appender-ref ref="Console"/>
          <appender-ref ref="Filelog"/>
          <appender-ref ref="RollingFileInfo"/>
          <appender-ref ref="RollingFileWarn"/>
          <appender-ref ref="RollingFileError"/>
        </root>
      </loggers>
    
    </configuration>
    

    配置参数简介:

    • 日志级别

      机制:如果一条日志信息的级别大于等于配置文件的级别,就记录。

      • trace:追踪,就是程序推进一下,可以写个trace输出
      • debug:调试,一般作为最低级别,trace基本不用。
      • info:输出重要的信息,使用较多
      • warn:警告,有些信息不是错误信息,但也要给程序员一些提示。
      • error:错误信息。用的也很多。
      • fatal:致命错误。
    • 输出源

      • CONSOLE(输出到控制台)
      • FILE(输出到文件)
    • 格式

      • SimpleLayout:以简单的形式显示
      • HTMLLayout:以HTML表格显示
      • PatternLayout:自定义形式显示
        • %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间,输出到毫秒的时间
        • %-5level : 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
        • %c : logger的名称(%logger)
        • %t : 输出当前线程名称
        • %p : 日志输出格式
        • %m : 日志内容,即 logger.info(“message”)
        • %n : 换行符
        • %C : Java类名(%F)
        • %L : 行号
        • %M : 方法名
        • %l : 输出语句所在的行数, 包括类名、方法名、文件名、行数
        • hostName : 本地机器名
        • hostAddress : 本地ip地址

    log4j2配置详解:

    • 根节点Configuration

      属性:

      • status:用来指定log4j本身的打印日志的级别.
      • monitorinterval:用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s.

      子节点:

      • Appenders
      • Loggers(表明可以定义多个Appender和Logger).
    • Appenders节点:常见的有三种子节点:Console、RollingFile、File

    • Console 节点:用来定义输出到控制台的Appender。

      属性:

      • name:指定Appender的名字.
      • target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.

      子节点:

      • PatternLayout:输出格式,不设置默认为:%m%n.
    • File节点:用来定义输出到指定位置的文件的Appender.

      属性:

      • name:指定Appender的名字.
      • fileName:指定输出日志的目的文件带全路径的文件名.
      • PatternLayout:输出格式,不设置默认为:%m%n.
    • RollingFile节点:用来定义超过指定条件自动删除旧的创建新的Appender.

      属性:

      • name:指定Appender的名字.
      • fileName:指定输出日志的目的文件带全路径的文件名.
      • filePattern:指定当发生Rolling时,文件的转移和重命名规则.

      子节点:

      • PatternLayout:输出格式,不设置默认为:%m%n.
      • Policies:指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.
        • TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am…而不是7am.
        • SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小.
      • DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。
    • Loggers节点:常见的有两种:Root和Logger.

    • Root节点:用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出

      属性:

      • level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.

      子节点:

      • AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender.
    • Logger节点:用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。

      属性:

      • name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.
      • level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

      子节点:

      • AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity="false"只在自定义的Appender中进行输出。
  • 第三步,在代码中使用

    • 直接使用 slf4j
      public class Demo {
        private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class);
        
        public static void main(String... args) {
          log.error("Something else is wrong here");
        }
      }
      
    • 搭配 Lombok
      先导入 Lombok 依赖:
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.26</version>
      </dependency>
      
      import lombok.extern.log4j.Log4j2;
      
      @Log4j2
      public class LogTest {
          public static void main(String[] args) {
              log.info("this is info log");
              log.error("this is error log");
              log.debug("this is debug log");
              log.warn("this is warn log");
              log.trace("this is trace log");
              log.fatal("this is fatal log");
          }
      }
      

2、MySQL + MybatisPlus

spring-boot-starter-parent 3.4.0

  • 第一步,pom.xml 导入依赖
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
    <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
         <version>3.5.9</version>
     </dependency>
    
  • 第二步,application.yml 添加配置
    # mysql config
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=utf-8&amp;autoReconnect=true
        username: root
        password: zhangsan123
     
    # mybatis-plus config
    mybatis-plus:
      type-aliases-package: com.story.domain 					# 别名扫描包,指定实体类所在的包路径
      mapper-locations: "classpath*:/mapper/**/*.xml" 			# Mapper.xml 文件地址
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl	# 定义MyBatis-Plus的日志实现方式(若不配置该参数,Mybatis在默认情况下会采用自动检测的方式):org.apache.ibatis.logging.slf4j.Slf4jImpl、org.apache.ibatis.logging.log4j.Log4jImpl、org.apache.ibatis.logging.stdout.StdOutImpl、org.apache.ibatis.logging.nologging.NoLoggingImpl
        map-underscore-to-camel-case: true 						# 是否开启下划线和驼峰的映射
        cache-enabled: false 									# 是否开启二级缓存
      global-config:
        banner: false											# 控制MyBatis-Plus启动时是否显示banner信息
        db-config:
          id-type: assign_id 									# 主键生成策略:AUTO、NONE、INPUT、ASSIGN_ID、ASSIGN_UUID
          update-strategy: not_null 							# 更新策略: 只更新非空字段
          logic-delete-value: 1									# 指定了逻辑删除的值
          logic-not-delete-value: 0								# 指定了未逻辑删除的值
    
  • 第三步,代码编写(可通过 EasyCode、MybatisPlus代码生成器生成代码)
    • 实体类

      /**
       * 用户表
       */
      @Data
      @TableName("api_student")
      public class Student {
          /**
           * 主键 ID,使用雪花算法生成
           */
          @TableId(type = IdType.ASSIGN_ID)
          private Long id;
       
          /**
           * 名称
           */
          private String name;
       
          /**
           * 年龄
           */
          private Integer age;
       
          /**
           * 性别
           */
          private String sex;
          
          /**
           * 班级id
           */
          private Integer classId;
      }
      

      相关注解:@TableId、@TableName、@TableField、@TableLogic、@Version

    • 数据访问层(Mapper)

      package com.example.demo.mapper;
      
      import com.baomidou.mybatisplus.core.mapper.BaseMapper;
      import com.example.demo.model.Student;
      import org.apache.ibatis.annotations.Mapper;
      
      @Mapper
      public interface StudentMapper extends BaseMapper<Student> {
      }
      
    • 业务逻辑层(Service)

      package com.example.demo.service;
      
      import com.baomidou.mybatisplus.extension.service.IService;
      import com.example.demo.model.Student;
      
      public interface StudentService extends IService<Student> {
      }
      
      package com.example.demo.service.impl;
      
      import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
      import com.example.demo.mapper.StudentMapper;
      import com.example.demo.model.Student;
      import com.example.demo.service.StudentService;
      import org.springframework.stereotype.Service;
      
      @Service
      public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
      }
      
    • 表现层(Controller)

      package com.example.demo.controller;
      
      
      import com.example.demo.service.StudentService;
      import jakarta.annotation.Resource;
      import org.springframework.web.bind.annotation.*;
      
      @RestController
      @RequestMapping("student")
      public class ApiUserController {
      
          @Resource
          private StudentService studentService;
      
          @GetMapping
          public Object query(@RequestParam Integer id) {
              return  studentService.getById(id);
          }
          
      }
      
  • 第四步,启动项目,通过终端访问:curl http://127.0.0.1:8080/student?id=1

可能报错:

  • java: 无法访问com.baomidou.mybatisplus.extension.repository.IRepository
    找不到com.baomidou.mybatisplus.extension.repository.IRepository的类文件

    一般是因为 IService继承的IRepository所在的包mybatis-plus-extension的版本存在版本冲突(比如项目有使用mybatis-plus-generator)(可使用Maven Helper查看是否存在版本冲突),将对应的依赖排除即可。

  • Invalid value type for attribute 'factoryBeanObjectType': java.lang.String

    springboot3更改了factoryBean方法,导致老版本的mybatis不能兼容, 所以最新的mybatis3.0.3修复了这个问题, 然而mybatisplus中还未更新

    <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
         <version>3.5.9</version>
         <exclusions>
             <exclusion>
                 <groupId>org.mybatis</groupId>
                 <artifactId>mybatis-spring</artifactId>
             </exclusion>
         </exclusions>
     </dependency>
    
     <dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis-spring</artifactId>
         <version>3.0.4</version>
     </dependency>
    
  • A component required a bean of type 'com.example.demo.mapper.Mapper' that could not be found.

    Mapper 类没找到,在启动类Application上添加 @MapperScan 注解

    @SpringBootApplication
    @MapperScan("com.example.demo.mapper")
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Main.class, args);
        }
    }
    

3、PageHelper

  • 第一步,pom.xml 导入依赖
    <dependency>
         <groupId>com.github.pagehelper</groupId>
         <artifactId>pagehelper</artifactId>
         <version>6.1.0</version>
     </dependency>
    
  • 第二步,application.yml 添加配置
    pagehelper:
      helper-dialect: mysql
      reasonable: true
      support-methods-arguments: true
    
    参数说明:
    • helper-dialect:设置数据库方言为 MySQL。这是为了生成正确的分页 SQL 语句。PageHelper 会根据这个配置来选择适合的 SQL 语法和函数。
    • reasonable:分页合理化参数。当设置为 true 时,如果 pageNum<1 会查询第一页,如果 pageNum>pages(总页数),会查询最后一页。默认值为 false,直接根据参数进行查询。
    • support-methods-arguments:支持通过 Mapper 接口方法的参数来传递分页参数。这允许你在调用 Mapper 方法时直接使用分页参数(如 pageNum 和 pageSize),而不是在 XML 映射文件中配置。若用QueryWrapper及其子类,也可不设置。
    • params:允许指定额外参数。通常这个配置不是必需的,因为 PageHelper 能够自动处理大多数情况。如果你有特殊的需求,比如需要对 count 查询进行优化,或者需要使用不同的逻辑来计算总记录数,那么你可以使用这个配置。
  • 第三步,编写代码
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        public PageInfo<User> getUsersByPage(int pageNum, int pageSize) {
            // 设置分页参数
            PageHelper.startPage(pageNum, pageSize);
    
            // 构建查询条件
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.ge("age", 18); // 示例条件:年龄大于等于18岁
    
            // 执行分页查询
            List<User> users = userMapper.selectList(queryWrapper);
    
            // 封装分页信息
            PageInfo<User> pageInfo = new PageInfo<>(users);
            return pageInfo;
        }
    }
    

关于分页插件,其实也可以用Mybatis-Plus本身自带的功能

  • 第一步,pom.xml 导入依赖
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.9</version>
    </dependency>
    
  • 第二步,添加配置文件 MybatisPlusConfig
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MybatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            return new MybatisPlusInterceptor();
        }
    }
    
  • 第三步,编写业务代码
    public Object page( @RequestBody PageVo pageVo ) {
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc(pageVo.getDesc()).orderByAsc(pageVo.getAsc());
        Page<Student> page = new Page<>(pageVo.getPage(), pageVo.getSize());
        server.page(page, queryWrapper);
        return page;
    }
    

9、资料:


网站公告

今日签到

点亮在社区的每一天
去签到