日志框架梳理(Log4j,Reload4j,JUL,JCL,SLF4J,Logback,Log4j2)

news2024/11/30 11:40:46

原文链接

日志框架发展历程

在了解日志框架时总会列出一系列框架:Log4j,Reload4j,JUL,JCL,SLF4J,Logback,Log4j2,这么多框架让人感到混乱,该怎么选取、该怎么用。接下来,让我们逐步理清这些框架及之间的关系。

首先来了解日志框架的发展历程,就能大致清楚这些框架之间的关联和区别。

  1. 1996 年,Log4j 开始出现,并成为一个流行的 Java 日志记录包,后来贡献给 Apache 基金会,但在 2015 年宣布不在维护了。

    reload4j 是 Apache log4j 版本 1.2.17 的一个分支,旨在解决 log4j 的安全问题。Reload4j 是log4j 版本 1.2.17 的直接替代品,所以想继续使用 log4j 1.x 的框架,推荐使用 slf4j-reload4j 进行替代。

  2. 2002 年 Java 1.4 发布,同时推出自己的日志库 JUL(Java Util Logging)。Apache 曾建议 sun 公司 将 Log4j 引入到 jdk 中,但被拒绝了,sun 公司仿照 Log4j,实现一套自己的日志实现框架,即 JUL。

  3. 同时,Apache 推出了 JCL(Jakarta Commons Logging,一个简单的日志门面框架),它提供了一套统一的日志接口,解决 Java 应用程序中使用不同日志框架导致的代码依赖问题,其内部提供了一个 Simple Log 简单日志实现,支持集成使用 Log4j、jdk 1.4(JUL)等具体日志实现。

    JCL最初是由Apache软件基金会的Jakarta 项目组开发的,当时它是 Apache Jakarta 项目的一部分。在2011年,Jakarta 项目组重新组织并成为 Apache Commons 项目。因此,JCL 目前被称为 Apache Commons Logging。

  4. 2006年,log4j 的作者又发布了 SLF4J(Simple Logging Facade for Java,是一个简单的日志门面框架),旨在提供统一的日志API,解决 Java 应用程序中使用不同日志框架导致的代码依赖问题。它比 Apache Commons Logging(JCL)见简单、稳定,支持集成各种日志实现框架(Jul、log4j 1.x、reload4j 和 Logback)。

  5. 同时,SLF4J 的作者顺带推出了 Logback 日志实现框架。

  6. 2014年,Apache 发布了 Log4j2,是 log4j 的官方升级版。

综上:

  • 日志门面技术(规范):JCL、SLF4J
  • 日志实现框架:Log4j 、JUL、Logback、Log4j2。

Log4j

Log4j 介绍

Log4j 有三个主要的组件:日志记录器(Logger),日志输出目标(Appenders)和日志格式化器(Layouts)。

  • 日志记录器(Logger):Logger 组件在此系统中被分为五个级别:DEBUG、INFO、WARN、ERROR 和 FATAL。这五个级别是有顺序的,DEBUG < INFO < WARN < ERROR < FATAL,分别用来指定这条日志信息的重要程度,只输出级别不低于设定级别的日志信息,假设 Logger 级别设定为 INFO,则INFO、WlARN、 ERROR 和 FATAL 级别的日志信息都会输出,而级别比 INFO 低的 DEBUG 则不会输出。

  • 日志输出目标(Appender):日志输出目标定义了日志消息的输出位置。Log4j 提供了多个内置的输出目标,如控制台、文件、数据库等。开发人员可以根据需要配置一个或多个输出目标来将日志消息输出到不同的位置。

    常使用的类如下:

    • org.apache.log4j.ConsoleAppender(输出到控制台)
    • org.apache.log4j.FileAppender(输出到文件)
    • org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
    • org.apache.log4j.RollingFileAppender(日志文件到达指定大小的时候产生一个新的日志文件)
    • org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
  • 日志格式化器(Layout):日志格式化器定义了日志消息的输出格式。Log4j 提供了多个内置的格式化器,如简单文本格式、HTML格式、XML格式、自由指定样式等。开发人员可以根据需要选择适当的格式化器来控制日志消息的输出样式。

    常使用的类如下:

    • org.apache.log4j.HTMLLayout(以HTML表格形式布局)
    • org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
    • org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
    • org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)

Log4j 配置文件

