SLF4J的介绍与使用(有logback和log4j2的具体实现案例)

目录

1.日志门面的介绍

常见的日志门面 :

常见的日志实现:

日志门面和日志实现的关系:

2.SLF4J 的介绍

业务场景(问题):

SLF4J的作用

SLF4J 的基本介绍

 日志框架的绑定(重点)

桥接旧的日志框架

SLF4J原理解析

3.SLF4J 的使用

非Springboot项目

 Springboot项目(重点)

Springboot中使用logback

Springboot中使用log4j2


1.日志门面的介绍

当我们的系统变的更加复杂的时候,我们的日志就容易发生混乱。随着系统开发的进行,可能会更新不同的日志框架,造成当前系统中存在不同的日志依赖,让我们难以统一的管理和控制。就算我们强制要 求所有的模块使用相同的日志框架,系统中也难以避免使用其他类似spring,mybatis等其他的第三方框 架,它们依赖于我们规定不同的日志框架,而且他们自身的日志系统就有着不一致性,依然会出来日志 体系的混乱。

所以我们需要借鉴JDBC的思想,为日志系统也提供一套门面,那么我们就可以面向这些接口规范来开 发,避免了直接依赖具体的日志框架。这样我们的系统在日志中,就存在了日志的门面和日志的实现。

常见的日志门面 :

JCL、slf4j

常见的日志实现:

JUL、log4j、logback、log4j2

日志门面和日志实现的关系:

通过这关系图,就大概知道了其实日志门面就类似于一套标准的接口,然后不同的日志实现框架基于这套标准的接口去实现具体的功能。 

简单来说,它仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如JDBC一样,只是一种规则而已。所以单独的slf4j是不能工作的,必须搭配其他具体的日志实现方案

日志框架出现的历史顺序:

log4j -->JUL-->JCL--> slf4j --> logback --> log4j2

2.SLF4J 的介绍

业务场景(问题):

现在开发项目都是使用maven进行构建开发,假设架构师a开发了一个通用组件A,他在程序中使用的是log4j组件进行日志输出;程序员b自己之前一直在开发自己的业务模块,并且他在程序中使用的是logback日志组件,突然有一天程序员b需要在自己的业务系统中使用架构师a的通用组件A,这个时候问题就出现了,由于两套程序使用了不同的日志组件,程序员b除了要维护自己的logback日志组件配置,还需要维护通用组件A的日志配置,如何让他们的日志输出整合到一起,这个问题是很头疼的。这时候,使用slf4j就可以完美解决问题

SLF4J的作用

* 1. 使用SLF4J框架,可以在部署时迁移到所需的日志记录框架。

* 2. SLF4J提供了对所有流行的日志框架的绑定,例如log4j,JUL,Simple logging和NOP。因此可以 在部署时切换到任何这些流行的框架。

* 3. 无论使用哪种绑定,SLF4J都支持参数化日志记录消息。由于SLF4J将应用程序和日志记录框架分离, 因此可以轻松编写独立于日志记录框架的应用程序。而无需担心用于编写应用程序的日志记录框架。

* 4. SLF4J提供了一个简单的Java工具,称为迁移器。使用此工具,可以迁移现有项目,这些项目使用日志 框架(如Jakarta Commons Logging(JCL)或log4j或Java.util.logging(JUL))到SLF4J。

SLF4J 的基本介绍

简单日志门面(Simple Logging Facade For Java) SLF4J主要是为了给Java日志访问提供一套标准、规范 的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等。 当然slf4j自己也提供了功能较为简单的实现,但是一般很少用到。对于一般的Java项目而言,日志框架 会选择slf4j-api作为门面,配上具体的实现框架(log4j、logback等),中间使用桥接器完成桥接。

官方网站: https://www.slf4j.org/

SLF4J是目前市面上最流行的日志门面。现在的项目中,基本上都是使用SLF4J作为我们的日志系统。

SLF4J日志门面主要提供两大功能:

