JDBC知识点总结概括(day29)

news2024/9/25 11:18:14

1 学习目标

  1. 了解JDBC的概念
  2. 重点掌握JDBC的CRUD
  3. 重点掌握JDBC的各个对象的使用

2 GIT

  • 查看安装手册

3 JDBC概述

3.1 数据的持久化

  • 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各种关系数据库来完成

  • 持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。

3.2 JAVA中的数据存储技术

  • 在Java中,数据库存取技术可分为如下几类:

    • JDBC直接访问数据库

    • JDO (Java Data Object )技术

    • 第三方O/R工具,如Hibernate, Mybatis 等

  • JDBC是java访问数据库的基石,JDO、Hibernate、MyBatis等只是更好的封装了JDBC。

3.3 JDBC介绍

  • JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。
  • JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
  • JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
  • 如果没有JDBC,那么Java程序访问数据库时是这样的:

  • 有了JDBC,Java程序访问数据库时是这样的:

3.4 JDBC体系结构

  • JDBC接口(API)包括两个层次:
    • 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。
    • 面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。

JDBC是sun公司提供一套用于数据库操作的接口,java程序员只需要面向这套接口编程即可。

不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。 ————面向接口编程

3.5 JDBC程序编写步骤

4 获取数据库连接

4.1 Driver接口实现类

4.1.1 Driver接口介绍

  • java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。

  • 在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现。

    • Oracle的驱动:oracle.jdbc.driver.OracleDriver
    • mySql的驱动: com.mysql.jdbc.Driver

4.1.2 导入jar包

①在01-JDBCDemo模块下的lib目录下,添加mysql的驱动jar包

②但是此时这个jar包还不能使用,我们需要将jar包引入到项目,操作很简单,只需要选中jar包,然后右键,点击Add as Library...选项

③在弹出的选框框中点击OK即可

④那么此时的jar包已经是可以展开的模式了,说明已经导入成功

4.1.3 加载与注册JDBC驱动

  • 加载驱动:加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名

    • Class.forName("com.mysql.jdbc.Driver");
  • 注册驱动:DriverManager 类是驱动程序管理器类,负责管理驱动程序

    • 使用DriverManager.registerDriver(com.mysql.jdbc.Driver)来注册驱动
    • 通常不用显式调用 DriverManager类的 registerDriver() 方法来注册驱动程序类的实例,因为 Driver 接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用 DriverManager.registerDriver() 方法来注册自身的一个实例。下图是MySQL的Driver实现类的源码:

4.1.4 TestConnection代码实现

①在01-JDBCDemo模块下的jdbc包中,找到TestConnection类,在该类中进行代码编写

②在该类中1.加载驱动处书写如下代码:

//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");

4.2 URL

4.2.1 URL组成结构

  • JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
  • JDBC URL的标准由三部分组成,各部分间用冒号分隔。
    • jdbc:子协议:子名称
    • 协议:JDBC URL中的协议总是jdbc
    • 子协议:子协议用于标识一个数据库驱动程序
    • 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名
  • 举例:

  • 注意:如果JDBC程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集

    jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8

4.2.2 TestConnection代码实现

  • 在TestConnection中的2.1指定URL,确定要连接哪个数据库处,实现URL的定义
//2.1指定URL,确定要连接哪个数据库
String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";

4.3 用户名和密码

  • 可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接

4.4 建立连接

package jdbc;

import java.sql.*;

/**
 * 用于测试JDBC获取数据库链接是否通畅的案例
 */
public class TestConnection {
    public static void main(String[] args) throws Exception {
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取和数据库的连接
        //2.1指定URL,确定要连接哪个数据库
        String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";
        //2.2指定使用的用户名
        String user = "root";
        //2.3指定使用的密码
        String pwd = "root";
        //2.4调用DriverManager类的getConnection()方法建立到数据库的连接
        Connection conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
    }
}

5 使用PreparedStatement实现操作

