SpringBoot_日志

本文详细介绍了SpringBoot中日志的配置与使用方法,包括SLF4J的使用方式与原理,如何统一日志,SpringBoot日志的默认配置及如何修改,指定日志配置,以及如何在SpringBoot中切换日志框架。

SLF4J

SLF4J使用方式:

在开发过程中,我们不应该直接调用日志的实现类,而是应该调用日志抽象层里面的方法;

示例:


 // 导入 slf4j的jar和 logback 的实现jar
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
	public static void main(String[] args) {

		// 调用LoggerFactory的 getLogger(记录器) 去记录 HelloWorld类的信息
		Logger logger = LoggerFactory.getLogger(HelloWorld.class);
		//进行日志记录
		logger.info("Hello World");
	}
}


SLF4J使用原理:

SLF4J 绑定 logback : 应用程序 面向 SLF4J 进行编程,调用它的方法,在程序里面导入日志的 logback 实现
类jar包,由logback 的 jar包进行日志记录;

SLF4J 绑定 log4j : 应用程序 依旧面向 SLF4J 进行编程,依旧调用它的方法,然后在中间导入一个适配层(相当于向上实现了 SLF4J 的具体方法,向下真正进行日志记录的时候又调用 log4j 的 方法) ,在程序里面导入日志的 log4j 的jar包,由log4j 的 jar包进行日志记录;

在这里插入图片描述

注意点: 使用 slf4j 框架以后,配置文件还是做成日志实现框架本身的配置文件;


SLF4J统一日志:

让系统中所有的日志都统一到 SLF4J 中

1,将系统中其他日志框架先排除出去;

2,用中间jar包来替换原有的日志框架;

3,导入SLF4J 的对应其他实现类jar包 ;

日志适配图:
在这里插入图片描述


SpringBoot 日志

SpringBoot 日志关系:

在 SpringBoot 的 web 项目 pom.xml 中,默认导入了 spring-boot-starter-web 依赖:

	<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

 

spring-boot-starter-web下包含 spring-boot-starter-logging ,SpringBoot 采用它来做日志功能:

	<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-logging</artifactId>
       <version>2.2.5.RELEASE</version>
       <scope>compile</scope>
    </dependency>

SpringBoot 的日志底层依赖关系:
在这里插入图片描述


SpringBoot 如果引入其他框架,要把这个框架的默认日志依赖移除掉:

示例:SpringBoot 底层是Spring,Spring框架用的日志依赖是commons-logging;

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring‐core</artifactId>
	<exclusions>
		<exclusion>
			<groupId>commons‐logging</groupId>
			<artifactId>commons‐logging</artifactId>
		</exclusion>
	</exclusions>
	</dependency>

注意点: SpringBoot 2.0及以上版本没有这样的写法;

总结:
SpringBoot 能自动适配所有的日志;
SpringBoot 底层使用 slf4 j+ logback 的方式记录日志;
SpringBoot 引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可;


SpringBoot 日志使用:

SpringBoot 日志默认配置 :

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBoot03LoggingApplicationTests {

    //记录器
    Logger logger = LoggerFactory.getLogger(getClass());
    @Test
    public void contextLoads() {

        /**
         * 日志的级别:
         * 由低到高   trace < debug < info < warn < error
         * 可以调整输出的日志级别;日志就只会在这个级别及以后的高级别生效
         * SpringBoot默认给我们使用的是info级别的,没有指定级别的就用SpringBoot默认规定的级别;
         */

        logger.trace("这是trace日志...");
        logger.debug("这是debug日志...");

        logger.info("这是info日志...");
        logger.warn("这是warn日志...");
        logger.error("这是error日志...");

    }

}

SpringBoot 修改日志默认配置:

//调整项目下 com.yp 目录下日志级别为 debug 级别 
	logging.level.com.yp=debug 
	
//不指定路径:在当前项目下生成 myspringboot.log 日志
//指定完整的路径:在对应路径下生成 myspringboot.log 日志
 	logging.file=E:/myspringboot.log

