【数据库编程】最新版MySQL的JDBC编程(图文演示)

news/2024/5/19 2:10:11 标签: 数据库, mysql, adb, jdbc, java

数据库系列文章
1. 零基础带你快速上手SQL语言
2. 玩转表及其数据
3. 上手表设计
4. 索引和事务
5. 最新版MySQL的JDBC编程


文章目录

  • 前言
  • 1. 数据库编程的必备条件
  • 2. Java的JDBC编程
  • 3. JDBC工作原理
  • 4. JDBC编程
    • 4.1 创建 Java 项目
    • 4.2 导入数据库驱动包
    • 4.3 利用 JDBC 实现增删改操作
      • 4.3.1 创建并初始化数据源
      • 4.3.2 连接数据库
      • 4.3.3 构造SQL语句
      • 4.3.4 执行SQL语句
      • 4.3.5 释放必要的资源
      • 4.3.6 全部代码展示
      • 4.3.7 运行代码结果
    • 4.4 利用JDBC实现查询操作
      • 4.4.1 执行SQL语句
      • 4.4.2 释放必要的资源
      • 4.4.3 全部代码展示
      • 4.4.4 运行代码结果
      • 4.4.5 JDBC使用步骤简易总结
  • 5. 一些补充
    • 5.1 Connection 数据库连接
    • 5.2 Statement 对象
    • 5.3 占位符 (?) 的使用
    • 5.4 两个思考问题
  • 总结


前言

此为数据库系列的最后一篇文章, 在学习完之前数据库基础的所有内容后, 即可开始JDBC的学习, 本文主要讲解数据库驱动, JDBC的概念及作用, 掌握JDBC使用的基本过程, 及JDBC是如何连接MySQL数据库, 并利用Java来进行增删改查的.
关注收藏, 开始学习吧🧐


1. 数据库编程的必备条件

  • 编程语言: 如Java, C/C++, Python等.
  • 数据库: 如Oracle, MySQL, SQL Server等.
  • 数据库驱动包: 不同的数据库, 对应不同的编程语言提供了不同的数据库驱动包, 如: MySQL提供了Java的驱动包mysql-connector-java, 需要基于Java操作MySQL即需要该驱动包. 同样的, 要基于Java操作, Oracle数据库则需要Oracle的数据库驱动包ojdbc.

在本文, 我们将用Java和MySQL来讲解(JDK1.8, MySQL8)

2. Java的JDBC编程

在学习了SQL语言后, 进入公司后, 我们是否需要一行行手搓SQL语句在控制台操作数据库呢? 答案是并不需要, 真正在公司中操作数据库的方法, 绝大多数情况都是通过编程语言代码来实现的, 很少会手动在客户端中输入SQL语句来实现.

JDBC, 即Java Database Connectivity, Java数据库连接.
是一种用于执行SQL语句的Java API,它是Java中的数据库连接规范。这个API由 java.sql., javax.sql.包中的一些类和接口组成,它为Java开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问.

API是什么意思呢? Application Programming Interface, 是一种允许不同软件应用程序之间进行通信和交互的接口, Java就是给各大数据库厂商提供了一个数据库连接规范, 让Java程序员写一套操作, 即可使用不同的数据库软件.

JDBC的优势:

  • Java语言访问数据库操作完全面向抽象接口编程
  • 开发数据库应用不用限定在特定数据库厂商的API
  • 程序的可移植性大大增强

3. JDBC工作原理

JDBC 为多种关系数据库提供了统一访问方式, 作为特定厂商数据库访问API的一种高级抽象, 它主要包含一些通用的接口类.

JDBC 访问数据库层次结构:
在这里插入图片描述
可以看到, 数据库厂商需要给提供一个驱动程序, 来完成 API 的转换, 对原生 API 进行封装, 封装为 JDBC 需要的样子, 驱动就是用来让 JDBC 能够认识数据库的 API, 而 Java 程序猿要想进行数据库开发, 就需要在项目中导入对应数据库的驱动包, 才能编写代码.

3.1 数据库驱动包从哪里来

目前数据库驱动包有多种方式可以获得, 我以我们要获取的MySQL数据库的驱动包为例:

列举三种获取方式:

  1. MySQL的官方网站获取
  2. GitHub上的开源资源
  3. Maven中央仓库