5.1 PreparedStatement介绍

  • 可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象
  • PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句
  • PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值
  • 调用PreparedStatement对象的以下方法可以执行增删改查操作:
    • 执行查询SQL时,调用executeQuery()方法,会返回ResultSet对象,将结果集封装在该对象中
    • 执行修改SQL(包括删除记录,修改记录,增添记录)时,调用executeUpdate()方法,会返回int类型数据,将修改的记录数返回

5.2 向regions表中添加记录

  • 在regions表中插入一条记录: region_id为5,region_name为"神之国度"
INSERT INTO regions(region_id,region_name) 
VALUES(null,'神之国度')
  • 代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * 用于测试JDBC添加记录
 */
public class TestInsert {
    private static Connection conn = null;
    private static PreparedStatement ps = null;

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String pwd = "root";
        conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
        //1.获取PreparedStatement的实例
        //1.1定义sql语句
        String sql = "INSERT INTO regions(region_id,region_name) VALUES(null,'神的国度')";
        //1.2创建PreparedStatement实例,并接受sql语句作为参数
        ps = conn.prepareStatement(sql);
        //1.3通过PreparedStatement调用executeUpdate()方法执行查询操作
        int rows = ps.executeUpdate();
        System.out.println(rows > 0 ? "添加" + rows + "条记录成功!" : "添加失败!");
        //2.释放资源
        rs.close();
        ps.close();
    }
}

5.3 修改regions表中记录

  • 将regions表中region_id为5的记录中的region_name值修改为'魔之国度'
UPDATE regions SET region_name = "魔之国度" where region_id =5;
  • 代码如下
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

/**
 * 用于测试JDBC修改记录
 */
public class TestUpdate {
    private static Connection conn = null;
    private static PreparedStatement ps = null;

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String pwd = "root";
        conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
        //1.获取PreparedStatement的实例
        //1.1定义sql语句
        String sql = "UPDATE regions SET region_name = '魔之国度' where region_id =5";
        //1.2创建PreparedStatement实例,并接受sql语句作为参数
        ps = conn.prepareStatement(sql);
        //1.3通过PreparedStatement调用executeUpdate()方法执行修改操作
        int rows = ps.executeUpdate();
        System.out.println(rows > 0 ? "修改" + rows + "条记录成功!" : "修改失败!");
        //2.释放资源
        rs.close();
        ps.close();
    }
}

5.4 删除regions表中记录

  • 将regions表中region_id为5的记录删除
DELETE FROM regions WHERE region_id =5;
  • 代码如下
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

/**
 * 用于测试JDBC删除记录
 */
public class TestDelete {
    private static Connection conn = null;
    private static PreparedStatement ps = null;

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String pwd = "root";
        conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
        //1.获取PreparedStatement的实例
        //1.1定义sql语句
        String sql = "DELETE FROM regions WHERE region_id =5;";
        //1.2创建PreparedStatement实例,并接受sql语句作为参数
        ps = conn.prepareStatement(sql);
        //1.3通过PreparedStatement调用executeUpdate()方法执行删除操作
        int rows = ps.executeUpdate();
        System.out.println(rows > 0 ? "删除" + rows + "条记录成功!" : "删除失败!");
        //2.释放资源
        rs.close();
        ps.close();
    }
}

5.5 查询regions表中的所有数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * 用于测试JDBC查询记录
 */
public class TestSelect {
    private static Connection conn = null;
    private static PreparedStatement ps = null;

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String pwd = "root";
        conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
        //1.定义sql语句
        String sql = "SELECT region_id,region_name FROM regions";
        //2.创建PreparedStatement实例,并接受sql语句作为参数
        ps = conn.prepareStatement(sql);
        //3.通过PreparedStatement调用executeQuery()方法执行查询操作
        ResultSet rs = ps.executeQuery();
        //4.遍历结果集
        while (rs.next()){ //while循环一次,迭代一行,遍历一行
            int regionId = rs.getInt("region_id");//get一次得到一个单元格的数据
            String regionName = rs.getString("region_name");
            System.out.println(regionId + "\t" + regionName);
        }
        //5.释放资源
        rs.close();
        ps.close();
        conn.close();
    }
}

5.6 解决SQL注入

5.6.1 案例

  • 查询regions表中指定的用户