1. 日志框架的绑定

2. 日志框架的桥接

 日志框架的绑定(重点)

如前所述,SLF4J支持各种日志框架。SLF4J发行版附带了几个称为“SLF4J绑定”的jar文件,每个绑定对应 一个受支持的框架。

 要切换日志框架,只需替换类路径上的slf4j绑定。例如,要从java.util.logging切换到log4j,只需将 slf4j-jdk14-1.7.27.jar替换为slf4j-log4j12-1.7.27.jar即可。

SLF4J不依赖于任何特殊的类装载。实际上,每个SLF4J绑定 在编译时 都是硬连线的 , 以使用一个且只有一个特定的日志记录框架。例如,slf4j-log4j12-1.7.27.jar绑定在编译时绑定以使用log4j。在您的代码 中,除了slf4j-api-1.7.27.jar 之外 ,您只需将您选择的一个且只有一个绑定放到相应的类路径位置。不要在类路径上放置多个绑定。以下是一般概念的图解说明。

 

注意点:在springboot项目中,如果项目中有多个实现类的话,项目是会直接报错,无法运行,如下图

桥接旧的日志框架

通常,您依赖的某些组件依赖于SLF4J以外的日志记录API。您也可以假设这些组件在不久的将来不会切 换到SLF4J。为了解决这种情况,SLF4J附带了几个桥接模块,这些模块将对log4j,JCL和 java.util.logging API的调用重定向,就好像它们是对SLF4J API一样。

桥接解决的是项目中日志的遗留问题,当系统中存在之前的日志API,可以通过桥接转换到slf4j的实现

1. 先去除之前老的日志框架的依赖

2. 添加SLF4J提供的桥接组件

3. 为项目添加SLF4J的具体实现

迁移的方式:

如果我们要使用SLF4J的桥接器,替换原有的日志框架,那么我们需要做的第一件事情,就是删除掉原 有项目中的日志框架的依赖。然后替换成SLF4J提供的桥接器。

注意问题:

1. jcl-over-slf4j.jar和 slf4j-jcl.jar不能同时部署。前一个jar文件将导致JCL将日志系统的选择委托给 SLF4J,后一个jar文件将导致SLF4J将日志系统的选择委托给JCL,从而导致 无限循环 。

2. log4j-over-slf4j.jar和slf4j-log4j12.jar不能同时出现

3. jul-to-slf4j.jar和slf4j-jdk14.jar不能同时出现

4. 所有的桥接都只对Logger日志记录器对象有效,如果程序中调用了内部的配置类或者是 Appender,Filter等对象,将无法产生效果。

桥接其实就是原来项目是使用的其他日志门面或者框架作为日志管理,现在像切换到使用slf4j来作为日志门面好做统一的日志管理,在不修改代码的前提下,提出了桥接这种方式来兼容原来的老项目

SLF4J原理解析

1. SLF4J通过LoggerFactory加载日志具体的实现对象。

2. LoggerFactory在初始化的过程中,会通过performInitialization()方法绑定具体的日志实现。

3. 在绑定具体实现的时候,通过类加载器,加载org/slf4j/impl/StaticLoggerBinder.class

4. 所以,只要是一个日志实现框架,在org.slf4j.impl包中提供一个自己的StaticLoggerBinder类,在 其中提供具体日志实现的LoggerFactory就可以被SLF4J所加载

3.SLF4J 的使用

非Springboot项目

建项目

导入依赖

<!--slf4j core 使用slf4j必須添加-->  
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.27</version>
 </dependency>
 <!--slf4j 自带的简单日志实现 -->
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.27</version>
 </dependency>

 编写代码

public void testQuick() throws Exception {//打印日志信息LOGGER.error("error");LOGGER.warn("warn");LOGGER.info("info");LOGGER.debug("debug");LOGGER.trace("trace");// 使用占位符输出日志信息String name = "jack";Integer age = 18;LOGGER.info("用户:{},{}", name, age);// 将系统异常信息写入日志try {int i = 1 / 0;} catch (Exception e) {// e.printStackTrace();LOGGER.info("出现异常:", e);}
}

 输出结果

