快速搭建SpringBoot3.x项目

news2024/11/16 19:50:19

快速搭建SpringBoot3.x项目

      • 写在前面
      • 一、创建项目
      • 二、配置多环境
      • 三、连接数据库查询数据
        • 3.1 新建数据库mybatisdemo并且创建sys_user表
        • 3.2 创建实体类
        • 3.2 创建Mapper接口
        • 3.3 添加mybatis.xml文件
        • 3.4 新建service 接口及实现类
        • 3.5 创建Controller
      • 四、封装统一结果返回
        • 4.1 定义 `IResultCode` 的接口
        • 4.2 定义了一个枚举类 `ResultCode`
        • 4.3 定义统一响应结构体
      • 五、定义值对象VO
        • 5.1 定义VO
        • 5.2 service 改造
        • 5.3 接口测试
      • 六、日期时间处理
      • 七、统一异常处理
        • 7.1 添加自定义异常与其他异常返回结果
        • 7.2 自定义异常
        • 7.3 全局异常处理
        • 7.4 测试异常处理
      • 八、添加系统日志
        • 8.1 常用日志框架
        • 8.2 日志常用配置
        • 8.3 日志基本使用
        • 8.4 日志高级配置
      • 九、小结

写在前面

上一小节中我们从0到1 使用Vite搭建了一个Vue3项目,并集成了Element Plus 实现了一个简单的增删改查页面。

这一篇中我们将使用IDEA快速搭建一个SpringBoot3.x的项目。

一、创建项目

1、File->new->project

新建项目

2、选择“Spring Initializr”,点击next;

Spring Initializr

3、选择spring boot版本及添加相关依赖

这一步我们需要选择springboot版本,及Dependencies信息,当然了Dependencies 不是必须选择的。可以在项目建好之后需要什么添加什么。

简要说明:我们这里选择了四个Dependencies

  • Lombok : 需要我们先安装Lombok插件,可以简化实体类书写
  • String Web:添加项目的web支持
  • MySQL Driver:我们用到MySQL数据库,所以添加MySQL相关驱动
  • MyBatis Framework:我们用到MyBatis这一ORM框架操作数据库

springboot版本

4、创建好的项目结构

项目结构

5、配置Maven

在这里配置本地Maven本地路径、Maven仓库。在本地Maven的settings.xml中会配置maven的镜像资源等信息

配置Maven

6、 下载相关依赖

在这里我们下载之前配置好的依赖,一般项目创建后会默认下载

下载依赖

二、配置多环境

在实际开发中,我们一般都会有好几套运行环境。比如①开发环境 ②测试环境 ③ 生产环境等等

我们不可能每次都去修改一个配置文件,这就显得很麻烦。下面我们主要说一说怎么配置多环境

① 修改application.properties 配置文件

idea创建的springboot项目,默认的配置文件是application.properties。我们这里将application.properties修改成application.yml。

为什么这么修改呢?因为yml文件配置起来比较方便,可以省略好多冗余内容,当然了你不改也是没啥问题的。

修改后的applicatio.yml文件如下,通过active:属性来切换环境

spring:
  application:
    name: springbootdemo
  profiles:
    active: dev

②添加开发环境配置

