MyBatis学习笔记之首次开发及文件配置

文章目录

  • MyBatis概述
    • 框架
    • 特点
  • 有关resources目录
  • 开发步骤
  • 从XML中构建SqlSessionFactory
  • MyBatis中有两个主要的配置文件
  • 编写MyBatis程序
  • 关于第一个程序的小细节
  • MyBatis的事务管理机制
    • JDBC
    • MANAGED
  • 编写一个较为完整的mybatis
  • junit测试
  • mybatis集成日志组件

MyBatis概述

框架

  • 在文献中看到的framework被翻译为框架
  • Java常用框架:
    • SSM三大框架:Spring + SpringMVC +MyBatis
    • SpringBoot
    • SpringCloud
    • 等。。
  • 枢架其实就是对通用代码的封装,提前写好子了一堆接口和类,我们可以在做项目的时候直接引入这些接口和类(引入框架),基于这些现有的接口和类进行开发,可以大大提高开发效率
  • 框架一般都法jar包的形式存在。(jar包中有class文件以及各种配置文件等。)
  • SSM三大框架的学习顺序:MyBatis、Spring.SpringMVC(仅仅是建议)

特点

  • 支持定制化SQL、存储过程、基本映射以及高级映射
  • 避免了几乎所有的JDBC代码中手动设置参数以及获取结果集
  • 支持XML开发,也支持注解式开发。【为了保证sql语句的灵活,所以mybatis大部分是采用XML方式开发。】
  • 将接口和Java的POJOs(Plain Ordinary Java Object,简单普通的Java对象)映射成数据库中的记录
  • 体积小好学:两个jar包,两个XML配置文件。
  • 完全做到sql解耦合。
  • 提供了基本映射标签。
  • 提供了高级映射标签。
  • 提供了XML标签,支持动态SQL的编写。

有关resources目录

放在这个目录当中的,一般都是资源文件,配置文件
直接访问在resources目录下的资源,等同于放到了类的根路径下。

开发步骤

  • 第一步:打包方式jar
<packaging>jar<packaging>
  • 第二部:引入依赖
<dependencies>
	<!--mybatis依赖-->
	<dependency>
		<groupId>org.mybatis</groupId>		
		<artifactId>mybatis</artifactId>
		<version>3.5.10</version>
	</dependency>
	
	<!--mysql驱动依赖-->
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>	
		<version>8.0.38</version>
	</dependency>
</dependencies>
  • 第三步:编写MyBatis核心配置文件:mybatis-config.xml

注意:
第一:这个文件名不是必须叫做mybatis-config.xml,可以用其他的名字。只是大家都采用这个名字。
第二:这个文件存放的位置也不是固定的,可以随意,但一般情况下,会放到类的根路径下。

mybatis-config.xml文件中的配置信息不理解没关系,先把数据库的信息修改以下即可。其他的别动

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<environments default=""development">
		<environment id="development">
			<transactionHanager type="JDBC/>
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.cj.jdbc.Drivercom.mysql.cj.jdbc.Driver"/>	
				<property name="url" value="jdbc:mysql://localhost:3306/demo"/>//这个是找到mysql并找到要操作的数据库
				<property name="username" value="root"/>//mysql的账号
				<property name="password" value="root"/>//mysql的密码		
			</dataSource>
		</environment>
	</environments>
	<mappers>
	<mapper resource="CarMapper.xml"/>//配置Mapper的地方
	</mappers>
</configuration>
  • 第四步:编写XxxxMapper.xml文件。

在这个配置文件当中编写SQL语句
这个文件名也不是固定的,放的位置也不是固定的,这里给它起个名字,叫做CarMapper.xml
把它暂时放到类的根路径下。