这种非springboot的项目大概流程是这样子,具体更多的使用细节这里我就不做讲解了,在开发中更多的是springboot项目,我重点介绍springboot项目

 Springboot项目(重点)

知识铺垫:

SpringBoot支持多种日志框架,包括Logback、Log4j2和Java Util Logging(JUL)。默认情况下,如果你使用SpringBoot的starters启动器,它将使用Logback作为日志框架。

  • Logback:Logback是SpringBoot默认的日志框架,它是Log4j的继任者,提供了更好的性能和可靠性。你可以通过在资源目录下创建一个logback-spring.xml文件来配置Logback。
  • Log4j2:Log4j2是Log4j的升级版,它在性能和功能上都有所提升,支持异步日志和插件机制。如果你想在SpringBoot中使用Log4j2,你需要添加相应的依赖并在配置文件中指定Log4j2作为日志框架。
  • Java Util Logging(JUL):JUL是Java SE的默认日志框架,SpringBoot可以配置使用JUL作为日志框架,但一般不推荐使用,因为它的性能和灵活性相对较差。

简单来说就是springboot项目已经帮我们内置好的日志框架,默认实现是SLF4J+logback

所以如果我们项目中没有做任何关于日志框架的处理,那么就会使用默认的组合

但在实际的开发中,往往需要对项目日志框架进行处理。开发中常用日志门面是SLF4J,常用到日志实现是logback和log42这二个具体的实现类。因为springboot项目默认使用的就是SLF4J,所以我们不需要在引入依赖的,只需要针对实现类做处理。

Springboot中使用logback

springboot项目默认的日志实现就是logback,所以我们不需要在引入依赖,如何配置logback相关的配置,有二种方式,一种在项目的配置文件种配置,一种是单独建一个文件配置(方便管理)。我这里采用单独第二种

logback会依次读取以下类型配置文件:

logback.groovy

logback-test.xml

logback.xml 如果均不存在会采用默认配置

这里我建一个logback.xml的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--日志输出格式:%-5level%d{yyyy-MM-dd HH:mm:ss.SSS}日期%c类的完整名称%M为method%L为行号%thread线程名称%m或者%msg为信息%n换行--><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%-5level] %c %M %L [%thread] %m%n"/><!--Appender: 设置日志信息的去向,常用的有以下几个ch.qos.logback.core.ConsoleAppender (控制台)ch.qos.logback.core.rolling.RollingFileAppender (文件大小到达指定尺寸的时候产生一个新文件)ch.qos.logback.core.FileAppender (文件)--><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><!--输出流对象 默认 System.out 改为 System.err--><target>System.out</target><!--日志格式配置--><encoderclass="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${pattern}</pattern></encoder></appender><!-- 日志文件存放目录 --><property name="log_dir" value="./logs"></property><!--日志文件输出appender对象--><appender name="file" class="ch.qos.logback.core.FileAppender"><!--日志格式配置--><encoderclass="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${pattern}</pattern></encoder><!--日志输出路径--><file>${log_dir}/logback.log</file></appender><!-- 生成html格式appender对象 --><appender name="htmlFile" class="ch.qos.logback.core.FileAppender"><!--日志格式配置--><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="ch.qos.logback.classic.html.HTMLLayout"><pattern>%level%d{yyyy-MM-ddHH:mm:ss}%c%M%L%thread%m</pattern></layout></encoder><!--日志输出路径--><file>${log_dir}/logback.html</file></appender><!-- 日志文件拆分和归档的appender对象--><appender name="rollFile"class="ch.qos.logback.core.rolling.RollingFileAppender"><!--日志格式配置--><encoderclass="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${pattern}</pattern></encoder><!--日志输出路径--><file>${log_dir}/roll_logback.log</file><!--指定日志文件拆分和压缩规则--><rollingPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!--通过指定压缩文件名称,来确定分割文件方式--><fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd}-%i.log</fileNamePattern><!--文件拆分大小--><maxFileSize>50MB</maxFileSize></rollingPolicy></appender><!--用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。<loger>仅有一个name属性,一个可选的level和一个可选的addtivity属性name:用来指定受此logger约束的某一个包或者具体的某一个类。level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和OFF,如果未设置此属性,那么当前logger将会继承上级的级别。additivity:是否向上级loger传递打印信息。默认是true。<logger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger--><!--也是<logger>元素,但是它是根logger。默认debuglevel:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和 OFF,<root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。--><root level="INFO"><appender-ref ref="console"/><appender-ref ref="rollFile"/></root>
</configuration>