这里我们通过Maven中央仓库来获取, 他类似于一个服务器, 托管了各种软件程序包, 如果我们有需要的程序包, 就可以访问他来下载. 下面我来教大家如何利用Maven仓库来下载.

给大家提供一个链接 ---- Maven仓库

在这里插入图片描述

打开后, 在上面的搜索框搜索MySQL.

在这里插入图片描述

然后我们选择MySQL Connector Java.

在这里插入图片描述

紧接着我们向下找下载的版本. 注意此处的版本, 大版本需要与数据库的版本相匹配, 由于博主的MySQL数据库版本为8, 所以此处下载的驱动包也得是8系列, 当然新版本是支持向下兼容的, 意思是新版本是可以使用旧版本的驱动包, 但旧版本的无法使用新版本驱动包, 如果读者使用的是MySQL5版本的, 请向下寻找5系列的驱动包.

找到8系列后, 我们可以随便选择一个, 小版本不重要, 只要大版本选择正确即可. 此处博主选择 8.0.30 版本.

在这里插入图片描述

打开之后, 我们选择 jar 包, 进行下载.

在这里插入图片描述

jar 包是我们 Java 发布程序的典型方式, 通过把一堆由 .java 源文件编译而成的 .class 文件, 打成压缩包(类似于 .rar , .zip), 把 jar 拷贝给对方, 对方就可以直接使用 jvm 来运行了~~

此处, MySQL驱动包的这个 jar 不是单独运行的 jar , 需要把他导入到项目中, 然后就可以调用其中的类和方法来进行编程了.

下载完成之后, 就可以正式开始我们的JDBC编程了.

4. JDBC编程

4.1 创建 Java 项目

此处我们使用 IntelliJ IDEA 进行演示, 软件版本为 2023.1.1 版本, 可能有部分操作与读者不同, 大家可以参考一下.

  1. 打开 IDEA 界面, 选择 New Project
    在这里插入图片描述
  2. 直接创建 Java 文件即可, 取一个项目名称, 一路默认.
    在这里插入图片描述
  3. 接下来一个 Java 文件就创建好了.
    在这里插入图片描述

4.2 导入数据库驱动包

  1. 找到刚才我们下载好的MySQL驱动包
    在这里插入图片描述
  2. 选择复制之后, 在 Java 项目中, 创建一个 lib 文件, 用来存放驱动包.
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  3. 将复制的 jar 包粘贴到 lib 中.
    在这里插入图片描述
  4. 把这个目录标记为项目的库, 右键驱动包, 点击 Add as library…
    在这里插入图片描述
    在这里插入图片描述
  5. 驱动包左侧出现小箭头, 并且可以展开, 表示已经添加成功.
    在这里插入图片描述
    经过以上操作, IDEA 就可以识别我们导入的 jar 包, 从而就可以调用里面的类来写代码了.

4.3 利用 JDBC 实现增删改操作

先讲一下数据库中的 insert 操作, delete, update 操作与之相同, 之后我再补充如何进行 select 操作.

首先我们创建一个类, 叫做JDBCInsert. 右键src, 进行创建.
在这里插入图片描述
在这里插入图片描述

写一个 main 方法.
在这里插入图片描述

接下来, 我们编写JDBC代码, 可以分为五步操作:
在这里插入图片描述

4.3.1 创建并初始化数据源

数据源顾名思义, 便是数据从哪里来, 描述数据库的服务器在哪, 我们使用 DataSource.
在这里插入图片描述

当然, 上述代码也可以不使用向上转型, 向下转型, 转来转去的.
在这里插入图片描述

有同学可能会问, DataSource 是用来描述数据库服务器在哪的, 那么URL是什么东西呢? 还有里面填写的一长堆字符串又是什么, 别急, 我们慢慢来讲.

URL, UniformResourceLocator, 统一资源定位符, 用来描述网络上某个资源所在的唯一位置. 其格式比较特殊. 我们只重点讲一下 JDBC 中的这个URL是什么意思.