<mapper namespace="fdsafdsa">//这个namespace暂时可以随便取
	<!--insert语句,id是这条SQL语句的唯一标识。这个id就代表了这条SQL语句。-->
	<insert id="insertCar">
		insert into t_car(id, car_num, brand, guide_price, produce_time ,car_type)
		values(null, '1083','丰田霸道',30.0," 2088-10-11','燃油车')
	</insert>
</mapper>
  • 第五步:在mybatis-config.xml文件中指定XxxxMapper.xml文件的路径:
<mapper resource="CarMapper.xml"/>

注意:resource属性会自动从类的路径下开始查找资源


  • 第六步:开始编写MyBatis程序(使用mybatis的类库,编写mybatis程序,连接数据库,做增删改查就行了。)

从XML中构建SqlSessionFactory

从官方的这句话中,能想到什么

  • 第一:在MyBatis中一定是有一个很重要的对象,这个对象是:SqlSessionFactory对象。
  • 第二:SalSessionFactory对象的创建需要XML

XML是什么?

  • 他一定是一个配置文件

MyBatis中有两个主要的配置文件

其中一个是:mybatis-config.xml,这是核心配置文件,主要配置连接数据库的信息等。(一个)
另一个是:XxxMapper.xml,这个文件是专门用来编写SQL语句的配置文件。(一个表一个)

  • t_user表,一般会对应一个UserMapper.xml
  • t_student表,一般会对应一个StudentMapper.xml

编写MyBatis程序

zaiMyBatis中,负责执行SQL语句的那个对象叫做什么?

  • SqlSession

SqlSession是专门用来执行SQL语句的,是一个Java程序和数据库之间的一次会话

要想获取SqlSession对象,需要先获取SqlSessionFactory对象,通过SqlSessionFactory工厂来实现SqlSession对象。

那如何获取SqlSessionFactory对象?
通过SqlSessionFactoryBuilder对象的build方法,来获取一个SqlSessionFactory对象。

mybatis的核心对象包括:

  • SqlSessionFactoryBuilder
  • SqlSessionFactory
  • SqlSession
    SqlSessionFacotryBuilder --> SqlSessionFactory -->SqlSession
public class MyBatisIntroductionTest {
	public static void main(string[] args) {
	//获取SqlSessionFactoryBuilder对象
	sqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
	//获取SqlSessionFactory对象
	//Inputstream is = new FileInputStream( name: "mybatis-config.xml文件的路径");
	InputStream is = Resources.getResourceAsStream( "mybatis-config.xml");
	//Resources.getResourceAsStream默认就是从类的根路径下开始查找资源
	SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
	//获取SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession():
	
	//执行SQL语句
	int count = sqlSession.insert( s: "insertCar"");//返回值是影响数据库表当中的记录条数。
	
	System.out.println("插入了几条记录:" + count);
	
	//手动提交
	sqlSession.commit();
	}
}

关于第一个程序的小细节

  • mybatis中sql语句的结尾";"可以省略。
  • Resources.getResourceAsStream

小技巧:以后凡是遇到resource这个单词,大部分情况下,这种加载资源的方式就是从类的根路径下开始加载。(开始查找)
优点:采用这种方式,从类路径当中加载资源,项目的移植性很强。项目从windows移植到linux,代码不需要修改,因为这个资源文件一直都在类路径当中。

  • InputStream is = new FileInputstream(“d:\lmybatis-config.xml”);

采用这种方式也可以。
缺点:可移植性太差,程序不够健壮。可能会移植到其他的操作系统当中。导致以上路径无效,还需要修改java代码中的路径。这样违背了OCP原则。

  • 己经验证了:

mybatis核心配置文件的名字,不一定是: mybatis-config.xml。可以是其它名字。
mybatis核心配置文件存放的路径,也不一定是在类的根路径下。可以放到其它位置。但为了项目的移植性,他壮性,最好将这个配置文件放到类路径下面。

  • InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(“mybatis-config .xml”);

classLoader.getSystemclassLoader()获取系统的类加载器。
系统类加载器有一个方法叫做:getResourceAsStream
它就是从类路径当中加载资源的。
通过源代码分析发现:
Inputstream is = Resources.getResourceAsStream("mybatis-config.xml");底层的源代码其实就是:
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xm1");

  • CarMapper.xml文件的名字是固定的吗? CarMapper.xml文件的路径是固定的吗?

都不是固定的。
resource属性:这种方式是从类路径当中加载资源
url属性:这种方式是从绝对路径当中加载资源。

MyBatis的事务管理机制

  • 在mybatis-config.xml文件中,可以通过以下的配置进行mybatis的事务管理
<transactionMapper type="JDBC"/>
  • type属性的值就包括两个:JDBC和MANAGED(大小写无所谓)
  • 在mybatis中提供了两种事务管理机制:JDBC事务管理器,MANAGED事务管理器

只要autoCommit是true,就表示没有开启事务。
只有autoCommit是false的时候,就表示开启了事务。

JDBC

mybatis框架自己管理事务,自己采用原生的JDBC代码去管理事务

conn.setAutoCommit(false);//开启事务
//...业务处理...
conn.commit();//手动提交事务

如果编写的是下面的代码

SqlSession sqlSession = sqlSessionFactory.openSession(true);

表示的是没有开启事务,因为这种方式压根不会执行:conn.setAutoCommit(false);
在JDBC事务中,没有执行conn.setAutoCommit(false);那么autoCommit就是true。
如果autoCommit是true,就表示没有开启事务。只要执行任意一条DML语句就要提交一次。

如果你没有在JDBC代码中执行:conn.setAutoCommit(false);的话,默认的autoCommit是false

MANAGED

mybatis不再负责事务的管理了,事务管理交给其他容器来负责,例如:spring,

我不管事务了,你来负责把

对于我们当前的单纯的只有mybatis的情况下,如果配置为:MANAGED
那么事务这块是没人管的。没有人管理事务表示事务压根没开启

编写一个较为完整的mybatis

package org.example;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisCompleteText {
    public static void main(String[] args) {
        SqlSession sqlsession = null;
        try {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlsession = sqlSessionFactory.openSession();//执行SQL语句,处理相关业务
            int count = sqlsession.insert("insertCar");
            System.out.println(count);
            //执行到这里,没有发生任何异常,提交事务。终止事务。sqlsession.commit();
        }catch (Exception e) {
            //最好回滚事务
            if (sqlsession != null) {
                sqlsession.rollback();
            }
            e.printStackTrace();
        }
		finally {
            //关团会话(释放资源>
            if (sqlsession != null) {
                sqlsession.close();
            }
        }
    }
}

junit测试

为了保证自己写的模块方法没问题,需要对其进行测试

单元测试方法写多少个
一般是一个业务方法对应一个测试方法
测试方法的规范:public void testXxxx(){}
测试方法的方法名:以test开始,假设测试的方法是sum,这个测试方法名:testSum
@Test注释非常重要,被这个注解标注的方法就是一个单元测试方法


单元测试中有两个重要的概念
一个是实际值(被测试的业务方法的真正执行结果)
一个是期望值(执行了这个业务方法之后,你期望的执行结果是多少)

//写的模块
package org.example;

public class MathServer {
    public int sum(int a,int b){
        return a+b;
    }
    public int sub(int a, int b){
        return a-b;
    }
}
//测试
package service;

import org.example.MathServer;
import org.junit.Assert;
import org.junit.Test;

public class MathServerTest {
    @Test
    public void testSum(){
        MathServer mathServer = new MathServer();
        //获取实际值
        int actual = mathServer.sum(1,2);
        //获取期望值
        int expected = 3;
        //加断言进行测试
        Assert.assertEquals(expected,actual);
    }

    @Test
    public void testSub(){
        MathServer mathServer = new MathServer();
        //实际值
        int actual = mathServer.sub(10,5);
        //期望值
        int expected = 5;
        Assert.assertEquals(expected,actual);
    }
}

在这里插入图片描述
绿色测试通过

mybatis集成日志组件

这玩意能让我们调试起来更加方便

在核心配置文件里面(mybatis-config.xml)中配置settings
这是MyBatis中极为重要的调整设置,它们会改变MyBatis的运行时行为。
链接:https://mybatis.net.cn/configuration.html#settings

↑可以查看settings中可以设置什么,以及它的作用

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!--开启mybatis自己对日志的实现-->
    </settings>

常见的mybatis集成日志组件有哪些呢?(在上面代码value中设置的还有啥)

  • SLF4J(沙拉风),是一个日志标准,其中有一个框架叫做logback,它实现了沙拉风规范
  • LOG4J
  • LOG4J2
  • STDOUT_LOGGING

其中STDOUT_LOGGING是标准日志,mybatis已经实现了这种标准日志,mybatis框架本身已经实现了这种标准
what is more标签是有它的顺序的在configuration标签中得按照它的标签顺序进行排序,不然会报错


集成logback日志框架。logback日志框架实现了slf4j标准

  • 第一步:引入logback的依赖
<!--第一次引入也挺快的-->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.11</version>
</dependency>
  • 第二步:引入logback所必须的xml配置文件
    这个配置文件的名字必须叫做:logback.xml或logback_test.xml,不能是其他的名字
    这配置文件必须放到类的根路径下,不能是其他的位置。

注意注意,不要用1.4开头的那个版本,会出现输出不了日志的情况

<!--logback配置文件的内容-->
<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="false">
    <!--控制台输出-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm: ss.SSS} [%thread] %-5level %logger{50} - %msg8n</pattern>
        </encoder>
    </appender>
    <!--按照每天生成日志文件-->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
           <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yYvy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度Xmsg:日志消息,%n是换行符--><pattern>%d{yyyy-MMN-dd HH:mm:ss.ssS} [%thread] %-5level %logger{50}- %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.sizeBasedTriggeringPolicy">
            <MaxFilesize>100MB</MaxFilesize>
        </triggeringPolicy>
    </appender>

    <!--mybatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.connection" level="DEBUG" />
    <logger name="java.sql.Statement" level="DEBUG" />
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    
    <!--日志输出级别,logback日志级别包括五个:TRACE< DEBUG<INFO<WARN < ERROR -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE"/>
    </root>
</configuration>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Excel VLOOKUP使用详解

VLOOKUP语法格式&#xff1a; VLOOKUP(lookup_value,table_array,col_index_num,range_lookup) VLOOKUP&#xff08;要查找的值&#xff0c;查找区域&#xff0c;要返回的结果在查找区域的第几列&#xff0c;精确匹配或近似匹配&#xff09; 一、精确查找 根据姓名查找对应…

FPGA Verilog移位寄存器应用:边沿检测、信号同步、毛刺滤波

文章目录 1. 端口定义2. 边沿检测3. 信号同步4. 信号滤波5. 源码6. 总结 输入信号的边沿检测、打拍同步、毛刺滤波处理&#xff0c;是FPGA开发的基础知识&#xff0c;本文介绍基于移位寄存器的方式&#xff0c;实现以上全部功能&#xff1a;上升沿、下降沿、双边沿检测、输入信…

个人使用:Windows下 OpenCV 的下载安装(2021.12.4详细)

一、下载OpenCV   到OpenCV官网Release(发布)板块下载OpenCV-4.5.4 Windows。 下载后是这样的 然后双击他&#xff0c;解压&#xff0c;就是大佬们说的安装&#xff0c;实质就是解压一下&#xff0c;解压完出来一个文件夹&#xff0c;其他什么也没发生。你把这个文件夹放在哪…

STM32(HAL库)驱动SHT30温湿度传感器通过串口进行打印

目录 1、简介 2、CubeMX初始化配置 2.1 基础配置 2.1.1 SYS配置 2.1.2 RCC配置 2.2 软件IIC引脚配置 2.3 串口外设配置 2.4 项目生成 3、KEIL端程序整合 3.1 串口重映射 3.2 SHT30驱动添加 3.3 主函数代 3.4 效果展示 1、简介 本文通过STM32F103C8T6单片机通过HAL库…

uniapp uni实人认证

uni实人认证依赖 目前仅支持App平台。 h5端活体人脸检测&#xff0c;使用的是百度云的h5人脸实名认证 使用要求 1、app端 在使用前&#xff0c;请确保您已注册DCloud账号&#xff0c;并已完成实名认证。 然后需要按文档开通服务 业务开通 | uni-app官网 2、h5端 在使用前…

STM32 ws2812b 最快点灯cubemx

文章目录 前言一、cubemx配置二、代码1.ws2812b.c/ws2812b.h2.主函数 前言 吐槽 想用stm32控制一下ws2812b的灯珠&#xff0c;结果发下没有一个好用的。 emmm&#xff01;&#xff01;&#xff01; 自己来吧&#xff01;&#xff01;&#xff01;&#xff01; 本篇基本不讲原理…

Unity DOTS如何优雅地实现ECS框架下的定时器Timer系统(无对象池,零GC)

实现定时器并不复杂&#xff0c;就是写个类存放回调&#xff0c;再写个类来统一管理这些回调类。但是ECS写代码的方式变了&#xff0c;所以还是有些区别的。 实现过程中需要注意的几点&#xff1a; 1、由于IComponentData不能存放managed类型的数据&#xff0c;所以无法用常规…

C#使用DataGridView模拟绘图

接到一个需求&#xff0c;绘制一个水管线的图片&#xff0c;这种管线可以有12种分段方法&#xff0c;最后将这12种分段方法合并后在一条水管线上展示&#xff0c;要求&#xff1a; ⒈支持分段的属性展示&#xff1b; ⒉要求每个分段都能清晰展示&#xff0c;分段数在0&#xff…

从CPU缓存结构到原子操作

文章目录 一、CPU缓存结构1.1 CPU的多级缓存1.2 Cache Line 二、写回策略三、缓存一致性问题及解决方案3.1 缓存一致性问题3.2 解决方案3.2.1 总线嗅探3.2.2 事务的串行化3.2.3 MESI 四、原子操作4.1 什么是原子操作4.2 c 标准库的原子类型4.2.1 atomic<T\>4.2.2 is_lock…

Python(四):Pycharm的安装配置

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

【基于FPGA的芯片设计】32位RISC-V存储器

实验板卡&#xff1a;xc7a100tlc sg324-2L&#xff0c;共20个开关 实验要求

RabbitMQ常用工作模式+整合springboot

目录 1.MQ的相关概念 1.1 什么是MQ消息中间件 1.2 为什么使用MQ (1) 应用解耦 (2) 异步提速 (3)削峰填谷 1.3 使用MQ的劣势 1.4 常见的MQ组件​​​​​​​ 2. RabbitMQ的概述 2.1 RabbitMQ的概念 2.2 RabbitMQ的原理 2.3 安装RabbitMQ 3. RabbitMQ 的工作模式…

【NLP】Word2Vec原理和认识

一、介绍 Word2Vec是NLP领域的最新突破。Tomas Mikolov是捷克计算机科学家&#xff0c;目前是CIIRC&#xff08;捷克信息学&#xff0c;机器人和控制论研究所&#xff09;的研究员&#xff0c;是word2vec研究和实施的主要贡献者之一。词嵌入是解决NLP中许多问题不可或缺的一部分…

基于B/S架构SaaS服务的实验室信息系统(LIS)

实验室信息系统LIS源码 实验室信息系统&#xff08;Laboratory Information System&#xff09;&#xff0c;简称LIS&#xff0c;是一个全面基于网络化应用&#xff0c;能够帮助用户按照规范内容和规范流程进行多角色、多层次检验信息及资源管理的系统。通过条码管理系统从HIS…

云计算的学习(三)

三、云计算中的网络基础知识 1.虚拟化中网络的架构 1.1虚拟化中网络的架构 二层交换机作为接入交换机使用&#xff0c;三层交换机可以作为汇聚交换机或核心交换机&#xff0c;在抛开网络安全设备时&#xff0c;路由器直接连接在互联网上。 1.2广播和单播 物理服务器内部主要…

Iceberg从入门到精通系列之十七:Apache InLong往Iceberg同步数据

Iceberg从入门到精通系列之十七&#xff1a;Apache InLong往Iceberg同步数据 一、概览二、版本支持三、依赖项四、SQL API 用法五、多表写入六、动态表名映射七、动态建库、建表八、动态schema变更九、Iceberg Load 节点参数十、数据类型映射 一、概览 Apache Iceberg是一种用…

Flutter系列文章-Flutter环境搭建和Dart基础

Flutter是Google推出的一个开源的、高性能的移动应用开发框架&#xff0c;可以用一套代码库开发Android和iOS应用。Dart则是Flutter所使用的编程语言。让我们来看看如何搭建Flutter开发环境&#xff0c;并了解Dart语言的基础知识。 一、Flutter环境搭建 1. 安装Flutter SDK …

springboot+ElasticSearch+Logstash+Kibana实现日志采集ELK

ElasticSearchLogstashKibana日志管理 一、什么是ELK? ELK是Elasticsearch、Logstash、Kibana的简称&#xff0c;这三者是核心套件&#xff0c;但并非全部。一般情况下我们可以把日志保存在日志文件当中&#xff0c;也可以把日志存入数据库当中。但随着业务量的增加&#xf…

搭建 Java 部署环境,部署 Web 项目到 Linux

为了进行部署&#xff0c;把写好的 java web 程序放到 Linux 上&#xff0c;需要先把对应的依赖的软件 (环境) 搭建好&#xff0c;安装一些必要的软件程序 JDKTomcatMySqL jdk 直接使用包管理器进行安装(基于yum安装) 一、yum 1、认识 yum yum (Yellow dog Updater, Modified…

6. Java + Selenium 环境搭建

前提&#xff1a;Java 版本最低要求为 8&#xff1b;推荐使用 chrome 浏览器 chrome Java 1. 下载 chrome 浏览器&#xff08;推荐&#xff09; 2. 查看 chrome 浏览器版本 重点记住前两位即可。 3. 下载 chrome 浏览器驱动 下载链接&#xff1a; https://chromedriver.…