SELECT region_id,region_name 
FROM regions 
WHERE region_id = 1 AND region_name = 'Europe'

5.6.2 SQL注入问题演示

import java.sql.*;
import java.util.Scanner;

/**
 * 用于测试JDBC的SQL注入问题
 */
public class TestSelect2 {
    private static Connection conn = null;
    private static PreparedStatement ps = null;
    private static ResultSet rs = null;

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String pwd = "root";
        conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
        //1.定义sql语句
        int regionID = 2;
        String regionName = "' or '1'='1";;
        String sql = "SELECT region_id,region_name FROM regions where region_id = " + regionID + " AND region_name = '" + regionName + "'";
        System.out.println("sql = " + sql);
        //2.创建PreparedStatement实例,并接受sql语句作为参数
        ps = conn.prepareStatement(sql);
        //3.通过PreparedStatement调用executeQuery()方法执行查询操作
        rs = ps.executeQuery();
        //4.判断结果
        System.out.println(rs.next() == true ? "记录存在!" : "记录不存在!");
        //5.释放资源
        rs.close();
        ps.close();
        conn.close();
    }
}

5.6.3 SQL注入解决

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * 用于测试JDBC通过PreparedStatement解决SQL注入问题
 */
public class TestSelect3 {
    private static Connection conn = null;
    private static PreparedStatement ps = null;
    private static ResultSet rs = null;

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String pwd = "root";
        conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
        //1.定义sql语句
        String sql = "SELECT region_id,region_name FROM regions where region_id = ? AND region_name = ?";
        //2.创建PreparedStatement实例,并接受sql语句作为参数
        ps = conn.prepareStatement(sql);
        //3.为SQL骨架传入参数
        ps.setInt(1, 1);
        ps.setString(2, "' or '1'='1");
        //4.通过PreparedStatement调用executeQuery()方法执行查询操作
        rs = ps.executeQuery();
        //5.遍历结果集
        System.out.println(rs.next() == true ? "记录存在!" : "记录不存在!");
        //6.释放资源
        rs.close();
        ps.close();
        conn.close();
    }
}

6 使用ResultSet封装结果集

6.1 ResultSet介绍

  • 查询需要调用PreparedStatement 的 executeQuery() 方法,查询结果是一个ResultSet 对象

  • ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商提供实现

  • ResultSet 返回的实际上就是一张数据表。有一个指针指向数据表的第一条记录的前面。

  • ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next() 方法移动到下一行。调用 next()方法检测下一行是否有效。若有效,该方法返回 true,且指针下移。

  • 当指针指向一行时, 可以通过调用getXxx(int columnName) 获取每一列的值。

    • 例如: getInt("region_id"), getString("region_name")
    • 注意:Java与数据库交互涉及到的相关Java API中的索引都从1开始。

  • ResultSet 接口的常用方法:
    • boolean next()

    • getString()

7 资源的释放

  • 释放ResultSet, PreparedStatement,Connection。
  • 数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。

8 JDBC的事务处理

8.1 JDBC管理事务

  • mysql默认是自动提交事务,每执行一条语句成功后,自动提交。

    需要开启手动提交模式。

​ setAutoCommit(false);

  • 提交事务

    Connection连接对象.commit();

  • 回滚事务

    Connection连接对象.rollback();

8.2 代码

import java.sql.*;

/**
 * 用于测试JDBC的事务处理
 */
public class TestTransaction {
    private static Connection conn = null;
    private static PreparedStatement ps = null;

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/hr?useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String pwd = "root";
        conn = DriverManager.getConnection(url, user, pwd);
        System.out.println("连接成功~~");
        //1.开启事务
        conn.setAutoCommit(false);//取消自动提交模式,开始手动提交模式
        //2.定义多条sql语句
        String sql1 = "UPDATE regions SET region_name = '青岛' WHERE region_id = 6";
        String sql2 = "UPDATE region SET region_name = '大冶' WHERE region_id = 4";
        //3.创建PreparedStatement实例,并执行sql
        try {
            ps = conn.prepareStatement(sql1);
            ps.executeUpdate();
            System.out.println("第一条记录更新成功");
            ps = conn.prepareStatement(sql2);
            ps.executeUpdate();
            System.out.println("第二条记录更新成功");
            //4.提交事务
            conn.commit();
        } catch (SQLException e) {
            //5.回滚事务
            e.printStackTrace();
            System.out.println("更新失败!");
            conn.rollback();
        }
        //6.释放资源
        ps.close();
        conn.close();
    }
}