//在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
	logging.path=/spring/log

//在控制台输出的日志的格式
	logging.pattern.console=%d{yyyy‐MM‐dd} [%thread] %5level %logger{50}%msg%n

//指定文件中日志输出的格式
	logging.pattern.file=%d{yyyy‐MM‐dd} === [%thread] === %5level === %logger{50} ==== %msg%n

日志输出格式说明:


  * %d: 表示日期时间
  * %thread: 表示线程
  * %‐5level:表示级别从左显示5个字符宽度
  * %logger{50}:表示logger名字最长50个字符,否则按照句点分割
  * %msg:表示日志消息
  * %n:表示换行符
  

logging.file 和 logging.path 比较:

logging.filelogging.path示例描述
(none)(none)只在控制台输出
指定文件名(none)myspringboot.log输出日志到 myspringboot.log 文件中
(none)指定目录/my输出到指定目录下的默认文件 spring.log 中

SpringBoot 指定日志配置:

给类路径下放上每个日志框架自己的配置文件即可,这样 SpringBoot 就不使用默认配置;

Logging SystemCustomization
Logbacklogback-spring.xml , logback-spring.groovy , logback.xml or logback.groovy
Log4j2log4j2-spring.xml or log4j2.xml
JDK (Java UtilLogging)logging.properties

注意点:

*logback.xml:*直接就被日志框架识别了;但是不能使用 SpringBoot 的高级 Profile 功能,如果使用 profile功能,会有以下错误 :

no applicable action for [springProfile]

*logback-spring.xml:*日志框架就不会直接加载日志的配置项,由 SpringBoot 解析日志配置,可以使用SpringBoot 的高级 Profile 功能;

<springProfile name="staging">
	<!‐‐ configuration to be enabled when the "staging" profile is active ‐‐>
	<!‐‐可以指定某段配置只在某个环境下生效 ‐‐>
</springProfile>
SpringBoot 切换日志框架:

可以按照 SLF4J 的日志适配图,进行相关的切换;

slf4j + log4j 的方式;


<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring‐boot‐starter‐web</artifactId>
	<exclusions>
		<exclusion>
			<artifactId>logback‐classic</artifactId>
			<groupId>ch.qos.logback</groupId>
		</exclusion>
		<exclusion>
			<artifactId>log4j‐over‐slf4j</artifactId>
			<groupId>org.slf4j</groupId>
		</exclusion>
	</exclusions>
</dependency>

<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j‐log4j12</artifactId>
</dependency>


log4j2 的方式;


<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring‐boot‐starter‐web</artifactId>
	<exclusions>
		<exclusion>
			<artifactId>spring‐boot‐starter‐logging</artifactId>
			<groupId>org.springframework.boot</groupId>
		</exclusion>
	</exclusions>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring‐boot‐starter‐log4j2</artifactId>
</dependency>