新建application-dev.yml 文件,在这里我们就可以配置开发环境下的端口,数据库连接等信息,具体内容如下

  • server.port 属性,指定应用程序在服务器上监听的端口号。这里设置为8080
  • spring.datasource 属性,配置应用程序与数据库的连接
    • driver-class-name 指定数据库驱动程序的类名
    • url 指定数据库的连接地址,这里是本地MySQL数据库的地址和端口号以及数据库名称
    • usernamepassword 分别指定连接数据库所需的用户名和密码
  • spring.mybatis.mapper-locations 属性,指定MyBatis映射器XML文件的位置。这里配置为 classpath:mapper/*.xml ,表示映射器文件位于classpath下的mapper目录中
server:
  port: 8080    # 配置端口为8080

spring:
  datasource:
    driver-class-name:  com.mysql.jdbc.Driver   
    url: jdbc:mysql://localhost:3308/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
    mapper-locations: classpath:mapper/*.xml

③ 添加生产环境配置

新建application-prod.yml文件,这里配置的是生产环境。具体内容如下,配置一样的,只是各种换成了生产的

server:
  port: 8989

spring:
  datasource:
    driver-class-name:  com.mysql.jdbc.Driver
    url: jdbc:mysql://www.xiezhrspace.cn:3308/mybatisdemo?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
    mapper-locations: classpath:mapper/*.xml

以上配置好之后,我们就可以启动springboot项目

启动项目

浏览器输入:http://localhost:8080 后出现如下内容,说明项目启动成功

项目启动成功

三、连接数据库查询数据

通过之前的步骤,我们的springboot项目已经可以正常运行起来了,接下来我们就从数据库中获取数据并通过json格式返回前台

3.1 新建数据库mybatisdemo并且创建sys_user表

DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
  `nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户昵称',
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户密码',
  `sex` enum('1','2') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户性别',
  `birthday` date NULL DEFAULT NULL COMMENT '用户生日',
  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户邮箱',
  `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户电话',
  `addr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户地址',
  `stop_flag` enum('1','0') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户启用标志',
  `create_time` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '用户创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '用户更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `sys_user` VALUES (1, 'xiezhr', '程序员小凡', '12345678', '1', '1999-09-19', 'xiezhr@qq.com', '13288888888', '云南省昆明市', '0', '2023-09-04 21:08:32', NULL);
INSERT INTO `sys_user` VALUES (2, 'xiaoqi', '程序员晓柒', '123456', '1', '2020-10-04', 'xiaoqi@163.com', '13288888888', '云南文山', '0', '2023-09-04 21:09:42', NULL);
INSERT INTO `sys_user` VALUES (3, 'xiaodeng', '财务小邓', '123456', '2', '2019-09-04', 'xiaodeng@qq.com', '13588888888', '云南文山', '0', '2023-09-04 21:10:43', NULL);

表结构

3.2 创建实体类

创建与表结构一致的实体类SysUser

@Data 是Lombok依赖的注解,使用它我们就不用写get、set方法了

@Data
public class SysUser implements Serializable {
    private static final long serialVersionUID = 526934774547561999L;
    /**
     * 主键id
     */
    private Integer id;
    /**
     * 用户名
     */
    private String username;
    /**
     * 用户昵称
     */
    private String nickname;
    /**
     * 用户密码
     */
    private String password;
    /**
     * 用户性别
     */
    private String sex;
    /**
     * 用户生日
     */
    private Date birthday;
    /**
     * 用户邮箱
     */
    private String email;
    /**
     * 用户电话
     */
    private String phone;
    /**
     * 用户地址
     */
    private String addr;
    /**
     * 用户启用标志
     */
    private String stopFlag;
    /**
     * 用户创建时间
     */
    private Date createTime;
    /**
     * 用户更新时间
     */
    private Date updateTime;

}

3.2 创建Mapper接口

数据访问对象,是MVC架构中负责与数据库进行交互的组件。它封装了数据库的访问操作,提供给Service层调用。Dao层通常包含一系列方法,用于对数据库进行增删改查操作,以及与数据库的连接、事务管理等。

@Mapper 表示这个接口是一个MyBatis的Mapper接口,用于定义数据库操作的方法

@Mapper
public interface SysUserMapper {

    List<SysUser> querySyserList();
}

3.3 添加mybatis.xml文件