编写测试类

public class LogbackTest {public static final Logger LOGGER = LoggerFactory.getLogger(Slf4jTest.class);@Testpublic void logbackTest(){LOGGER.error("error");  //错误信息,不会影响程序运行LOGGER.warn("warn");    //警告信息,表示系统运行可能出现的异常LOGGER.info("info");    //提示信息,记录系统运行,io操作等LOGGER.debug("debug");  //调试信息,一般在开发中使用LOGGER.trace("trace");  //追踪信息,记录程序所有的流程信息// 占位符输出日志String name = "jack";Integer age = 18;LOGGER.info("用户姓名:{},年龄:{}",name,age);int i = 1;try {i = i/0;} catch (Exception e) {LOGGER.info("出现异常",e);}}
}

运行效果:

未配置logback.xml前的输出效果

配置后的输出效果

总结:在springboot 使用logback非常的简单,你只需要通过配置文件去配置它就好了

Springboot中使用log4j2

 因为springboot项目内置日志实现是logback,所以如果我们要使用log42的话,需要移除默认的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!--排除默认spring-boot-starter-logging启动器-->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

加入 log4j2的依赖

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

 

在src/main/resources目录下创建一个名为log4j2-spring.xml的配置文件,Spring Boot会默认加载这个配置文件。Spring Boot官方推荐优先使用带有-spring的文件名作为日志配置。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"><!-- 定义全局变量,日志文件路径和格式 --><Properties><Property name="log.path">./dev</Property><Property name="log.name">log4j2</Property><Property name="file.pattern">%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{50} - %msg%n</Property></Properties><!-- 控制台输出配置 --><Appenders><Console name="STDOUT" target="SYSTEM_OUT"><PatternLayout pattern="${file.pattern}"/><ThresholdFilter level="DEBUG"/></Console><!-- 文件输出配置 --><RollingFile name="INFO_FILE" fileName="${log.path}/${log.name}.log4j2.log"filePattern="${log.path}/%d{yyyy-MM-dd}/${log.name}.info.%d{yyyy-MM-dd}-%i.log"><PatternLayout pattern="${file.pattern}"/><LevelMatchFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/><!-- 每个文件最大10MB --><SizeBasedTriggeringPolicy size="10MB"/><!-- 最多保留30天的历史记录 --><DefaultRolloverStrategy max="30"/></RollingFile><!-- 文件输出配置 --><RollingFile name="ERROR_FILE" fileName="${log.path}/${log.name}.error.log"filePattern="${log.path}/%d{yyyy-MM-dd}/${log.name}.error.%d{yyyy-MM-dd}-%i.log"><PatternLayout pattern="${file.pattern}"/><LevelMatchFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/><!-- 每个文件最大10MB --><SizeBasedTriggeringPolicy size="10MB"/><!-- 最多保留30天的历史记录 --><DefaultRolloverStrategy max="30"/></RollingFile></Appenders><!-- 设置root logger --><Loggers><Root level="INFO"><AppenderRef ref="STDOUT"/><AppenderRef ref="INFO_FILE"/><AppenderRef ref="ERROR_FILE"/></Root></Loggers>
</Configuration>