jdbc:mysql://127.0.0.1:3306/learn
jdbc:数据库://主机号:端口号/要操作的数据库名称

  • jdbc:
    表示遵守的是jdbc协议, 每个数据库都是固定的.

  • mysql:
    表示用的是MySQL数据库, 看使用的是什么数据库.

  • 127.0.0.1:
    表示是主机号, 通常, 客户端和服务器之间都是利用网络进行通讯的, 而网络上确认主机的位置就是通过 IP 地址来确定的, 这里咱们写的都是 127.0.0.1 环回 IP , 表示我们自己的主机, 因为咱们的数据库客户端和数据库服务器是在一个主机上的, 这里我们也可以将 127.0.0.1 写为 localhost , 也可以表示我们自己的主机. 当然, 当客户端和服务器不在一个主机上, IP地址就得变一变了, 具体得看那会的主机地址是什么.

  • 3306:
    此处为端口号, 端口用来区分应用程序, 而我们数据库服务器的默认端口号就是3306, 具体得看当初安装数据库时设置的.

  • learn:
    此处指的是我们要操作的数据库的名称, 使用该数据库时, 得确保你的MySQL数据库中有该数据库.

在这里插入图片描述
接下来, 我们再将自己的数据库账号和密码提供给数据库服务器, 注意, MySQL账号默认为 root , 密码为自己当初设置的数据库密码.

4.3.2 连接数据库

写到这里的代码, 只是设置了数据源, 描述了数据库服务器在哪, 但还没有真正的和数据库连接. 接下来, 我们利用 Connection 类进行数据库的连接.

在这里插入图片描述

可以看到, getConnection()方法报了受查异常, 我们采用抛除异常进行处理.

在这里插入图片描述

4.3.3 构造SQL语句

连接好数据库后, 我们就可以使用构造SQL语句, 对数据库进行操作了, 在这里我们实现一个插入操作, 要求对 test 表中, 插入一条id为1, 名字叫张三的数据. 在实现该操作前, 我们要确保数据库中有一个表为 test.

create table test(id int, name varchar(20));

在这里插入图片描述

接下来, 用JDBC实现我们的插入操作. 首先构造一个SQL语句.

在这里插入图片描述

即使我们使用Java来操作数据库, 还是得靠SQL语句, 只不过是换成用代码来构造SQL语句, 就是利用的前面学的SQL增删改查的基础语法.

在这里插入图片描述

接着, 在向服务器发送SQL语句之前, 我们使用 PreparedStatement 预编译一下SQL语句, 这样可以减轻服务器的负担. 然后, 我们就可以向服务器发送SQL语句了, 并执行SQL操作了.

4.3.4 执行SQL语句

在这里插入图片描述
将SQL语句(预编译过的)发送给数据库服务器, 由服务器做出响应, insert, delete, update 操作, 使用的都是 executeUpdate() 方法, 返回 int 表示影响到的行数.

如果我们要实现 delete, update 的操作, 只需要将此处的SQL语句按需求修改即可.

在这里插入图片描述

而 select 操作因为结果是一个集合, 所以返回的比较复杂, 使用的是executeQuery()方法, 返回的是一个结果集. 我们之后讲一下 select 操作时, 再谈它的使用方法.

4.3.5 释放必要的资源

在这里插入图片描述
这一步是将我们之前调用的类都关闭掉, 以免浪费服务器资源.

4.3.6 全部代码展示

java">public class JDBCInsert {
    public static void main(String[] args) throws SQLException {

        // JDBC 需要通过以下步骤来完成开发
        // 1. 创建并初始化一个数据源
        DataSource dataSource = new MysqlDataSource(); // 向上转型
        // 这个是子类拥有的, 父类没有的方法, 要想使用, 就需要把父类引用向下转型为子类引用.
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn");
        // 输入数据库账号
        ((MysqlDataSource)dataSource).setUser("root");
        // 输入数据库密码
        ((MysqlDataSource)dataSource).setPassword("1111");
        

        // 2. 和数据库服务器建立连接
        Connection connection = dataSource.getConnection();

        // 3. 构造 SQL 语句
        // 给 test 表中, 插入一条id为1, 姓名为张三的记录
        String sql = "insert into test value('1', '张三')";
        // 使用 PreparedStatement 预编译一下SQL语句
        PreparedStatement statement = connection.prepareStatement(sql);

        // 4. 执行 SQL 语句
        int ret = statement.executeUpdate();
        System.out.println("ret = " + ret);

        // 5. 释放必要的资源
        statement.close();
        connection.close();

    }
}

完成以上五步操作后, 我们即可运行一下代码.

4.3.7 运行代码结果