MyBatis的映射文件(mapper),用于操作数据库中的sys_user表。其中定义了一个resultMap用于映射查询结果到SysUser对象,还定义了一个select语句用于查询sys_user表中的所有用户信息。 id=“querySyserList” 必须与mapper接口中方法名一致

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiezhr.mapper.SysUserMapper">
    <resultMap type="com.xiezhr.model.entity.SysUser" id="SysUserMap">
        <result property="id" column="id" jdbcType="INTEGER"/>
        <result property="username" column="username" jdbcType="VARCHAR"/>
        <result property="nickname" column="nickname" jdbcType="VARCHAR"/>
        <result property="password" column="password" jdbcType="VARCHAR"/>
        <result property="sex" column="sex" jdbcType="VARCHAR"/>
        <result property="birthday" column="birthday" jdbcType="TIMESTAMP"/>
        <result property="email" column="email" jdbcType="VARCHAR"/>
        <result property="phone" column="phone" jdbcType="VARCHAR"/>
        <result property="addr" column="addr" jdbcType="VARCHAR"/>
        <result property="stopFlag" column="stop_flag" jdbcType="VARCHAR"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
        <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <!--查询所有用户信息-->
    <select id="querySyserList" resultMap="SysUserMap">
        select * from sys_user
    </select>
</mapper>

3.4 新建service 接口及实现类

Service是MVC架构中负责处理业务逻辑的组件。它封装了业务逻辑的实现细节,提供给Controller调用。Service层通常包含一系列方法,用于处理各种业务需求,如数据处理、事务管理、业务规则校验等。

SysUserService

public interface SysUserService {
    List<SysUser> querySyserList();
}

SysUserServiceImpl

  • @Service :标识这个类是服务层(Service)的组件,用于实现业务逻辑的封装和管理。以便Spring容器能够扫描并将其实例化为一个Bean,并将其纳入到Spring的管理中。通过@Service注解,可以方便地进行依赖注入、事务管理等操作
  • @Resource :标识一个类或对象需要被注入到另一个类中,用于实现依赖注入
@Service
public class SysUserServiceImpl implements SysUserService {

   @Resource
    private SysUserMapper  userMapper;
    @Override
    public List<SysUser> querySyserList() {
        return userMapper.querySyserList();
    }
}

3.5 创建Controller

Controller是MVC架构中负责接收用户请求并处理的组件。它接收来自用户的请求,并根据请求的内容调用相应的Service方法进行业务处理,然后返回结果给用户。Controller通常负责路由请求、参数验证、调用Service等操作

SysUserController

  • @RestController:用于标识一个类是RESTful风格的控制器,结合了@Controller和@ResponseBody注解的功能,用于处理HTTP请求并返回RESTful风格的响应
  • @RequestMapping:用于映射HTTP请求到控制器的处理方法,指定请求的URL路径和请求方法
  • @Autowired:用于自动装配依赖对象
@RestController
@RequestMapping("/sysUser")
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    @RequestMapping(value = "/querySysUser",method = RequestMethod.GET)
    public List<SysUser> querySysUser(){
       return sysUserService.querySyserList();
    }
}

到此我们三大组件的代码都写完了,接下来我们来看看我们写好的接口

浏览器地址栏输入:http://localhost:8080/sysUser/querySysUser

json数据返回

四、封装统一结果返回

为了保证所有接口返回的数据格式一致,减少重复代码编写。我们将对返回结果进行统一处理。

具体返回结果格式如下

{
  "code": 200, // 状态码,表示请求的处理结果
  "message": "请求成功", // 状态消息,对请求结果的简要描述
  "data": { // 数据对象,用于存储具体的返回数据
    "key1": "value1",
    "key2": "value2"
  }
}
  • code :表示请求的处理结果,一般采用HTTP状态码或自定义的业务状态码
  • message :对请求结果的简要描述,通常是一个字符串
  • data :用于存储具体的返回数据,可以是一个对象、数组或其他类型的数据

4.1 定义 IResultCode 的接口

它位于 com.xiezhr.common.result 包中,可以由不同的类来实现,实现一致且统一的结果码和消息的处理和返回

package com.xiezhr.common.result;

public interface IResultCode {
    String getCode();
    String getMsg();
}
  • getCode() : 这个方法返回一个 String 类型的结果码
  • getMsg() : 这个方法返回一个 String 类型的结果消息

4.2 定义了一个枚举类 ResultCode

定义了一个枚举类 ResultCode ,它实现了 IResultCode 接口,并包含了一些常见的响应码和对应的消息。