Log4j 使用一个配置文件来指定日志记录器、输出目标、格式化器等的配置信息。在实际应用中,在 使用 Log4j 之前先设置配置文件。配置文件事实上也就是对 Logger、Appender 及 Layout 进行相应设置。Log4j 支持两种配置文件格式,一种是 XML 格式的文件,一种是 properties 属性文件。下面是以 xml 属性文件的配置示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
        <!-- 设置日志输出位置 -->
        <param name="Target" value="System.out" />
        <!-- 设置日志输出格式 -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p %c{1} : %m%n" />
        </layout>
    </appender>

    <!-- 指定包下的日志输出级别 -->
<!--    <logger name="com.jcl.demo">-->
<!--        <level value="error"/>-->
<!--    </logger>-->

    <!-- 配置所有包下的日志输出级别, 除了 logger 指定的包>-->
    <root>
        <priority value="info" />
        <appender-ref ref="ConsoleAppender" />
    </root>

</log4j:configuration>

Log4j 使用示例

  1. 引入依赖

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    
  2. 按照上面 Log4j 设置配置文件

  3. 代码示例

    import org.apache.log4j.Logger;
    import org.junit.Test;
    
    public class Log4jTest {
    
        @Test
        public void Log4jTest() {
            Logger log = Logger.getLogger(Log4jTest.class);
            log.info("info日志打印");
            log.error("error日志打印");
        }
    }
    

JUL(Java Util Logging)

JUL 介绍

JUL 是 Java 1.4 版本自带的日志框架,JUL的核心组件是java.util.logging包中的类和接口。Logger是最重要的类,用于创建和管理日志记录器。Handler用于定义日志消息的输出目的地,如控制台、文件等。Formatter定义了日志消息的格式。Level表示日志的级别,JUL定义了七个日志级别,从低到高分别是:ALL、FINEST、FINER、FINE、CONFIG、INFO、WARNING、SEVERE、OFF。

JUL的默认配置是通过配置文件logging.properties进行的。

JUL 使用示例

  1. Java 核心包,所以无需引入其他依赖

  2. 配置 logging.properties 文件设置日志相关信息,不配置取默认设置。

  3. Java 代码示例

    import org.junit.Test;
    import java.util.logging.Logger;
    
    public class JulTest {
    
        @Test
        public void testLog(){
            Logger log = Logger.getLogger("com.jcl.demo.JulTest");
            log.info("info日志打印");
        }
    }
    

JCL(Jakarta Commons Logging)

JCL 介绍

JCL(Jakarta Commons Logging,一个简单的日志门面技术),它提供了一套统一的日志接口,通过集成不同的日志实现框架来处理日志记录。JCL 是 Apache 中的项目。

前面介绍了 Log4j 和 JUL 日志实现框架,使用两种框架需要分别定义不同框架下的类,随着框架或者业务发展,有时需要使用或替换不同的日志实现框架,这时业务代码中的日志实现是深度耦合的,开发人员修改替换使用的日志类非常麻烦。于是出现了日志门面框架,就是提供一系列通用接口(规范),在业务代码中统一使用日志门面框架提供的接口,日志处理操作交由引入的具体日志实现框架来实现。这就好比 JDBC 数据库驱动,统一调用 JDBC 的接口,具体处理方式由引入的具体驱动包来实现。这样在更换日志实现框架时不需要修改业务代码,解耦特定的日志实现。

JCL 使用示例

  1. JCL 是 Apache 中的项目,所以需要引入依赖包

    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    
  2. 若没有引入其他日志实现框架,默认使用 Java 1.4 自带的日志框架(JUL),若使用 Log4j 日志实现框架,引入相关依赖,配置 log4j.xml。

  3. 代码使用示例,可以看到业务代码使用日志门面框架中的接口类,具体日志处理交由对应的日志实现框架处理,这样在更换日志实现框架时,不需要修改业务代码,只需要对相关日志实现框架进行相应配置即可。

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.junit.Test;
    
    public class JclTest {
    
        @Test
        public void testLog(){
            Log log = LogFactory.getLog(JclTest.class);
            log.info("info日志打印");
            log.error("error日志打印");
        }
    }
    

Logback

logback 使用示例

  1. 引入依赖,这个包依赖了 slf4j-api,所以是 slf4j + logback 的形式。

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.12</version>
    </dependency>
    
  2. 配置 logback.xml

    <configuration>
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} === %msg%n</pattern>
            </encoder>
        </appender>
    
        <root level="info">
            <appender-ref ref="CONSOLE" />
        </root>
    </configuration>
    
  3. 代码使用示例

    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class LogbackTest {
    
        @Test
        public void Log4jTest() {
            Logger log = LoggerFactory.getLogger(LogbackTest.class);
            log.info("info日志打印");
            log.error("error日志打印");
        }
    }
    