在这里插入图片描述
可以看到, 结果返回 ret = 1 , 影响了1行代码, 这里表示的是指插入了一条数据.
我们再看一看 test 表中数据到底有没有成功添加, 这里我们先使用控制台查看即可.
在这里插入图片描述
可以看到, id 为1, name 为张三的数据已经插入到 test 表中, 插入成功了!!!

那么我们如何利用代码来实现 select 查询的操作呢? 与 insert, delete, update哪里不同呢?

4.4 利用JDBC实现查询操作

这里我们就拿上面的 test 表来举例子介绍 select 查询操作, 要求查询到 test 表中的所有数据, 我们的基本操作与之前介绍的增删改操作基本相同, 唯一不同的就是 select 语句返回的是一个结果集 ---- ResultSet对象, 而并非一个数字, 所以, 在代码中, 我们将查询语句发送给服务器后, 收到的响应也应该拿一个结果集来储存.

我们再创建一个 JDBCSelect类, 具体过程我就不演示了, 大家可以参考之前讲的 JDBCInsert 类的创建方法.

我们要做的, 还是以下五步, 这里我只讲第四步和第五步操作, 其余操作都与之前相同.
在这里插入图片描述

4.4.1 执行SQL语句

在之前我们构造的SQL语句为:

java">// 查询 test 表中的所有数据.
String sql = "select * from test";

在这里插入图片描述
之前我们使用 int 类型来接受服务器响应回的值, 而这里通过executeQuery()方法提交的 select 语句, 服务器响应回来的是一个结果集, 我们用 ResultSet 来接受, 它代表符合SQL语句条件的所有行, 并且能通过一套 getXXX() 方提供了对这些行中数据的访问.

ResultSet 里的数据一行一行排列, 每行有多个字段, 并且有一个记录指针, 指针所指的数据行叫做当前数据行, 我们只能来操作当前的数据行. 我们如果想要取得某一条记录, 就要使用 ResultSet 的 next() 方法, 如果我们想要得到ResultSet里的所有记录, 就应该使用while循环.

在这里插入图片描述
按照此种方法即可将返回结果一行一行的打印出来, 当指针把整个表都走完, 就会返回 false 结束循环, getXXX() 方法是取出这一行的指定列的值, 使用时要注意和列的类型相匹配, 在这里我们用 getInt() 和 getString() 来取出 id 和 name 值, 其中的参数可以是列名, 或者表中第几列的下标(从1开始).

4.4.2 释放必要的资源

在这里插入图片描述
此步需要将 resultSet 也进行关闭.

4.4.3 全部代码展示

java">public class JDBCSelect {
    public static void main(String[] args) throws SQLException {

        // JDBC 需要通过以下步骤来完成开发
        // 1. 创建并初始化一个数据源
        DataSource dataSource = new MysqlDataSource(); // 向上转型
        // 这个是子类拥有的, 父类没有的方法, 要想使用, 就需要把父类引用向下转型为子类引用.
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn");
        // 输入数据库账号
        ((MysqlDataSource)dataSource).setUser("root");
        // 输入数据库密码
        ((MysqlDataSource)dataSource).setPassword("1111");

        // 2. 和数据库服务器建立连接
        Connection connection = dataSource.getConnection();

        // 3. 构造 SQL 语句
        String sql = "select * from test";
        PreparedStatement statement = connection.prepareStatement(sql);

        // 4. 执行 SQL 语句
        ResultSet resultSet = statement.executeQuery();

        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            System.out.println("id = " + id + " name = " + name);
        }

        // 5. 释放必要的资源
        resultSet.close();
        statement.close();
        connection.close();

    }
}

下面我们执行一下代码.

4.4.4 运行代码结果

在这里插入图片描述

可以看到, 实现了我们的要求, 查询到了 test 表中的所有数据, 与之前控制台查询到的数据相符合.
在这里插入图片描述

4.4.5 JDBC使用步骤简易总结

  1. 创建并初始化数据库
java">DataSource dataSource = new MysqlDataSource();
  1. 连接数据库
java">Connection connection = dataSource.getConnection();
  1. 构造SQL语句
java">String sql = "xxxxxxxxx";
PreparedStatement statement = connection.prepareStatement(sql);
  1. 执行SQL语句
java">// 两种情况
// 1. insert, delete, update 使用 executeUpdate()
int ret = statement.executeUpdate();