9 总结

① JDBC 是什么?

JDBC 是 Java 数据库连接技术的简称,用于在 Java 程序中连接和操作关系型数据库。

② JDBC 驱动的作用是什么?

JDBC 驱动是一个软件模块,用于在 Java 程序中连接和操作关系型数据库。

③如何防止 SQL 注入攻击?

使用 PreparedStatement 和 SQL 参数化查询可以有效地防止 SQL 注入攻击。

④JDBC 中如何实现事务处理?

使用 JDBC 的事务处理功能可以确保数据库操作的原子性、一致性、隔离性和持久性,可以使用 Connection 对象的 setAutoCommit() 方法来关闭自动提交,并通过 commit() 和 rollback() 方法来实现事务的提交和回滚。

上一篇文章:数据库事务知识点(day28)-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/Z0412_J0103/article/details/141845763下一篇文章: 

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

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

相关文章

【人工智能学习笔记】5 计算机视觉基础

计算机视觉概述 定义:计算机视觉(Computer Vision)是一门研究如何使机器“看”的科学,也可以看作是研究如何使人工系统从图像活多维数据中“感知”的科学终极目标:计算机视觉成为机器认知世界的基础,终极目…

Linux——高流量 高并发(访问场景) 高可用(架构要求)

高并发通用设计逻辑: 定位单点,拆分问题 架构调整的顺序: 动静分离 // 没有实现动静分离 // 静态请求 交给 nginx或者 httpd 这种对于静态资源处理效率更高的服务,动态请求 交给php-fpm 服务来处理 使用云服务提供商 &#xff…

怎么翻译图片上的文字?6种方法教你快速翻译

现如今,图片已经成为传播信息的重要载体之一,然而,图片上的文字往往成为我们获取信息的障碍。幸运的是,随着技术的发展,多种图片文字翻译工具应运而生,让翻译变得简单快捷。很多小伙伴不清楚哪些翻译工具简…

《JavaEE进阶》----15.<Spring Boot 日志>

本篇文章将记录我学习SpringBoot日志 1.日志文件的用途 2.SpringBoot日志文件的配置 3.用lombook依赖引入Slf4j注解,从而引入log对象。方便我们打印日志。 一、日志的作用 日志主要是为了发现问题、分析问题、定位问题。除此之外、日志还有许多其他的用途。 1.系统监…

玩转西门子 S7-1200/1500 的 Modbus RTU 通信诊断

01 概述工控人加入PLC工业自动化精英社群 Modbus RTU 是一种串行通信协议,由于具有协议透明,实现成本低,简单易用等诸多特点,至今仍然广泛应用在工业控制的各个领域。 为了通信可以长期稳定的运行,并且可以在故障时可…

Vue组件:依赖注入provide和inject的使用

1、Prop 逐级透传问题 通常情况下,当我们需要从父组件向子组件传递数据时,会使用 props。想象一下这样的结构:有一些多层级嵌套的组件,形成了一棵巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据…

智慧水务建设的核心内容

智慧水务解决方案的主要对象客户是全国各地水务投资集团、水务局、水司、水厂、农水办,也会有少量项目涉及到住建局或城管局。解决方案通常会以具体的某个业务单位的职能工作为切入点,配合物联感知、大数据分析、人工智能等技术手段,为城市供水、乡村供水的水质安全、供水调…

一文彻底了解DNS协议工作原理,恐怕没有比这更通俗易懂的了吧?

了解DNS工作原理有助于深入理解互联网通信的基础机制,对于网络运维、开发以及优化网站访问速度至关重要。它能帮助解决域名解析问题,提升用户体验,同时对于网络安全和防护也具有重要意义。本文博主反反复复、前前后后斟酌了三天,就…