@AllArgsConstructor
@NoArgsConstructor
public enum ResultCode implements IResultCode, Serializable {
    SUCCESS("200","成功"),
    NOT_FOUND("404","未找到"),
    INTERNAL_SERVER_ERROR("500","服务器内部错误"),    
    ;
    private String code;
    private String msg;
    @Override
    public String getCode() {
        return code;
    }

    @Override
    public String getMsg() {
        return msg;
    }
}

定义系统中常见的响应码和对应的消息,用于表示不同的业务场景或操作的执行结果

每个枚举常量都包含一个 code 和一个 msg ,分别表示响应码和消息内容

枚举常量包括了一些常见的响应码,如 SUCCESS 表示成功, INTERNAL_SERVER_ERROR 服务器内部错误, NOT_FOUND 表示未找到

4.3 定义统一响应结构体

定义了一个名为 Result 的类,用于表示统一的响应结构体

@Data
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    private String code;
    private String msg;
    private T data;

    public static<T>  Result<T> success() {
        return success(null);
    }

    public static<T>  Result<T> success(T data) {
        Result result = new Result<>();
        result.setCode(ResultCode.SUCCESS.getCode());
        result.setMsg(ResultCode.SUCCESS.getMsg());
        result.setData(data);
        return result;
    }

    public static <T> Result<T> error(String msg) {
        Result<T> result = new Result<>();
        result.setCode(ResultCode.ERROR.getCode());
        result.setMsg(ResultCode.ERROR.getMsg());
        return result;
    }
}

到此,统一响应返回我们已经封装好了,我们来改造一下Controller中的代码看看效果

SysUserController未改之前

@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)
public List<SysUser> querySysUser(){
    return sysUserService.querySyserList();
}

SysUserController修改之后

@RequestMapping(value = "/querySysUser",method = RequestMethod.GET)
public Result querySysUser(){
    return Result.success(sysUserService.querySyserList());
}

前端返回结果

统一响应体返回

五、定义值对象VO

从上面的返回结果,我们会发现将密码等敏感信息返回到了前端,这是非常不可取的

这时,我们就需要根据前端的需求,灵活地选择需要展示的数据字段

如果你还傻傻分不清PO BO VO DTO POJO DAO DO 这些概念,可以看看知乎的这篇文章,个人觉得还是说的比较清楚的了

https://www.zhihu.com/question/39651928/answer/2490565983

image-20230914224644771

5.1 定义VO

定义一个需要返回前端的VO

@Data
public class UserInfoVO {

    /**
     * 用户名
     */
    private String username;
    /**
     * 用户昵称
     */
    private String nickname;

    /**
     * 用户性别
     */
    private String sex;
    /**
     * 用户生日
     */
    private Date birthday;
    /**
     * 用户邮箱
     */
    private String email;
    /**
     * 用户电话
     */
    private String phone;
    /**
     * 用户地址
     */
    private String addr;
}

5.2 service 改造

interface SysUserService 改造前

public interface SysUserService {
    List<SysUser> querySyserList();
}

interface SysUserService 改造后

public interface SysUserService {
    List<UserInfoVO> querySyserList();
}

SysUserServiceImpl 改造前

@Service
public class SysUserServiceImpl implements SysUserService {

   @Resource
    private SysUserMapper  userMapper;
    @Override
    public List<SysUser> querySyserList() {
        return userMapper.querySyserList();
    }
}

SysUserServiceImpl改造后

@Service
public class SysUserServiceImpl implements SysUserService {

   @Resource
    private SysUserMapper  userMapper;
    @Override
    public List<UserInfoVO> querySyserList() {
        List<UserInfoVO> userInfoVOList = new ArrayList<UserInfoVO>();

        List<SysUser> sysUserList= userMapper.querySyserList();

        for (SysUser sysUser : sysUserList) {
            UserInfoVO userInfoVO = new UserInfoVO();
            BeanUtils.copyProperties(sysUser,userInfoVO);
            userInfoVOList.add(userInfoVO);
        }

        return userInfoVOList;
    }
}