SLF4J(Simple Logging Facade For Java)

SLF4J 介绍

SLF4J 也是一个日志门面框架,即简单日志门面(Simple Logging Facade For Java),主要是为了提供一套标准、规范的日志接口,具体的实现交由其他日志实现框架。

参考官网,SLF4J 可以集成使用以下不同的日志实现框架:

  • slf4j-api.jar 包,这是使用 SLF4J 接口需要使用的 jar 包,只引入该 jar 包,使用时会提示没有提供日志实现,默认会去使用 slf4j-nop 日志实现框架,一种无操作的日志记录机制。
  • slf4j-nop.jar 包,这是 SLF4J 的一个日志实现,它实际上是一个空操作的日志记录器。当应用程序使用slf4j-nop作为日志框架时,所有的日志操作都将被忽略,不会有任何实际的日志输出。
  • slf4j-simple.jar 包,这是 SLF4J 的一个简单日志实现,它提供了一个轻量级的日志记录器,适用于简单的应用程序和测试环境。
  • logback-classic.jar + logback-core.jar 包,logback-core是Logback框架的一个核心模块,作为logback-classic的基础组件之一,它提供了Logback框架的核心功能和基本组件;logback-classic 是 Logback 框架的一个核心模块,它建立在logback-core之上,提供了与log4j兼容的API,并且是log4j的继任者。实际引入 logback-classic 包即可,该包中引入了 logback-core 包。
  • reload4j.jar + slf4j-reload4j.jar 包,reload4j 是 log4j 的一个扩展版本,slf4j 需要使用这个三方日志实现框架,需要使用 slf4j-reload4j 适配器(桥接器),即 slf4j ——> slf4j-reload4j ——> reload4j。
  • JUL + slf4j-jdk14.jar 包,JUL 是 Java 1.4 自带的的日志实现框架,slf4j 集成这个日志实现框架使用,同样需要引入 slf4j-jdk14 适配器(桥接器),即 slf4j ——> slf4j-jdk14 ——> JUL。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 深灰色框表示需要引入的 jar 包(如:slf4j-api.jar);
  • 浅蓝色框表示slf4j日志门面框架;
  • 深蓝色框表示slf4j本地的日志实现框架;
  • 绿色框表示需要使用的适配器;
  • 浅灰色框表示其他的日志实现框架;

SLF4J 使用示例

  1. 引入 SLF4J 依赖

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.36</version>
    </dependency>
    
  2. 需要引入日志实现框架依赖包,否则默认使用 slf4j-nop,slf4j 本地的日志实现。

    使用 slf4j-nop 日志实现,不输出任何日志,即忽略日志

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-nop</artifactId>
        <version>1.7.36</version>
    </dependency>
    

    使用 reload4j 日志实现,需要引入桥接器,配置 log4j.xml

    <!-- 桥接器 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-reload4j</artifactId>
        <version>1.7.36</version>
    </dependency>
    <!-- reload4j 日志实现框架 -->
    <dependency>
        <groupId>ch.qos.reload4j</groupId>
        <artifactId>reload4j</artifactId>
        <version>1.2.25</version>
    </dependency>
    

    使用 jul 日志实现,jul java 自带,不需要引入包,但需要引入桥接器

    <!-- jul 日志实现需要引入的桥接器 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk14</artifactId>
        <version>1.7.36</version>
    </dependency>
    

    使用 logback 日志实现,配置 logback.xml

    <!-- logback 日志实现, slf4j 本地的日志实现, logback-classic 包中包含 logback-core -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.12</version>
    </dependency>
    

    使用 log4j2 日志实现,配置 log4j2.xml

    <!-- 使用 Log4j2 日志实现框架 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.17.1</version>
    </dependency>
    <!-- 桥接器 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.17.1</version>
    </dependency>
    
  3. 代码使用示例

    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Slf4jTest {
    
        @Test
        public void Log4jTest() {
            Logger log = LoggerFactory.getLogger(Slf4jTest.class);
            log.info("info日志打印");
            log.error("error日志打印");
        }
    }
    

Log4j2

Log4j2 是 Log4j 的升级版。