<think>好的,用户想了解SQL外连接的区别,也就是left join、right join、inner join和outer join的不同之处。首先,我需要回忆一下这些连接的基本定义和用法,确保自己理解正确。 根据引用[3],inner join是等值连接,只返回两个表中匹配的行。而left join会返回表的所有记录,加上表中匹配的部分,如果不匹配,表的部分会用NULL填充。right join则相反,返回表的所有记录和表匹配的部分。outer join分为left outer join和right outer join,其实就是left join和right join的另一种写法,不过有时候outer join可能指full outer join,但引用[3]提到在常规使用中,开发者可能较少直接写outer join,而用left或right代替。 用户提供的引用中有一些需要整合的地方。比如引用[1]指出inner join等同于join,left join等同于left outer join,这说明在语法上这些关键字可以互换使用。而引用[2]提到outer join在ABAP中的实现主要是通过left或right join,这可能让用户混淆outer join的具体表现。需要明确说明outer join通常指的是left或right outer join,而full outer join可能不被所有数据库支持,比如MySQL不支持,但其他如SQL Server支持。 接下来需要结构清晰地解释每个连接类型,最好用例子或表格来说明。比如,inner join只保留匹配的行,left join保留表所有行,right保留表所有行,full outer join保留所有行,不匹配的部分用NULL填充。但根据引用[3]和引用[4],可能用户提到的outer join更多指left或right,而full outer join可能需要单独说明。 另外,用户可能在实际应用中遇到如何选择连接类型的问题,比如什么时候用left join,什么时候用inner join。这时候可能需要举例说明,比如需要包含所有订单,即使没有客户信息,就用left join;如果只需要有客户信息的订单,就用inner join。 还需要注意不同数据库对语法的支持情况,比如HIVE的优化可能不同,但用户的问题集中在区别上,暂时不需要深入优化部分。不过引用[1]提到了HIVE join优化,如果用户后续提问可以提及,但当前问题不需要。 最后,生成相关问题时要考虑用户可能的进一步疑问,比如性能差异、实际应用场景、如何选择连接类型,以及具体数据库的支持情况。确保问题能够引导用户深入理解。</think>### SQL连接类型解析 #### 1. **INNER JOIN内连接)** - **定义**:仅返回两个表中**匹配条件**的行。 - **特点**:若表或表中存在不匹配的行,则会被过滤掉。 - **语法示例**: ```sql SELECT * FROM TableA INNER JOIN TableB ON TableA.key = TableB.key; ``` - **应用场景**:需同时满足两表关联条件的精确查询,例如查询“有订单记录的客户”[^3]。 #### 2. **LEFT JOIN外连接)** - **定义**:返回表**所有行**,表仅返回匹配的行;若表无匹配,则以`NULL`填充。 - **特点**:**表为主表**,表为从表。 - **语法示例**: ```sql SELECT * FROM TableA LEFT JOIN TableB ON TableA.key = TableB.key; ``` - **应用场景**:需保留表全部数据,例如“查询所有客户的订单(包括未下单客户)”[^2][^3]。 #### 3. **RIGHT JOIN外连接)** - **定义**:返回表**所有行**,表仅返回匹配的行;若表无匹配,则以`NULL`填充。 - **特点**:**表为主表**,表为从表。 - **语法示例**: ```sql SELECT * FROM TableA RIGHT JOIN TableB ON TableA.key = TableB.key; ``` - **应用场景**:需保留表全部数据,例如“查询所有产品的订单(包括未售出产品)”[^3][^4]。 #### 4. **OUTER JOIN外连接)** - **定义**:分为`LEFT OUTER JOIN`和`RIGHT OUTER JOIN`,分别等价于`LEFT JOIN`和`RIGHT JOIN`。部分数据库(如PostgreSQL)支持`FULL OUTER JOIN`,即同时保留两表所有不匹配行[^1][^3]。 - **语法示例**: ```sql -- FULL OUTER JOIN(部分数据库支持) SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.key = TableB.key; ``` #### 对比表格 | 连接类型 | 主表保留方向 | 匹配行为 | 不匹配行为 | |----------------|--------------|------------------------|--------------------------| | `INNER JOIN` | 无主表 | 仅返回匹配行 | 丢弃不匹配行 | | `LEFT JOIN` | 表 | 保留表所有行 | 表以`NULL`填充 | | `RIGHT JOIN` | 表 | 保留表所有行 | 表以`NULL`填充 | | `FULL JOIN`* | 双向 | 保留两表所有行 | 不匹配侧以`NULL`填充 | > *注:`FULL JOIN`需特定数据库支持(如SQL Server)[^4]。 --- ### 应用示例 假设存在表`Customers`(客户表)和`Orders`(订单表): ```sql -- 查询所有客户及其订单(含未下单客户) SELECT * FROM Customers LEFT JOIN Orders ON Customers.id = Orders.customer_id; -- 查询所有订单对应的客户(仅含匹配记录) SELECT * FROM Customers INNER JOIN Orders ON Customers.id = Orders.customer_id; ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值