service 返回由原来的SysUser -->变成UserInfoVO

5.3 接口测试

浏览器地址栏输入:http://localhost:8080/sysUser/querySysUser

这时返回前端的json数据中已经没有密码了

接口测试

六、日期时间处理

认真看文章的小伙伴可能已经发现了,前面返回的json数据中,日期是 “birthday”: “1999-09-18T16:00:00.000+00:00” 这样的

这样的日期可读性非常差,有没有什么方法可以格式化下日期呢?

其实呢,日期格式化非常简单,我们只需要在之前定义好的UserInfoVO 的日期属性上加上一个注解即可

import com.fasterxml.jackson.annotation.JsonFormat;

@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthday;

我们来测试一下

通过格式化的日期就是我们习惯的日期格式了

日期显示

七、统一异常处理

日常开发中,我们处理异常一般都会用到try-catchthrowthrows 的方式抛出异常。

这种方式不仅仅程序员处理麻烦,对用户来说也不太友好

我们都希望不用写过多的重复代码处理异常,又能提升用户体验。

这时候全局异常处理就显得很便捷很重要了

小伙伴们如果对异常还不熟悉的可以看看这篇文章

https://blog.csdn.net/rong09_13/article/details/128090748

Springboot对于异常的处理也做了不错的支持,它提供两个注解供我们使用

  • @ControllerAdvice注解 :用来开启全局的异常捕获
  • @ExceptionHandler注解:说明捕获哪些异常,对那些异常进行处理
@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(value =Exception.class)
	public String exceptionHandler(Exception e){
		System.out.println("发生了一个异常"+e);
       	return e.getMessage();
    }
}

7.1 添加自定义异常与其他异常返回结果

我们在Result 类中添加如下两个方法来处理自定义异常和其他异常返回结果

//自定义异常返回的结果
public static <T> Result<T> bussinessErr(BusinessException e) {
    Result<T> result = new Result<>();
    result.setCode(e.getErrorCode());
    result.setMsg(e.getErrorMsg());
    result.setData(null);
    return result;
}
//其他异常处理方法返回的结果
public static <T> Result<T> otherErr(ResultCode resultCode) {
    Result<T> result = new Result<>();
    result.setCode(resultCode.getCode());
    result.setMsg(resultCode.getMsg());
    result.setData(null);
    return result;
}

7.2 自定义异常

新建com.xiezhr.exception包,并自定义异常类

public class BusinessException  extends RuntimeException{
    private String errorCode;
    private String errorMsg;

    public BusinessException() {

    }

    public BusinessException(String errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

}

7.3 全局异常处理

我们自定义一个全局异常处理类,来处理各种异常,包括自己定义的异常内部异常

这样可以简化不少代码,不用自己对每个异常都使用try,catch的方式来实现

我们在com.xiezhr.exception 包下面添加全局异常处理类GlobalExceptionHandler

@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 处理自定义异常
     *
     */
    @ExceptionHandler(value = BusinessException.class)
    @ResponseBody
    public<T> Result<T> bizExceptionHandler(BusinessException e) {
        return Result.bussinessErr(e);
    }