logback 使用示例

  1. 引入依赖,这个包依赖了 slf4j-api,所以是 slf4j + logback 的形式。

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.17.1</version>
    </dependency>
    
  2. 配置 logback.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
        <Appenders>
            <Console name="Console" target="SYSTEM_OUT">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} == %msg%n" />
            </Console>
        </Appenders>
        <Loggers>
            <Root level="info">
                <AppenderRef ref="Console" />
            </Root>
        </Loggers>
    </Configuration>
    
  3. 代码使用示例

    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.junit.Test;
    
    public class Log4j2Test {
    
        @Test
        public void Log4jTest() {
            Logger log = LogManager.getLogger(Log4j2Test.class);
            log.info("info日志打印");
            log.error("error日志打印");
        }
    }
    

​ 日志框架梳理(Log4j,Reload4j,
JUL,JCL,SLF4J,Logback,Log4j2)

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

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

相关文章

LV.12 D23 IIC控制器与MPU6050 学习笔记

一、Exynos_4412下的IIC控制器 ​ 4412有四个IIC&#xff0c;如果要使用需要配置四个寄存器 I2CCON&#xff1a;配置一些功能 I2CSTAT&#xff1a;控制一些功能、显示一些状态 I2CDS&#xff1a;发送和接收数据 I2CADD&#xff1a;当4412作为从机时需要一个地址&#xff…

亚马逊云科技Serverless视频内容摘要提取方案

概述 随着GenAI的普及&#xff0c;视频内容摘要生成成为一个备受关注的领域。通过将视频内容转化为文本&#xff0c;可以探索到更广泛的应用场景&#xff0c;其中包括&#xff1a; 视频搜索与索引&#xff1a;将视频内容转化为文本形式&#xff0c;可以方便地进行搜索和索引操作…

利用阿里云 DDoS、WAF、CDN 和云防火墙为在线业务赋能

在这篇博客中&#xff0c;我们将详细讨论使用阿里云 CDN 和安全产品保护您的在线业务所需的步骤。 方案描述 创新技术的快速发展为世界各地的在线业务带来了新的机遇。今天的人们不仅习惯了&#xff0c;而且依靠互联网来开展他们的日常生活&#xff0c;包括购物、玩游戏、看电…

HarmonyOS4.0从零开始的开发教程04 初识ArkTS开发语言(下)

HarmonyOS&#xff08;二&#xff09; 初识ArkTS开发语言&#xff08;下&#xff09;之TypeScript入门 声明式UI基本概念 应用界面是由一个个页面组成&#xff0c;ArkTS是由ArkUI框架提供&#xff0c;用于以声明式开发范式开发界面的语言。 声明式UI构建页面的过程&#xff…

打包 抖音直播云游戏

抖音直播云游戏 oaid资源中的bcpkix-jdk15to18-1.68.jar与抖音云游戏的资源冲突。 其实资源名称是一样的&#xff0c;拷贝时资源名称有变化。 为解决此问题&#xff0c;需要规范化文件的资源名称&#xff0c;将.置为_ Error: Command failed: cmd /c echo off && Chc…

Kubernetes(K8s)DashBoard的使用-11

DashBoard 之前在kubernetes中完成的所有操作都是通过命令行工具kubectl完成的。其实&#xff0c;为了提供更丰富的用户体验&#xff0c;kubernetes还开发了一个基于web的用户界面&#xff08;Dashboard&#xff09;。用户可以使用Dashboard部署容器化的应用&#xff0c;还可以…

Redis key过期删除机制实现分析

文章目录 前言Redis key过期淘汰机制惰性删除机制定时扫描删除机制 前言 当我们创建Redis key时&#xff0c;可以通过expire命令指定key的过期时间(TTL)&#xff0c;当超过指定的TTL时间后&#xff0c;key将会失效。 那么当key失效后&#xff0c;Redis会立刻将其删除么&#…

k8s 安装 Longhorn

Longhorn 的 helm 模板官网地址&#xff1a;Longhorn 加入仓库 helm repo add longhorn https://charts.longhorn.iohelm repo update开始部署 helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace --version 1.5.3检查pod运行状态是…

STM32——电动车报警器

项目设计 // 如果检测到 PA4 被拉低&#xff08;小偷偷车&#xff09;&#xff0c;并且警报模式打开 // 则将 PB7 拉低&#xff0c;继电器通电&#xff0c;喇叭一直响 // 如果检测到 PA5 被拉高&#xff08;按键 A 按下&#xff09;&#xff0c;设定为开启警报模式 // 则将…