 运行效果

 如何是出现如上图,就代表使用的是log4j2这个日志实现了

总的来说,推荐使用Logback,配置简单,性能也还不错,而且是SpringBoot的默认日志框架

这里对于logback和log4j2的使用只是基本的使用,对于更多的使用细节,后续我会分别出对应实现框架的文章,文章到这里就结束了,如有不足,欢迎指正

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

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

相关文章

线程安全的原因及解决方法

什么是线程安全问题 线程安全问题指的是在多线程编程环境中&#xff0c;由于多个线程共享数据或资源&#xff0c;并且这些线程对共享数据或资源的访问和操作没有正确地同步&#xff0c;导致数据的不一致、脏读、不可重复读、幻读等问题。线程安全问题的出现&#xff0c;通常是…

Mac 系统如何将搜狗输入法设置为默认输入法

Mac 系统默认将自带的ABC输入法作为默认输入法&#xff0c;很不方便中文输入&#xff0c;想设置搜狗输入法为默认输入法如何设置呢&#xff1f;具体步骤如下&#xff1a; 1、打开&#xff1a;系统设置——键盘——文字输入&#xff0c;点击设置 2、点击左下角的 3、选择 其他…

数学系C++(六七)

目录 * &指针与地址 void指针 指针可以等于&#xff1a; const 指向常量的指针 const int *px 常指针 int * const px 指向常量的常指针const 类型标识符 * const 指针名 指针加减&#xff1a; 指针恒等式 函数指针【待续】 指针型函数&#xff1a; 指向函数的…

52-5 内网代理2 - LCX端口转发(不推荐使用LCX)

环境搭建: 本地开3台虚拟机:kali(必须)、windows2012与2008 (可换成其他windows虚拟机) kali - 网络配置成桥接模式 windows2012 - 设置两个网卡,NAT与桥接模式 注意:windows2012要关闭防火墙,要不然其他主机ping不通 关闭防火墙后再开启远程桌面连接 windwos20…

拉曼光谱入门:3.拉曼光谱的特征参数与定量定性分析策略

1.特征参数 1.1 退偏振率 退偏振率&#xff08;p&#xff09;是一个衡量拉曼散射光偏振状态的参数&#xff0c;它描述了拉曼散射光的偏振方向与入射光偏振方向之间的关系。退偏振率定义为垂直偏振方向的拉曼散射强度与平行偏振方向的拉曼散射强度之比。退偏振率&#xff08;p&…

Hi6602 恒压恒流SSR电源方案

Hi6602是一款针对离线式反激电源设计的高性能PWM控制器。Hi6602内集成有通用的原边恒流控制技术&#xff0c;可支持断续模式和连续模式工作&#xff0c;适用于恒流输出的隔离型电源应用中。Hi6602内部具有高精度65kHz开关频率振荡器&#xff0c;且带有抖频功能可优化EMI性能。H…

【全面介绍下如何使用Zoom视频会议软件!】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

WEB自动化框架封装MySQL连接及sql断言教程

为了在Web自动化测试中连接MySQL数据库并进行SQL断言&#xff0c;您可以按照以下步骤&#xff1a; 安装MySQL Connector/Python驱动程序&#xff0c;并导入它。 使用Connector/Python创建一个连接对象&#xff0c;指定所需的主机名、用户名、密码和数据库名。 创建一个游标对…

系统级别的原生弹窗窗口

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>原生的弹出窗口dialog</title><style>…

相见恨晚的《新程序员》 AI 专辑

声明&#xff1a;本文并不什么“软文”&#xff0c;是我的真实感受分享。本人和《新程序员》无任何利益关系&#xff0c;读者购买专栏我不会获得任何分成。 一、前言 前不久有位朋友送我一本 CSDN 出品的 《新程序员 006&#xff1a;人工智能新十年》 的杂志。 说实话&#x…

Axure教程:App侧边抽屉菜单交互制作

今天给大家示范一下抽屉菜单在Axure中的做法。在抽屉式菜单中&#xff0c;要实现两个交互效果&#xff0c;分别是&#xff1a; 交互一 抽屉菜单中1、2级菜单项的伸缩效果 实现逻辑&#xff1a;设置动态面板的切换状态及“推动/拉动原件”实现 交互二 菜单项的选中状态切换 …

Nuxt3 的生命周期和钩子函数(十)

title: Nuxt3 的生命周期和钩子函数&#xff08;十&#xff09; date: 2024/6/30 updated: 2024/6/30 author: cmdragon excerpt: 摘要&#xff1a;本文详细介绍了Nuxt3框架中的五个webpack钩子函数&#xff1a;webpack:configResolved用于在webpack配置解析后读取和修改配置…

秋招力扣刷题——从前序与中序遍历序列构造二叉树

一、题目要求 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 二、解法思路 根据二叉树的遍历结构重构二叉树&#xff0c;至少两种遍历方式结合&…

批量爬取B站网络视频信息

使用XPath爬取B站视频链接等相关信息 分析B站html框架获取内容完整代码 对于B站&#xff0c;目前网上的爬虫大多都是使用通过解析服务器的响应来爬取想要的内容&#xff0c;下面我们通过使用XPath来爬取B站上一些想要的信息 此次任务我们需要对B站搜索到的关键字&#xff0c;并…

苍穹外卖--sky-take-out(四)10-12

苍穹外卖--sky-take-out&#xff08;一&#xff09; 苍穹外卖--sky-take-out&#xff08;一&#xff09;-CSDN博客​编辑https://blog.csdn.net/kussm_/article/details/138614737?spm1001.2014.3001.5501https://blog.csdn.net/kussm_/article/details/138614737?spm1001.2…

创维汽车开展年中总结会:创新创造·勇开拓 智慧经营·攀高峰

2024年7月3日&#xff0c;回顾上半年的工作成果&#xff0c;总结经验教训&#xff0c;明确下半年的发展方向和重点任务&#xff0c;创维汽车于山西省晋中市榆次区山西联合创维体验中心开展年中总结会。 创维集团、创维汽车创始人黄宏生&#xff1b;开沃集团联合创始人、首席执…

昇思25天学习打卡营第12天|FCN图像语义分割

文章目录 昇思MindSpore应用实践基于MindSpore的FCN图像语义分割1、FCN 图像分割简介2、构建 FCN 模型3、数据预处理4、模型训练自定义评价指标 Metrics 5、模型推理结果 Reference 昇思MindSpore应用实践 本系列文章主要用于记录昇思25天学习打卡营的学习心得。 基于MindSpo…

MySQL Binlog详解:提升数据库可靠性的核心技术

文章目录 1. 引言1.1 什么是MySQL Bin Log&#xff1f;1.2 Bin Log的作用和应用场景 2. Bin Log的基本概念2.1 Bin Log的工作原理2.2 Bin Log的三种格式 3. 配置与管理Bin Log3.1 启用Bin Log3.2 配置Bin Log参数3.3 管理Bin Log文件3.4 查看Bin Log内容3.5 使用mysqlbinlog工具…

Oracle连接失败,ORA-12514, TNS:listener does not currently know of service requested in connect descripto

问题描述 在Window上搭建Oracle数据库,安装后启动,使用Dbeaver连接时无法连接,报错:Listener refused the connection with the following error: ORA-12514, TNS:listener does not currently know of service requested in connect descriptor Listener refused the c…

MySQL 中的 DDL、DML、DQL 和 DCL

文章目录 1. 数据定义语言&#xff08;DDL&#xff09;2. 数据操作语言&#xff08;DML&#xff09;3. 数据查询语言&#xff08;DQL&#xff09;4. 数据控制语言&#xff08;DCL&#xff09;总结 在 MySQL 数据库管理系统中&#xff0c;SQL 语句可以根据其功能分为不同的类别&…