MyBatis基础知识

news2025/5/31 20:28:06

1 JDBC基础知识

1.1 JDBC简介

JDBC是使用Java语言操作关系型数据库的一套API,全称Java DataBase Connectivity,Java数据库连接。JDBC定义了操作所有关系型数据库的规则,同一套Java代码可以操作不同的关系型数据库。也就是JDBC是Java语言操作数据库的接口规范,MySQL、Oracle、DB2等数据库厂商实现JDBC接口,使开发者可以通过JDBC接口操作自己家的数据库。数据库自己的JDBC接口实现类叫作驱动(以jar包形式提供)。

1.2 JDBC使用

  1. 导入MySQL驱动jar包

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>6.0.2</version>
</dependency>

2、入门使用

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class Main {
    public static void main(String[] args) {
        try {
            String url = "jdbc:mysql://localhost:3306/db1";
            String user = "root";
            String password = "1234";
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            Connection connection = DriverManager.getConnection(url,user,password);
            //定义SQL语句
            String sql = "update account set monkey = 2000 where id = 1";
            //获取执行SQL的Statement
            Statement statement = connection.createStatement();
            //执行SQL,返回值代表受影响的行数
            int rowCount = statement.executeUpdate(sql);
            //释放资源
            statement.close();
            connection.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

1.3 JDBC API详解

1.3.1 DriverManager

1、注册驱动对象
public static synchronized void registerDriver(java.sql.Driver driver)
    throws SQLException {

    registerDriver(driver, null);
}



2、获取数据库连接
public static Connection getConnection(String url,
    String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();

    if (user != null) {
        info.put("user", user);
    }
    if (password != null) {
        info.put("password", password);
    }

    return (getConnection(url, info, Reflection.getCallerClass()));
}

1.3.2 Connection

1、获取执行SQL的Statement

//普通执行SQL对象,存在SQL注入风险
Statement createStatement() throws SQLException;
//预编译SQL的执行SQL对象,可预防SQL注入
PreparedStatement prepareStatement(String sql) throws SQLException;

2、事务管理

void setAutoCommit(boolean autoCommit) throws SQLException;
boolean getAutoCommit() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;

事务使用如下:

String url = "jdbc:mysql://localhost:3306/db1";
String user = "root";
String password = "1234";
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection(url,user,password);
//定义SQL语句
String sql1 = "update account set monkey = 2000 where id = 1";
String sql2 = "update account set monkey = 3000 where id = 2";
//获取执行SQL的Statement
Statement statement = connection.createStatement();
try {
    //我们希望sql1和sql2同成功同失败,因此在执行SQL前开启事务
    connection.setAutoCommit(false);
    //执行SQL,返回值代表受影响的行数
    int rowCount1 = statement.executeUpdate(sql1);
    int rowCount2 = statement.executeUpdate(sql2);
    //手动提交事务
    connection.commit();
}catch (Exception e) {
    //如果执行SQL的过程中发生异常,回滚事务
    connection.rollback();
}

//释放资源
statement.close();
connection.close();

1.3.3 Statement

  1. 执行DDL、DML语句

/**
 * Executes the given SQL statement, which may be an <code>INSERT</code>,
 * <code>UPDATE</code>, or <code>DELETE</code> statement or an
 * SQL statement that returns nothing, such as an SQL DDL statement.
 *<p>
 * <strong>Note:</strong>This method cannot be called on a
 * <code>PreparedStatement</code> or <code>CallableStatement</code>.
 * @param sql an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
 * <code>DELETE</code>; or an SQL statement that returns nothing,
 * such as a DDL statement.
 *
 * @return either (1) the row count for SQL Data Manipulation Language (DML) statements
 *         or (2) 0 for SQL statements that return nothing
 *
 * @exception SQLException if a database access error occurs,
 * this method is called on a closed <code>Statement</code>, the given
 * SQL statement produces a <code>ResultSet</code> object, the method is called on a
 * <code>PreparedStatement</code> or <code>CallableStatement</code>
 * @throws SQLTimeoutException when the driver has determined that the
 * timeout value that was specified by the {@code setQueryTimeout}
 * method has been exceeded and has at least attempted to cancel
 * the currently running {@code Statement}
 */
int executeUpdate(String sql) throws SQLException;

返回值:1、DML语句返回影响的行数 2、DDL语句执行成功后返回0

  1. 执行DQL语句

/**
 * Executes the given SQL statement, which returns a single
 * <code>ResultSet</code> object.
 *<p>
 * <strong>Note:</strong>This method cannot be called on a
 * <code>PreparedStatement</code> or <code>CallableStatement</code>.
 * @param sql an SQL statement to be sent to the database, typically a
 *        static SQL <code>SELECT</code> statement
 * @return a <code>ResultSet</code> object that contains the data produced
 *         by the given query; never <code>null</code>
 * @exception SQLException if a database access error occurs,
 * this method is called on a closed <code>Statement</code>, the given
 *            SQL statement produces anything other than a single
 *            <code>ResultSet</code> object, the method is called on a
 * <code>PreparedStatement</code> or <code>CallableStatement</code>
 * @throws SQLTimeoutException when the driver has determined that the
 * timeout value that was specified by the {@code setQueryTimeout}
 * method has been exceeded and has at least attempted to cancel
 * the currently running {@code Statement}
 */
ResultSet executeQuery(String sql) throws SQLException;

1.3.3 SQL注入问题

SQL注入是通过输入特定字符来修改事先已经定义好的SQL语句,用来达到执行代码对服务器进行攻击的方式。下面以输入用户名、 密码来登录为例说明。

正常情况,登录成功:

try {
    String url = "jdbc:mysql://localhost:3306/db1";
    String user = "root";
    String password = "1234";
    //注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //获取连接
    Connection connection = DriverManager.getConnection(url, user, password);
    String name = "zhangsan";
    String pwd = "123";
    //定义SQL语句
    String sql = "select * from user where username='" + name + "' and password='" + pwd + "'";
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery(sql);
    if (resultSet.next()) {
        System.out.println("登录成功");
    } else {
        System.out.println("登录失败");
    }
    //释放资源
    resultSet.close();
    statement.close();
    connection.close();
} catch (Exception e) {
    throw new RuntimeException(e);
}

输入敏感字符,存在注入情况,也可以登录成功:

try {
    String url = "jdbc:mysql://localhost:3306/db1";
    String user = "root";
    String pwd = "' or '1' ='1";
    //注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //获取连接
    Connection connection = DriverManager.getConnection(url, user, password);
    String name = “用户名随便写” ;
    String pwd = "123";
    //定义SQL语句
    String sql = "select * from user where username='" + name + "' and password='" + pwd + "'";
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery(sql);
    if (resultSet.next()) {
        System.out.println("登录成功");
    } else {
        System.out.println("登录失败");
    }
    //释放资源
    resultSet.close();
    statement.close();
    connection.close();
} catch (Exception e) {
    throw new RuntimeException(e);
}

注入后的SQL语句如下:

select * from user where username =‘用户名随便写’ and password =‘ ’ or ‘1’=‘1’

1.3.4 PreparedStatement

String url = "jdbc:mysql://localhost:3306/db1?userServerPrepStmts=true";
String user = "root";
String password = "1234";
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection(url, user, password);
//定义SQL语句
String sql = "select * from user where username=? and password=?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"zhangsan");
preparedStatement.setString(2,"1234");
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
    System.out.println("登录成功");
} else {
    System.out.println("登录失败");
}
//释放资源
resultSet.close();
preparedStatement.close();
connection.close();

PreparedStatement在setXXX设置参数时会将传入敏感字符进行转义,从而解决SQL注入问题。

预编译功能默认是关闭的,通过配置URL可以打开预编译功能,jdbc:mysql://localhost:3306/db1?userServerPrepStmts=true

1.3.5 ResultSet

String url = "jdbc:mysql://localhost:3306/db1";
String user = "root";
String password = "1234";
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection(url,user,password);
//定义SQL语句
String sql = "select * from user";
//获取执行SQL的Statement
Statement statement = connection.createStatement();
ResultSet set =  statement.executeQuery(sql);
while (set.next()) {
    int id = set.getInt("id”);//传入列的字段名
    String name = set.getString("name”);//传入列的字段名
    String pd = set.getString(3);//传入列的编号
}
//释放资源
set.close();
statement.close();
connection.close();

1.4 数据库连接池

1.4.1 数据库连接池简介

建立数据库连接很耗时、关闭数据库连接也耗时

1.4.2 Druid数据库连接池

1、导入jar包

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.1.16</version>
</dependency>
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>6.0.2</version>
</dependency>

2、定义配置文件

新建druid.properties文件,并配置如下:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db1?userServerPrepStmts=true
username=root
password=1234
initialSize=5
maxActive=10
#最大等待时间,单位毫秒
maxWait=3000

注意健的名称固定

3、加载配置文件、获取数据库连接池对象、获取连接

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;

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

        try {
            Properties properties = new Properties();
            properties.load(new FileInputStream("druid.properties"));
            DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
            Connection connection = dataSource.getConnection();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

2 MyBatis基础知识

2.1 简介

官网:https://mybatis.org/mybatis-3/zh/index.html

2.2 入门使用

  1. 建库建表

create database db1;

create table user(id int primary key auto_increment,username varchar(20),password varchar(20),gender char(1),addr varchar(30));

  1. 导入mybatis依赖坐标

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.11</version>
</dependency>

<!--MySQL 驱动坐标 -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>6.0.2</version>
</dependency>
<!-- 单元测试坐标-->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.2</version>
  <scope>test</scope>
</dependency>
  1. Mybatis配置文件

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/db1?userServerPrepStmts=true"/>
                <property name="username" value="root"/>
                <property name="password" value="1234"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>

        <!--加载SQL映射文件 -->
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>
  1. sql映射文件

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
    <select id="selectAll" resultType="User">
        select * from User;
    </select>
</mapper>
  1. 编码

        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session = sqlSessionFactory.openSession();
            List<User> userList =  session.selectList("test.selectAll");//名称空间.sqlId
            System.out.println(userList);
            session.close();//释放资源
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

2.3 Mapper代理开发

1.新建Mapper接口

返回值类型要与SQL映射文件中一致;方法名要和SQL映射文件SQL语句的ID相同。

package mapper;

import pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> selectAll();
}

2.修改UserMapper.xml中的命名空间属性

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.UserMapper">
    <select id="selectAll" resultType="pojo.User">
        select * from User;
    </select>
</mapper>

3.修改mybatis-config.xml中SQL映射文件加载方式

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/db1?userServerPrepStmts=true"/>
                <property name="username" value="root"/>
                <property name="password" value="mrxi2016."/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- 包扫描方式,扫描resources/mapper包下面的所有SQL映射文件-->
       <package name="mapper"/>
    </mappers>
</configuration>

注意原来的<mapper resource="mapper/UserMapper.xml"/>方式也可用。包扫描方式省事,不用配置多个SQL映射文件

4.获取mapper对象执行SQL

String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
    inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession session = sqlSessionFactory.openSession();
    UserMapper userMapper = session.getMapper(UserMapper.class);
    List<User> userList = userMapper.selectAll();
    System.out.println(userList);
    session.close();
} catch (IOException e) {
    throw new RuntimeException(e);
}

2.4 配置文件完成增删改查

建库建表

Create database db1;
create table tb_brand(id int primary key auto_increment,brand_name varchar(20),company_name varchar(20),ordered int,description varchar(100),status int);

Brand实体类

package pojo;

public class Brand {
    private int id;
    private String brandName;
    private String companyName;
    private int ordered;
    private int status;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public int getOrdered() {
        return ordered;
    }

    public void setOrdered(int ordered) {
        this.ordered = ordered;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }


    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", status=" + status +
                '}';
    }
}

2.4.1 查询所有数据

BrandMapper

package mapper;

import pojo.Brand;

import java.util.List;

public interface BrandMapper {
    /**
     * 查询所有数据
     * @return
     */
    List<Brand> selectAll();
}

BrandMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.BrandMapper">
  
    <select id="selectAll" resultType="pojo.Brand">
        select * from tb_brand;
    </select>
  
</mapper>

存在以下问题:表中的字段名称和实体类的属性名称不一致时,不能自动封装。

解决方法1:起别名,给表中的不一样的字段起别名,别名就是实体属性名称

如下:

<mapper namespace="mapper.BrandMapper">
    
    <select id="selectAll" resultType="pojo.Brand">
        select id,brand_name as brandName,company_name as companyName,ordered,status from tb_brand;
    </select>
   
</mapper>

起别名缺点是每次定义select查询都定义一次别名,可以定义SQL片段解决,引入SQL片段即可,如下:

<mapper namespace="mapper.BrandMapper">
  
   
    <sql id="brand_column">
        id,brand_name as brandName,company_name as companyName,ordered,status

    </sql>
  
    <select id="selectAll" resultType="pojo.Brand">
        select <include refid="brand_column"/> from tb_brand;
    </select>
</mapper>

解决方法2:定义resultMap标签(推荐),在select中用resultMap代替resultTpye

<mapper namespace="mapper.BrandMapper">
     <!-- 
        id:唯一标识
        type:实体类型,支持别名
     -->
    <resultMap id="brandResultMap" type="pojo.Brand">
        <!-- 
        result标签,id定义主键,result定义一般字段。
        column:表中的字段  property:实体属性
        -->
        <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>
    <select id="selectAll" resultMap="brandResultMap">
        select * from tb_brand;
    </select>

</mapper>

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

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

相关文章

分布式高级篇3 —— RabbitMQ

一、RabbitMQ1、RabbitMQ 介绍2、RabbitMQ 的相关概念3、安装 RabbitMQ4、交换机类型&#xff08;1&#xff09;direct - 直连交换机&#xff08;2&#xff09;fanout - 扇出交换机&#xff08;3&#xff09;topic - 主题交换机5、RabbitMQ 管理界面6、SpringBoot 整合RabbitMQ…

Autowired注解源码解析

一、Autowired注解的原理的概览 我们都知道一个Bean的大致生命周期有这几个阶段&#xff0c;实例化--> 属性填充 --> 初始化 --> 销毁回调 其中Autowired作用的时间就是在属性填充阶段&#xff0c;而且是通过AutowiredAnnotation BeanPostProcessor类进行处理的。注…

android14预览版介绍及解读

​ 前言&#xff1a; android14快要来了&#xff0c;最近2月8日&#xff0c;android14的第一个开发者预览版发布了&#xff0c;正式版大约会和往常一样&#xff0c;大概率在六月份左右推出&#xff0c;八九月份时会有国内会有第一批手机支持安卓14。所以&#xff0c;本文就带…

为什么要用频谱分析仪测量频谱?

频谱分析仪是研究电信号频谱结构的仪器&#xff0c;用于信号失真度、调制度、谱纯度、频率稳定度和交调失真等信号参数的测量&#xff0c;可用以测量放大器和滤波器等电路系统的某些参数&#xff0c;是一种多用途的电子测量仪器。从事通信工程的技术人员&#xff0c;在很多时候…

免费下载学术文献的网站,好用!

推荐几款好用的免费下载学术文献网站&#xff0c;让你的查找文献环节更加事半功倍&#xff01; 1、Open Access Library&#xff08;OALib&#xff09;图书馆让学者可以免费下载学术文献和论文&#xff0c;并在这个平台上发表自己的论文。提供Open Access数据库资源。 2、文献…

Spring Security实现RBAC权限模型练习

1.Spring Security介绍 Spring Security的核心功能就是认证、授权、攻击防护&#xff0c;Spring Boot项目启动之后会自动进行配置&#xff0c;其核心就是一组链式过滤器。 如下图所示&#xff0c;对于一个用户请求&#xff0c;Username Password Authentication Filter验证用…

2022年API安全研究报告

导读 API应用的增速与其安全发展的不平衡,使其成为恶意攻击的首选目标,围绕API安全的攻防较量愈演愈烈。 2022年API安全风险概况 2022年平均每月遭受攻击的API数量超21万 2022年全年平均每月遭受攻击的API数量超过21万,第二季度(4-6月)遭受攻击的API数量达到高峰,月均…

经典文献阅读之--IGP2(可解释性目标的自动驾驶预测与规划)

0. 简介 对于自动驾驶的预测和规划而言&#xff0c;能够有效的对目标产生可解释性是非常有必要的&#xff0c;而《Interpretable Goal-based Prediction and Planning for Autonomous Driving》文中就提出了一种综合的自动驾驶预测和规划系统&#xff0c;它利用合理的逆规划来…

php mysql娱乐场所运营管理系统

目 录 1 背景与意义 3 1.1 研究背景 3 1.2 国内外发展状况研究 3 2 系统开发环境与技术 4 2.1 PHP介绍 4 2.2 MYSQL介绍 5 2.3 APACHE介绍 6 2.4 dreameaver介绍 7 2.5 wamp介绍 7 3 系统分析 8 3.1 系统可行性分析 8 3.1.1 技术可行性 …

【编程基础之Python】1、初始Python

【编程基础之Python】1、初始Python初始Python什么是PythonPython的运行过程Python的应用领域如何学好Python初始Python Python是一种跨平台的、开源免费的、解释型的、面向对象的高级编程语言。 Python的应用领域非常广泛&#xff0c;包括客户端程序、服务器程序、移动端程序…

Redis未授权漏洞蜜罐模拟与捕获分析

1.概述 文章主要分析Redis未授权漏洞的原理及形成原因&#xff0c;使用vulhub靶场进行漏洞复现&#xff0c;在了解漏洞原理并复现的基础上使用golang编写蜜罐代码进行模拟&#xff0c;开放端口在网上捕获真实存在的恶意攻击行为&#xff0c;对恶意样本进行分析&#xff0c;总结…

C++与Lua交互实例 -- 矩阵的加减乘除(版本二)

C与Lua交互实例 – 矩阵的加减乘除&#xff08;版本二&#xff09; TIPS&#xff1a;关于使用矩阵的加减乘除测试C与Lua的交互以及下面没讲述到的知识点可以阅读第一版&#xff1a; https://blog.csdn.net/qq135595696/article/details/128960951 同时下面两个方式矩阵的数据都…

爬虫JS逆向思路 - - 扣JS(data解密)

网络上几千块都学不到的JS逆向思路这里全都有&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb; 本系列持续更新中&#xff0c;三连关注不迷路&#x1f44c;&#x1f3fb; 干货满满不看后悔&#x1f44d;&#x1f44d;&#x1f44d; ❌注意…

电机过流的一次bug排查记录

一、bug现象描述如下&#xff1a; 有一天&#xff0c;某员工给自己的组件换一个语音模块&#xff0c;其中电机和主板是通过单总线连接&#xff0c;据该员工回忆曾经在换语音芯片时曾将电源线不小心短路过。 电机已经DVT试产&#xff0c;功能和硬件测试已经通过&#xff0c;但是…

小白系列Vite-Vue3-TypeScript:007-配置axios并封装api

上一篇我们介绍了ViteVue3TypeScript项目中Element Plus的安装和配置&#xff0c;本篇我们来介绍一下如何配置axios并封装api。axios是一个基于promise的HTTP库&#xff0c;可以用在浏览器和node.js中&#xff0c;其最大的亮点就是支持了ES6里的Promise Api。废话不多说&#x…

Node =>Express学习

1.Express 能做什么 能快速构建web网站的服务器 或 Api接口的服务期 Web网站服务器&#xff0c;专门对外提供Web网页资源的服务器Api接口服务器&#xff1a;专门对外提供API接口的服务器 2.安装 在项目所处的目录中&#xff0c;运行以下命令&#xff0c;简装到项目中了 npm …

ChatGPT与马斯克 在 “ 遥感 ” 中的初探索

有人说&#xff1a;一个人从1岁活到80岁很平凡&#xff0c;但如果从80岁倒着活&#xff0c;那么一半以上的人都可能不凡。 生活没有捷径&#xff0c;我们踩过的坑都成为了生活的经验&#xff0c;这些经验越早知道&#xff0c;你要走的弯路就会越少。 1前言 文章开始前&#x…

栈和队列基本原理

栈和队列基本原理1.栈1.1 栈基本原理1.2. 栈操作步骤1.2.1 插入数据流程【压栈】1.2.2 移除数据流程【出栈】1.3. 栈代码实现2.队列2.1 队列基本原理2.2 队列操作步骤2.2.1 插入数据2.2.2 移除数据2.3. 队列代码实现3.栈与队列对比1.栈 1.1 栈基本原理 栈顶【末尾】&#xff…

突破边界:“超融合+”带来的商业化精益之路

相信大家都看了《流浪地球2》&#xff0c;其中人类一次次超越极限&#xff0c;以勇气和责任完成伟大征程的情节让我们深深感动。在现实的科技发展中&#xff0c;我们可能不会像科幻作品那样完成惊险万分地完成突破。但超越极限&#xff0c;却时时刻刻发生在科技产业当中。“超融…

K_A12_002 基于STM32等单片机采集光敏电阻传感器参数串口与OLED0.96双显示

K_A12_002 基于STM32等单片机采集光敏电阻传感器参数串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RC光敏电阻传感器模块1.2、STM32F103C8T6光敏电阻传感器模块五、基…