0X05

打开题目 点击完登录和注册都没有什么反应&#xff0c;所以先扫一下看看 在出现admin.php后就截止了&#xff0c;访问看看,进入后台。。 尝试一下弱口令 admin/12345 或者是demo/demo 设计中-自定义->右上角导出主题 找到一个导出的点&#xff0c;下载了一个1.zip压缩包…

多传感器融合SLAM在自动驾驶方向的初步探索的记录

1. VIO的不可观问题 现有的VIO都是解决的六自由度的问题, 但是对于行驶在路面上的车来说, 通常情况下不会有roll与z方向的自由度, 而且车体模型限制了不可能有纯yaw的变换. 同时由于IMU在Z轴上与roll, pitch上激励不足, 会导致IMU在初始化过程中尺度不准以及重力方向估计错误,…

配置CentOS服务器以支持PHP

CentOS是一款优秀的开源服务器操作系统&#xff0c;为各种网络服务提供了强大的支持。为了使CentOS服务器能够支持PHP&#xff0c;我们需要进行一些必要的配置。下面将介绍配置CentOS服务器以支持PHP的关键步骤。 安装PHP 首先&#xff0c;需要安装PHP解释器。在CentOS上&…

设置webstorm和idea符合Alibaba规范

只格式化自己更改的代码 ctrlShiftAltL 插件建议 Alibaba Java Coding Guidelines&#xff08;新版本的idea不支持&#xff0c;有其他同名的非官方版可代替&#xff09;&#xff0c;使用方法在此不赘述 1、设置webstorm 包含 设置两个空格缩进&#xff0c;去掉行尾分号&#…

用Mnesia为cache增加分布式支持

一&#xff1a;分布式缓存 1.选取通信策略 在设计分布式程序时&#xff0c;可供选择的通信方式主要有两种&#xff1a;异步通信和同步通信。采用异步通信时&#xff0c;发送方无须等待任何确认或应答。而在采用同步通信时&#xff0c;发送方会处于挂起状态&#xff0c;直至收…

万宾科技智能水环境综合治理监测系统效果

水环境综合治理是一项旨在全面改善水环境质量的系统工程。它以水体为对象&#xff0c;综合考虑各种因素&#xff0c;通过科学规划和技术手段&#xff0c;解决水环境污染、生态退化等问题&#xff0c;核心理念是“统一规划、分步实施&#xff1b;标本兼治&#xff0c;重在治本&a…

用C语言实现链栈的基本操作

#include <stdio.h> #include <malloc.h> #define ElemType char//相当于ElemType等同于char类型 //链式结构 数据域指针域 typedef struct LinkStackNode//定义一个链栈的结构体类型 {ElemType data;//ElemType是链栈的元素类型&#xff0c;代表数据域struct Lin…

京东数据运营(京东API接口):10月投影仪店铺数据分析

鲸参谋监测的京东平台10月份投影仪市场销售数据已出炉&#xff01; 10月份&#xff0c;环同比来看&#xff0c;投影仪市场销售均上涨。鲸参谋数据显示&#xff0c;今年10月&#xff0c;京东平台投影仪的销量为16万&#xff0c;环比增长约22%&#xff0c;同比增长约8%&#xff1…

关于前端学习的思考-align-items的用法

垂直对齐只对&#xff0c;显示模式display&#xff1a;flex有效 所以只能是flex 盒子才能应用。 摆四张图片就能清晰认识&#xff0c;不再赘述。

2023 金砖国家职业技能大赛网络安全省赛二三阶段样题(金砖国家未来技能挑战赛)

2023 金砖国家职业技能大赛网络安全省赛二三阶段样题&#xff08;金砖国家未来技能挑战赛&#xff09; 第二阶段&#xff1a; 安全运营 **背景&#xff1a;**作为信息安全技术人员必须能够掌握操作系统加固与安全管控、防火 墙一般配置、常见服务配置等相关技能&#xff0c;利…

【Qt】在表格QTableWidget或者QTableView中,当主键Id存在时更新数据,不存在时添加数据解决方案

问题 有时在开发中&#xff0c;表格需要显示数据&#xff0c;每一行呢&#xff0c;需要记录对应的id。 当更新表格数据时&#xff0c;会根据id进行更新&#xff0c;id存在就更新行数据&#xff0c;不存在就添加一行新数据。 解决方案 如何知道id存在还是不存在呢&#xff1f…