【学习笔记】手写Tomcat 二

目录 响应静态资源 HTTP协议请求格式 1. 解析请求信息 创建解析请求类 HttpRequest 2. 创建静态资源目录 webs 3. 封装响应信息 创建静态资源处理器 StaticResourceHandler 创建响应类 HttpResponse 作业 1. 绘制 请求解析类 HttpRequest 和响应类 HttpResponse 的封…

动手学深度学习(pytorch土堆)-03常见的Transforms

Compose transforms.Compose 是 PyTorch 中的一个函数,用于将多个图像变换操作组合在一起,形成一个变换流水线。这样可以将一系列的图像处理操作整合为一个步骤,便于对图像进行批量预处理或增强。 基本用法 transforms.Compose 接受一个列表…

vue + Lodop 制作可视化设计页面 实现打印设计功能(四)

历史: vue2 Lodop 制作可视化设计页面 实现打印设计功能(一) vue Lodop 制作可视化设计页面 实现打印设计功能(二) vue Lodop 制作可视化设计页面 实现打印设计功能(三) 前言&#xff1a…

必看!实网环境下,合宙Cat.1模组低功耗详细数据

一、背景说明 合宙4G Cat.1模组以低功耗为显著特点,提供了三种功耗模式以适应不同需求。 分别是:常规模式,低功耗模式,PSM模式。 在实际应用中,用户可以根据不同的应用场景和需求,灵活选择合宙4G Cat.1模…

数据结构与算法图论 并查集

前言 写一道并查集的题 判断是否为亲戚 原题目:现在有若干家族图谱关系,给出了一些亲戚关系,如Marrv和Tom是亲戚,Tom和Ben是亲戚等等。从这些信息中,你可以推导出Marry和Ben是亲戚。请写一个程序,对于我…

一文读懂在线学习凸优化技术

一文读懂在线学习凸优化技术 在当今的数据驱动时代,机器学习算法已成为解决复杂问题的关键工具。在线学习凸优化作为机器学习中的一项核心技术,不仅在理论研究上具有重要意义,还在实际应用中展现出巨大的潜力。本文将深入浅出地介绍在线学习…

C++(三)----内存管理

1.C/C内存分布 看下面这个问题(考考你们之前学的咋样): int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pCh…

【leetcode C++】 动态规划

4. 91 解码方法 题目: 一条包含字母 A-Z 的消息通过以下映射进行了 编码 : "1" -> A "2" -> B ... "25" -> Y "26" -> Z 然而,在 解码 已编码的消息时,你意识到有许多不同的…

数据湖-方案对比

数据湖架构结合了数据湖和数据仓库。虽然它不仅仅是两者之间的简单集成,但其理念是充分发挥两种架构的优势:数据仓库的可靠交易以及数据湖的可扩展性和低成本。 Lakehouse 架构支持管理各种数据类型,例如结构化、半结构化和非结构化数据&…

巧用工具,Vue 集成 medium-zoom 实现图片缩放

文章目录 巧用工具,Vue 集成 medium-zoom 实现图片缩放介绍medium-zoomVue3集成 medium-zoom 示例Vue2集成 medium-zoom 示例进阶 - 可选参数 巧用工具,Vue 集成 medium-zoom 实现图片缩放 在现代网页开发中,为用户提供良好的视觉体验至关重…

爬虫逆向学习(六):补环境过某数四代

声明:本篇文章内容是整理并分享在学习网上各位大佬的优秀知识后的实战与踩坑记录 引用博客: https://blog.csdn.net/shayuchaor/article/details/103629294 https://blog.csdn.net/qq_36291294/article/details/127699273 https://blog.csdn.net/weixin_…

vivo手机已删除的短信还能恢复吗?

虽然现在我们很少使用vivo手机的短信功能,但是我们偶尔还会通过vivo手机短信功能接收一些重要的信息。如果我们在清理垃圾短信的时候误删了vivo手机重要短信,该怎么恢复呢? 方法一:通过vivo云服务恢复 1、确保您已开启vivo云服务…