// 2. select 使用executeQuery()
ResultSet resultSet = statement.executeQuery();
  1. 释放必要资源
java">// 使用了什么关闭什么
// resultSet.close(); 
statement.close();
connection.close();

5. 一些补充

到这里, JDBC编程的基础知识已经讲到很多了, 下面我们进行一些别的补充.

5.1 Connection 数据库连接

Connection 接口实现类由数据库提供,获取 Connection 对象通常有两种方式:

  • 一种是通过 DataSource(数据源) 对象获取, 我们上述使用的JDBC便是使用 DataSource 这样的方式来编写的, 而实际应用中也会使用DataSource对象.
java">// 1. 创建并初始化一个数据源
DataSource dataSource = new MysqlDataSource(); // 向上转型
// 这个是子类拥有的, 父类没有的方法, 要想使用, 就需要把父类引用向下转型为子类引用.
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn");
// 输入数据库账号
((MysqlDataSource)dataSource).setUser("root");
// 输入数据库密码
((MysqlDataSource)dataSource).setPassword("311003");
// 2. 和数据库服务器建立连接
Connection connection = dataSource.getConnection();
  • 一种是通过 DriverManager(驱动管理类) 的静态方法获取. 其本质是, 通过反射的方式, 加载驱动包中的类. 如果在学习本文前, 了解过一些JDBC编程知识, 应该学习的是这种最常见的方法.
java">// 加载JDBC驱动程序
Class.forName("com.mysql.jdbc.Driver");
// 设置数据库的信息
String url = "jdbc:mysql://127.0.0.1:3306/learn";
String user = "root";
String password = "1111";
// 创建数据库连接
Connection connection = DriverManager.getConnection(url, user, password);
  • 以上两种方法的不同点是什么呢, 我们为什么使用 DataSource 来获取连接, 而不使用 DriverManager 呢?
    1. Class.forName反射是属于Java开发中的特殊手段, 使用反射伤敌一千, 自损八百, 不到万不得已, 不要轻易使用. 因为反射的代码可读性很差, 编译器难以对代码的正确性进行检查, 很容易发生运行时异常. 并且 DriverManager 类来获取的 Connection 连接, 是无法重复利用的, 每次使用完以后释放资源时, 通过 connection.close() 都是关闭物理连接.
    2. DataSource内置了数据库连接池(类似于Java中的字符串常量池), 可以复用连接, 提高了连接服务器的效率. 连接池在初始化时将创建一定数量的数据库连接, 这些连接是可以复用的, 每次使用完数据库连接, 释放资源调用 connection.close() 都是将 Conncetion 连接对象回收.

5.2 Statement 对象

Statement 对象主要是将SQL语句发送到数据库中.
JDBC API 中主要提供了三种Statement对象:
在这里插入图片描述
本文我们没有使用 Statement 对象进行JDBC编程的演示, 原因是使用Statement接口操作数据库时会产生一些问题.

  • 拼串操作很繁琐

  • 存在SQL注入的问题

而实际开发中最常用的是 PreparedStatement 对象, 以下对其的总结:
在这里插入图片描述

主要掌握两种执行SQL的方法:

  • executeQuery() 方法执行后返回单个结果集的, 通常用于select语句.
  • executeUpdate() 方法返回值是一个整数, 指示受影响的行数, 通常用于update, insert, delete 语句.

5.3 占位符 (?) 的使用

还记得我们之前是怎么构造SQL语句的吗?
在这里插入图片描述
这种做法, 要插入的数据是写死的, 更合适的做法是, 把数据通过其他方式让用户来输入(比如控制台输入).

其实, 使用 PreparedStatement 对象操作的sql语句会先预编译成指令再发送给数据库, 数据库执行指令即可, 并且可以使用占位符 (?) 来替代原来的字符串拼接.

下面使用占位符来完成我们之前的 Insert 插入操作:

java">public class JDBCInsert {
    public static void main(String[] args) throws SQLException {

        // JDBC 需要通过以下步骤来完成开发
        // 1. 创建并初始化一个数据源
        DataSource dataSource = new MysqlDataSource(); // 向上转型
        // 这个是子类拥有的, 父类没有的方法, 要想使用, 就需要把父类引用向下转型为子类引用.
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn");
        // 输入数据库账号
        ((MysqlDataSource)dataSource).setUser("root");
        // 输入数据库密码
        ((MysqlDataSource)dataSource).setPassword("311003");


        // 2. 和数据库服务器建立连接
        Connection connection = dataSource.getConnection();

        // 3. 构造 SQL 语句
        // 给 test 表中, 插入一条记录
        String sql = "insert into test value(?, ?)";
        // 使用 PreparedStatement 预编译一下SQL语句
        PreparedStatement statement = connection.prepareStatement(sql);
        // 控制台输入学生数据
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入学生姓名: ");
        String name = scanner.next();
        System.out.println("请输入学号: ");
        int id = scanner.nextInt();
        // 将占位符替换成输入的值
        statement.setInt(1, id);
        statement.setString(2, name);

        // 4. 执行 SQL 语句
        int ret = statement.executeUpdate();
        System.out.println("ret = " + ret);

        // 5. 释放必要的资源
        statement.close();
        connection.close();

    }
}

使用占位符的好处:

  • 避免SQL注入风险.
  • 会为字符串自动增加上单引号.
  • 可以实现动态输入效果.

5.4 两个思考问题

  • 数据库连接有哪些方式?分别有什么区别?
  • 数据库 Statement 和 PreparedStatement 有什么区别?

总结

数据库的学习就要告一段落了, 这段时间, 学习了MySQL数据库增删改查的基础操作, 以及又学习了进阶操作, 在之后我们又补充了一些数据库的必备知识, 比如表的设计, 数据库索引和事务, 还有JDBC基础编程.
✨ 想了解更多数据库知识, 可以打开博主的数据库专栏目录小白的数据库学习之路
✨ 感谢你们的耐心阅读, 博主本人也是一名学生, 也还有需要很多学习的东西. 写这篇文章是以本人所学内容为基础, 日后也会不断更新自己的学习记录, 我们一起努力进步, 变得优秀, 小小菜鸟, 也能有大大梦想, 关注我, 一起学习。

感谢你们的阅读, 你们的鼓励是我创作的最大动力!!!!!


http://www.niftyadmin.cn/n/698721.html

相关文章

免费天气接口

城市接口 https://wis.qq.com/city/like 参数名称 含义 source 请求类型: pc/wx city 城市名:深圳 实例: https://wis.qq.com/city/like?sourcepc&city深圳{"data":{"101280601":"广东, 深圳"},&q…

kafka生产者api和数据操作

Kafka 生产者 发送流程 消息发送过程中涉及到两个线程——main线程和Sender线程 main线程 使用serializer(并非java默认)序列化数据,使用partitioner确认发送分区 在main线程中创建了一个双端队列RecordAccumulator,main线程将…

「 C++ 11」std::thread “invalid use of non-static member function“问题处理

(705条消息) 「 C 11」std::thread “invalid use of non-static member function“问题处理_c invalid use of non-static member function_谁吃薄荷糖的博客-CSDN博客 也可以使用function bind解决.

数据库监控与调优【十八】—— Percona Toolkit调优神器安装与使用

Percona Toolkit调优神器安装与使用 Percona Toolkit安装 本文基于Percona Toolkit 3.2.0,理论支持所有版本。 Percona Toolkit是一款MySQL世界里面非常实用的工具套件,如何安装它。 Windows系统 不支持。详见https://forums.percona.com/discussion/…

I2C总线协议详解

I2C总线物理拓扑结构 I2C总线物理拓扑图 I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来 产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时&#…

训练自己的ChatGPT 语言模型(一).md

0x00 Background 为什么研究这个? ChatGPT在国内外都受到了广泛关注,很多高校、研究机构和企业都计划推出类似的模型。然而,ChatGPT并没有开源,且复现难度非常大,即使到现在,没有任何单位或企业能够完全复…

echarts图中,点击高亮,滑动条位置不需要更新配置的问题

首先要监听一下echarts中滑动的事件,代码如下:echarts图中,点击高亮,滑动条位置不需要更新配置的问题 这样可以监听到滑动块的start的位置和end的位置,然后记录一下start和end的值。 接着在点击事件的时候&#xff0c…

【javascript】全选按钮

当点击全选按钮时&#xff0c;与之相关的所有选项都会被自动框选。 效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"></head><body><label><input type"checkbox" i…