    /**
     * 处理其他异常
     *
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result exceptionHandler(Exception e) {
        return Result.otherErr(ResultCode.INTERNAL_SERVER_ERROR);
    }

}

7.4 测试异常处理

我们在SysUserController 中添加如下代码来测试下异常,看看能不能捕获到

@RequestMapping("/getBusinessException")
public Result DeException(){
    throw new BusinessException("400","我出错了");
}
@RequestMapping("/getException")
public Result Exception(){
    Result result = new Result();
    int a=1/0;
    return result;
}

自定义异常捕获返回

其他异常捕获与返回

八、添加系统日志

日志记录应用程序的运行状态,通过日志开发者可以更好的了解应用程序的运行情况

当系统出现bug时,也能通过日志快速定位问题和解决问题

8.1 常用日志框架

① 常用日志框架

JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j…

② 日志框架之间的关系

日志框架的设计类似于JDBC-数据库驱动的设计,提供了统一的接口抽象层,然后再由各个数据库厂商去实现它,

从而实现连接不同数据库(Oracle、MySQL、PostgreSQL、MongoD…)

日志门面(日志抽象层)日志实现
JCL
SLF4j
jboss-logging
Log4j
JUL(java.util.logging)
Log4j2
Logback

我们需要需要选择一个日志门面 和日志实现

springboot 默认选用SLF4jLogback

8.2 日志常用配置

① 日志输出分析

默认日志输出

  • 日期时间:精确到毫秒
  • 日志级别:TRACE|DEBUG|INFO|WARN|ERR
  • 进程ID:60236
  • 分隔符:默认以—进行分割
  • 线程名:由中括号括起来,如[ main]
  • Logger名: 一般使用类名
  • 日志内容

② 日志级别

日志级别由低到高如下

TRACE < DEBUG< INFO< WARN < ERROR

如果设置为 WARN ,则低于 WARN 的信息都不会输出
Spring Boot中默认配置ERRORWARNINFO级别的日志输出到控制台

怎么调整日志级别呢?

  • 在application.properties或application.yml配置文件中 调整
logging.level.root=DEBUG
  • 在运行Spring Boot应用程序时,通过命令行参数来设置日志级别
java -jar your-application.jar --logging.level.root=DEBUG

③ 日志写到文件中

需在application.properties或application.yml配置文件中设置logging.filelogging.path属性

  • logging.file,设置文件,可以是绝对路径,也可以是相对路径。如:logging.file=my.log
  • logging.path,设置目录,会在该目录下创建spring.log文件,并写入日志内容,如:logging.path=/var/log

如果只配置 logging.file,会在项目的当前路径下生成一个 xxx.log 日志文件。
如果只配置 logging.path,在 /var/log文件夹生成一个日志文件为 spring.log

:二者不能同时使用,如若同时使用,则只有logging.file生效

默认情况下,日志文件的大小达到10MB时会切分一次,产生新的日志文件,默认级别为:ERROR、WARN、INFO

8.3 日志基本使用

①第一种方法

我们参照官网:https://www.slf4j.org/manual.html 的例子即可

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {

  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

②第二种方法

第一种方法中,每次使用都要创建了一个名为 logger 的Logger对象,使用起来有点繁琐。这里我们引入注解方式实现

使用注解@Slf4j 需要安装lombok插件

可以用{} 占位符来拼接字符串,而不需要使用+来连接字符串。

@SpringBootTest
@Slf4j
class SpringbootdemoApplicationTests {

    @Test
    void testLog() {
        String name = "xiezhr";
        int age = 20;
        log.info("name:{},age:{}", name, age);
    }

}

日志输出如下:

2023-09-16T12:27:57.014+08:00  INFO 53792 --- [           main] c.x.s.SpringbootdemoApplicationTests     : name:xiezhr,age:20

8.4 日志高级配置

前面几节说的都是springboot基本日志配置,如果这些都不能满足我们的需求,我们就需要添加logback-spring.xml 官方推荐的配置文件进行配置

logback-spring.xml 中 配置了两个 分别是①输出到控制台②将日志写到文件中 并且使用 指定开发/生产环境配置

大家可以参考下面配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<configuration>

    <!-- SpringBoot默认logback的配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
    <property name="LOG_HOME" value="/logs/${APP_NAME}"/>

    <!--1. 输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!-- <withJansi>true</withJansi>-->
        <!--此日志appender是为开发使用,只配置最低级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 2. 输出到文件  -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 当前记录的日志文档完整路径 -->
        <file>${LOG_HOME}/log.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 临界值过滤器,输出大于INFO级别日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
    </appender>

    <!-- 开发环境输出至控制台 -->
    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
        </root>
    </springProfile>

    <!-- 生产环境输出至文件 -->
    <springProfile name="prod">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
        </root>
    </springProfile>
</configuration>

看到这,大家如果对日志还不太清楚的可以看看下面雷神讲的视频,

https://www.bilibili.com/video/BV1sb411H7Po

最终完整项目结构如下

完成项目结构

九、小结

本篇文章我们手把手创建了一个SpringBoot项目,并整合Mybatis实现了将数据库中数据通过json返回前端。

对返回json结果进行统一封装,异常的统一处理,日期时间的处理、开发/生产环境配置以及系统日志配置。

以上都是基于日常工作开发中的实际案例,希望对你有所帮助。

本期内容到此九结束了,希望对你有所帮助。我们下期再见~ (●’◡’●)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1018896.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算平均值

任务描述 编程实现&#xff1a;编写程序实现如下功能&#xff1a;通过键盘&#xff0c;用指针输入10个元素的值&#xff0c;再通过指针计算各元素的平均值&#xff0c;输出平均值。 测试说明 平台会对你编写的代码进行测试&#xff1a; 测试样例1&#xff1a; 测试输入&…

applicationId和packageName 的异同

关于作者&#xff1a; CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP&#xff0c;带领广告团队广告单日营收超千万。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业化变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读…

安卓机型固件系统分区的基础组成 手机启动规律初步常识 各分区的基本含义与说明

此贴为基本常识。感兴趣的友友可以了解手机的启动顺序和各模式的基本操作与意义。另外了解手机系统分区各文件夹的含义 分区说明对应贴&#xff1a;安卓机型固件中分区对应说明 手机开机基本启动顺序 当我们按下手机开机键的时候。基本的启动顺序为 注意&#xff1a;该结构图…

基于matlab实现的多普勒频移海底混响点散射模型程序

完整程序&#xff1a; %有多普勒频移的海底混响点散射模型 clear all; close all; clc H100; %海水深度 D50; %合置声纳深度 c1500; %声速 azmpi/6; %水平方位角 u-27; %垂直散射系数 v20; %声…

Linux基础指令(四)

目录 前言1. find & which 指令1.1 find1.2 which1.3 alias1.4 where 2、grep 指令3、xargs 指令结语&#xff1a; 前言 欢迎各位伙伴来到学习 Linux 指令的 第四天&#xff01;&#xff01;&#xff01; 在上一篇文章 Linux基本指令(三) 当中&#xff0c;我们学会了通过…

Python爬虫-某网酒店评论数据

前言 本文是该专栏的第6篇,后面会持续分享python爬虫案例干货,记得关注。 本文以某网的酒店数据为例,采集对应酒店的评论数据。具体思路和方法跟着笔者直接往下看正文详细内容。(附带完整代码) 注意:本文的案例“数据集”,选用的是本专栏上一篇“Python爬虫-某网酒店数…

【JAVA-Day19】深入探讨 Java 泛型和枚举的精髓

深入探讨 Java 泛型和枚举的精髓 深入探讨 Java 泛型和枚举的精髓摘要引言一、Java 泛型二、Java 枚举三、泛型和枚举的区别和使用场景区别泛型和枚举的使用场景泛型的使用场景枚举的使用场景 四、总结参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&am…

后端中间件安装与启动(Redis、Nginx、Nacos、Kafka)

后端中间件安装与启动 RedisNginxNacosKafka Redis 1.打开cmd终端&#xff0c;进入redis文件目录 2.输入redis-server.exe redis.windows.conf即可启动&#xff0c;不能关闭cmd窗口 &#xff08;端口配置方式&#xff1a;redis目录下的redis.windows.conf配置文件&#xff0c;…

线程池(重点)

1.线程池的三大方法 package com.kuang.pool;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; //Executors工具类 三大方法 //使用线程池&#xff0c;创建线程 public class Demo01 {public static void main(String[] args) { // …

RHCSA_Linux 从命令行管理文件

目录 一、文件命令规范&#xff1a; 二、创建链接文件 1、创建软链接文件 2、创建硬链接文件 三、目录操作命令 1、创建目录 -- mkdir 2、统计目录及文件的空间占用情况 -- du 3、删除目录文件 四、创建、删除普通文件 1、创建普通文件 2、删除普通文件 五、数据流和…

春秋云镜 CVE-2010-1870/CVE-2013-1965

春秋云镜 CVE-2010-1870 S2-005 远程代码执行漏洞 靶标介绍 struts2将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象&#xff0c;struts框架通过过滤#字符防止安全问题&#xff0c;然而通过unicode编码(u0023)或8漏洞(43)即绕过…

【项目经验】:elementui多选表格默认选中

一.需求 在页面刚打开就默认选中指定项。 二.方法Table Methods toggleRowSelection用于多选表格&#xff0c;切换某一行的选中状态&#xff0c;如果使用了第二个参数&#xff0c;则是设置这一行选中与否&#xff08;selected 为 true 则选中&#xff09;row, selected 详细…

Docker部署单点Elasticsearch与Kibana

一 、 创建网络 因为需要部署kibana容器&#xff0c;因此需要让es和kibana容器互联。这里创建一个网络&#xff1a; docker network create es-net # 创建一个网络名称为:es-net 二 、拉取并加载镜像 方式一 docker pull elasticsearch:7.12.1 版本为elasticsearch的7…

线性代数基础-矩阵

八、矩阵的基础概念 1.矩阵 我们忘掉之前行列式的一切&#xff0c;列一种全新的数表&#xff0c;虽然长得很像&#xff0c;但是大不相同&#xff0c;首先一个区别就是矩阵不能展开成一个值&#xff0c;这里不讨论矩阵的空间意义 { a 11 x 1 a 12 x 2 a 13 x 3 . . . a 1…

CH573-09-BLE蓝牙安卓应用二次开发——RISC-V内核BLE MCU快速开发教程

一、基础工程搭建 在上一章最后一讲的BLE蓝牙例程中&#xff0c;我们使用了沁恒官方的BLE调试助手完成数据发送&#xff0c;接下来我们使用Android Studio完成一款简易的BLE调试助手。 1、参考文章 我这里参考了CSDN中的一位博主“摸爬滚打的程序媛”的文章以及对应文章中的…

2023最新玩客云刷机armbian,部署docker并配置各种常用容器镜像

#以下安装从基于 rootonecloud:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.2 LTS Release: 22.04 Codename: jammy刷机开始 &#xff08;以下刷机教程部分资料来源于&#xff1a;玩客云刷ARMBIAN系统…

linux查看进程对应的线程(数)

首先&#xff0c;top或ps查看进程列表&#xff0c;确定要查看的进程pid&#xff0c;如下面40698 查看进程的线程情况 查看进程&#xff1a;top -p 40698 查看线程&#xff1a;top -p 40698 -d 3 -H 其中-d是刷新频率 可看到此进程共211个线程&#xff0c;运行中的是211个。…

C++基础-类和对象(下)

文章目录 前言一、构造深入1.初始化列表2.隐式类型转换1.隐式类型转换2.explicit 3.委托构造 二、类的静态成员1.静态成员声明2.静态成员定义3.静态成员特性 三、重载运算符和类型转化1.关系及算数运算符重载2.递增递减运算符重载及如何区分3.赋值运算符重载4.重载输入输出运算…

【基础篇】五、基于SpringBoot来整合SSM的案例(上)

文章目录 0、创建模块1、实体类的快速开发Lombok2、数据层开发&#xff08;CRUD&#xff09;3、分页4、条件查询5、业务层的标准开发6、业务层的快速开发&#xff08;基于MyBatisPlus&#xff09;7、表现层开发 接下来在SpringBoot下&#xff0c;把Spring、SpringMVC、MyBatis整…

项目进度管理(3-3)PERT计划评审技术详解

1 计划评审技术起源 PERT&#xff08;Program Evaluation and Review Technique&#xff0c;项目评估和审查技术&#xff09;的起源可以追溯到20世纪50年代&#xff0c;与美国国防部和美国海军的项目管理有关。 PERT的发展始于20世纪50年代初&#xff0c;当时美国国防部正面临…