当前位置: 首页 > news >正文

第十四讲 JDBC数据库

1. 什么是JDBC

JDBC(Java Database Connectivity,Java数据库连接),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系型数据库,并使用SQL语句来完成对数据库中数据的查询、新增、更新和删除等操作。

应用程序使用JDBC访问数据库的方式如图1所示。

图1 应用程序通过JDBC访问数据库方式

2. JDBC常用API

1Driver接口

Driver接口是所有JDBC驱动程序必须实现的接口,该接口专门提供给数据库厂商使用。

注意:在编写JDBC程序时,必须要把所使用的数据库驱动程序或类库加载到项目的classpath中(这里指数据库的驱动JAR包)。

(2)DriverManager类

DriverManager类用于加载JDBC驱动并且创建与数据库的连接。其主要方法如表1所示。

表1 DriverManager类常用方法

方法声明

功能描述

static synchronized void registerDriver(Driver driver)

该方法用于向DriverManager中注册给定的JDBC驱动程序

static Connection getConnection(String url,String user,String pwd)

该方法用于建立和数据库的连接,并返回表示连接的Connection对象

说明:在实际开发中,通常不使用registerDriver(Driverdriver)注册驱动。因为JDBC驱动类Driver中有一段静态代码块,是向DriverManager注册一个Driver实例,当再次执行registerDriver(newDriver()),相当于实例化了两个Driver对象,因此在加载数据库驱动时通常使用Class类的静态方法forName()来实现。

(3) Connection接口

Connection接口代表Java程序和数据库的连接对象,只有获得该连接对象后,才能访问数据库,并操作数据表。Connection接口常用方法如表2所示。

表2 Connection接口

方法声明

功能描述

Statement createStatement()

该方法用于返回一个向数据库发送语句的Statement对象

PreparedStatement prepareStatement(String sql)

该方法用于返回一个PreparedStatement对象,该对象用于向数据库发送参数化的SQL语句

CallableStatement prepareCall(String sql)

该方法用于返回一个CallableStatement对象,该对象用于调用数据库中的存储过程

(4) Statement接口

Statement是Java执行数据库操作的一个重要接口,它用于执行静态的SQL语句,并返回一个结果对象。

说明:Statement接口对象可以通过Connection实例的createStatement()方法获得,然后返回数据库的处理结果。Statement接口常用方法如表3所示。

表3 Statement常用方法

方法声明

功能描述

boolean execute(String sql)

用于执行各种SQL语句,返回一个boolean类型的值,如果为true,表示所执行的SQL语句有查询结果,可通过Statement的getResultSet()方法获得查询结果

int executeUpdate(String sql)

用于执行SQL中的insert、update和delete语句。该方法返回一个int类型的值,表示数据库中受该SQL语句影响的记录条数

ResultSet executeQuery(String sql)

用于执行SQL中的select语句,该方法返回一个表示查询结果的ResultSet对象

(5)PreparedStatement接口

Statement接口封装了JDBC执行SQL语句的方法,虽然可以完成Java程序执行SQL语句的操作,但是在实际开发过程中往往需要将程序中的变量作为SQL语句的查询条件,而使用Statement接口操作这些SQL语句会过于繁琐,并且存在安全方面的问题。针对这一问题,JDBC API 中提供了扩展的PreparedStatement接口。PreparedStatement是Statement的子接口,用于执行预编译的SQL语句。

说明:PreparedStatement接口扩展了带有参数SQL语句的执行操作,应用接口中的SQL语句可以使用占位符“?”来代替其参数,然后通过setXxx()方法为SQL语句的参数赋值。

PreparedStatement接口常用方法如表4所示。

表4 PreparedStatement接口常用方法

方法声明

功能描述

int executeUpdate()

在此PreparedStatement对象中执行 SQL 语句,该语句必须是一个DML语句或者是无返回内容的SQL 语句,如 DDL 语句

ResultSet executeQuery()

在此PreparedStatement对象中执行 SQL 查询,该方法返回的是ResultSet对象

void setInt(int parameterIndex, int x)

将指定参数设置为给定的int值

void setFloat(int parameterIndex, float x)

将指定参数设置为给定的float值

void setString(int parameterIndex, String x)

将指定参数设置为给定的String值

void setDate(int parameterIndex, Date x)

将指定参数设置为给定的Date值

void addBatch()

将一组参数添加到此PreparedStatement对象的批处理命令中

void setCharacterStream(int parameterIndex,  java.io.Reader reader,  int length)

将指定的输入流写入数据库的文本字段

void setBinaryStream(int parameterIndex, java.io.InputStream x, int length)

将二进制的输入流数据写入到二进制字段中

为SQL语句参数赋值时,可以通过输入参数与SQL类型相匹配的setXxx()方法。例如字段的数据类型为int或Integer,那么应该使用setInt()方法,也可以通过setObject()方法设置多种类型的输入参数。

    // 假设users表中字段id、name、email类型分别是int、varchar、varcharString sql = "INSERT INTO users(id,name,email) VALUES(?,?,?)";PreparedStatement  preStmt = conn.prepareStatement(sql);preStmt.setInt(1, 1);                    //使用参数与SQL类型相匹配的方法preStmt.setString(2, "zhangsan");         //使用参数与SQL类型相匹配的方法preStmt.setObject(3, "zs@sina.com");     //使用setObject()方法设置参数preStmt.executeUpdate();

(6)ResultSet接口

ResultSet接口用于保存JDBC执行查询时返回的结果集,该结果集封装在一个逻辑表格中。在ResultSet接口内部有一个指向表格数据行的游标(或指针),ResultSet对象初始化时,游标在表格的第一行之前,调用next()方法可将游标移动到下一行。如果下一行没有数据,则返回false。在程序中经常使用next()方法作为while循环的条件来迭代ResultSet结果集。ResultSet接口常用方法如表5所示。

表5 ResultSet接口常用方法

方法声明

功能描述

String getString(int

 columnIndex)

用于获取指定字段的String类型的值,参数columnIndex代表字段的索引

String getString(String

 columnName)

用于获取指定字段的String类型的值,参数columnName代表字段的名称

int getInt(int columnIndex)

用于获取指定字段的int类型的值,参数columnIndex代表字段的索引

int getInt(String columnName)

用于获取指定字段的int类型的值,参数columnName代表字段的名称

Date getDate(int columnIndex)

用于获取指定字段的Date类型的值,参数columnIndex代表字段的索引

Date getDate(String

 columnName)

用于获取指定字段的Date类型的值,参数columnName代表字段的名称

boolean next()

将游标从当前位置向下移一行

boolean absolute(int row)

将游标移动到此 ResultSet 对象的指定行

void afterLast()

将游标移动到此 ResultSet 对象的末尾,即最后一行之后

void beforeFirst()

将游标移动到此 ResultSet 对象的开头,即第一行之前

boolean previous()

将游标移动到此 ResultSet 对象的上一行

boolean last()

将游标移动到此 ResultSet 对象的最后一行

ResultSet接口中定义了大量的getXxx()方法,而采用哪种getXxx()方法取决于字段的数据类型。

程序既可以通过字段的名称来获取指定数据,也可以通过字段的索引来获取指定的数据,字段的索引是从1开始编号的。

例如,假设数据表的第1列字段名为id,字段类型为int,那么既可以使用getInt("id")获取该列的值,也可以使用getInt(1)获取该列的值。

3. JDBC编程的基本步骤

通常情况下,JDBC编程可分为如下几个基本步骤。

(1)加载数据库驱动

 加载数据库驱动通常使用Class类的静态方法forName()来实现,使用格式:

Class.forName(DriverName);

上述代码中,DriverName代表的是数据库驱动类所对应的字符串。例如,要加载MySQL数据库的驱动可以采用如下代码。

Class.forName("com.mysql.jdbc.Driver");

(2)通过DriverManager获取数据库连接

DriverManager提供了一个getConnection()方法来获取数据库连接,使用格式如下。

Connection conn = DriverManager.getConnection(String url, String user, String pwd);

   参数说明:

url:表示连接数据库的URL。

user:表示登录数据库的用户名。

pwd:表示登录数据库的密码。

用户名和密码通常由数据库管理员设置,而连接数据库的URL则有固定格式。如MySQL数据库的URL地址为。

jdbc:mysql://hostname:prot/databasename

上述代码中,jdbc:mysql:是固定写法,mysql指的是MySQL数据库;hostname指的是MySQL数据库所在的主机名或IP地址(例如数据库在本机上,hostname可以是localhost或127.0.0.1);port指的是连接数据库的端口号(默认为3306);databasename指的是要操作的数据库。

(3)通过Connection对象获取Statement对象

Connection创建Statement的方式有3种。

①createStatement():创建基本的Statement对象。

②prepareStatement(String sql):根据传递的SQL语句创建PreparedStatement对象。

③prepareCall(Stringsql):根据传入的SQL语句创建CallableStatement对象。

例创建基本的Statement对象,其代码如下所示。

Statement stmt = conn.createStatement();

(4)使用Statement执行SQL语句

可通过如下3种不同的方式来执行SQL语句。

①execute(String sql):用于执行任意的SQL语句。

②executeQuery(String sql):用于执行查询语句,返回ResultSet结果集对象。

③executeUpdate(String sql):主要用于执行DML(数据操作语言)和DDL(数据定义语言)语句。执行DML语句(INSERT、UPDATE或DELETE)时,会返回受SQL语句影响的行数,执行DDL(CREATE、ALTER)语句返回0。

例执行查询SQL,获取结果集:

// 执行SQL语句,获取结果集ResultSetResultSet rs = stmt.executeQuery(sql);

(5)操作ResultSet结果集

如果执行的SQL语句是查询语句,执行结果将返回一个ResultSet对象,该对象里保存了SQL语句查询的结果。程序可以通过操作该ResultSet对象来取出查询结果。

(6)关闭连接,释放资源

每次操作数据库结束后都要关闭数据库连接,释放资源,以重复利用资源。通常资源的关闭顺序与打开顺序相反,顺序是ResultSet、Statement(或PreparedStatement)和Connection。为了保证在异常情况下也能关闭资源,需要在try...catch的finally代码块中统一关闭资源。

4. JDBC编程示例

(1)添加mysql驱动

①在项目中新建一lib目录,将mysql的驱动程序复制到此目录中。

②选择菜单【file】-【project structure】,左侧选择“modules”,右侧中间选择“Dependencies”,然后点击右上角的“+”号,选择“1 jars or directories…”,如下图所示。

③在弹出的对话框中选择项目中lib目录下的mysql驱动,然后点击”ok”返回。

④此时在Dependencies中会多了刚才选中的mysql驱动,然后点击“ok”即可。

(2)数据库操作

假设要操作的MySQL数据库名为db_student,db_student数据库中有一个表为tb_stud,表中内容如下所示。

【例10-1】读取表中内容并显示

import java.sql.*;public class JDBCShow {public static void main(String[] args) throws SQLException {Connection conn = null;Statement stmt = null;ResultSet rs = null;try{Class.forName("com.mysql.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/db_student?characterEncoding=utf8";String username="root";String password = "";conn = DriverManager.getConnection(url,username,password);stmt = conn.createStatement();rs = stmt.executeQuery("select * from tb_stud");System.out.println("no\t\tname\tmath\tchinese\tenglish");while(rs.next()){String no = rs.getString("no");String name = rs.getString("name");int math = rs.getInt("math");int chinese = rs.getInt("chinese");int english = rs.getInt("english");System.out.println(no + "\t" +name + "\t" + math + "\t\t" + chinese+"\t\t"+ english);}}catch(Exception e){e.printStackTrace();}finally{if(rs!=null) {rs.close();}if(stmt!=null){stmt.close();}if (conn!=null){conn.close();}}}}

运行结果如下图所示。

【例10-2】先往表中插入记录,然后读取表中记录显示

import java.sql.*;public class JDBCInsertShow {public static void main(String[] args) throws SQLException {Connection conn = null;Statement stmt = null;ResultSet rs = null;try{Class.forName("com.mysql.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/db_student?characterEncoding=utf8";String username="root";String password = "";conn = DriverManager.getConnection(url,username,password);stmt = conn.createStatement();String sql = "insert into tb_stud(no,name,math,chinese,english) values(?,?,?,?,?)";PreparedStatement preStmt =conn.prepareStatement(sql);preStmt.setString(1,"1005");preStmt.setString(2,"张小");preStmt.setInt(3,80);preStmt.setInt(4,99);preStmt.setInt(5,90);preStmt.executeUpdate();rs = stmt.executeQuery("select * from tb_stud");System.out.println("no\t\tname\tmath\tchinese\tenglish");while(rs.next()){String no = rs.getString("no");String name = rs.getString("name");int math = rs.getInt("math");int chinese = rs.getInt("chinese");int english = rs.getInt("english");System.out.println(no + "\t" +name + "\t" + math + "\t\t" + chinese+"\t\t"+ english);}}catch(Exception e){e.printStackTrace();}finally{if(rs!=null) {rs.close();}if(stmt!=null){stmt.close();}if (conn!=null){conn.close();}}}}

运行结果如下图所示。

此时数据库表中内容如下所示。

【例10-3】记录的增、删、改、显示操作

import java.sql.*;public class JDBCOperator {public static void main(String[] args) throws SQLException {Connection conn = null;Statement stmt = null;ResultSet rs = null;try{Class.forName("com.mysql.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/db_student?characterEncoding=utf8";String username = "root";String pw = "";conn = DriverManager.getConnection(url,username,pw);stmt = conn.createStatement();String sql = "update tb_stud set name='王明' where id=1";   //记录的修改stmt.executeUpdate(sql);sql = "insert into tb_stud values(null,'1004','张朋',70,70,70)"; //记录的添加stmt.executeUpdate(sql);sql = "delete from tb_stud where name='李军'";   //记录的删除stmt.executeUpdate(sql);rs = stmt.executeQuery("select * from tb_stud");System.out.println("no\t\tname\tmath\tchinese\tenglish");while(rs.next()){String no = rs.getString("no");String name = rs.getString("name");int math = rs.getInt("math");int chinese = rs.getInt("chinese");int english = rs.getInt("english");System.out.println(no + "\t" +name + "\t" + math + "\t\t" + chinese+"\t\t"+ english);}}catch(Exception e){e.printStackTrace();}        }finally{if (rs!=null){rs.close();}if (stmt!=null) {stmt.close();}if (conn!=null) {conn.close();}}}

运行结果如下图所示。

此时表中内容如下所示。

 

相关文章:

第十四讲 JDBC数据库

1. 什么是JDBC JDBC(Java Database Connectivity,Java数据库连接),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系型数据库,并使用SQL语句来完成对数据库中数据的查询、新增、更新和删除等操作…...

“AI教学实训系统:打造未来教育的超级引擎

嘿,各位教育界的伙伴们,今天我要跟你们聊聊一个绝对能让你们眼前一亮的教学神器——AI教学实训系统。作为资深产品经理,我可是亲眼见证了这款系统如何颠覆传统教学,成为未来教育的超级引擎。 一、什么是AI教学实训系统&#xff1f…...

java读取设置pdf属性信息

pom <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.24</version> </dependency>读取属性 import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmod…...

C语言内存管理详解

C语言不像其他高级语言那样提供自动内存管理&#xff0c;它要求程序员手动进行内存的分配和释放。在C语言中&#xff0c;动态内存的管理主要依赖于 malloc、calloc、realloc 和 free 等函数。理解这些函数的用法、内存泄漏的原因及其防止方法&#xff0c;对于编写高效、可靠的C…...

mysql从全备文件中提取单库或单表进行恢复——筑梦之路

前提条件 与业务确认涉及业务、数据库IP、数据误删除时间点、数据删除涉及的SCHEMA、数据表&#xff0c;确认该数据库为MySQLdump备份方式&#xff0c;备份策略为每日凌晨1点进行数据库全备份&#xff0c;备份保留7天&#xff0c;业务误删除数据时间点为当日10点左右&#xff0…...

HTML-新浪新闻-实现标题-排版

标题排版 图片标签&#xff1a;<img> src&#xff1a;指定图片的url&#xff08;绝对路径/相对路径&#xff09; width&#xff1a;图片的宽度&#xff08;像素/相对于父元素的百分比&#xff09; heigth&#xff1a;图片的高度&#xff08;像素/相对于父元素的百分比&a…...

【前沿聚焦】机器学习的未来版图:从自动化到隐私保护的技术突破

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…...

二叉树的最大深度(C语言详解版)

一、摘要 嗨喽呀大家&#xff0c;leetcode每日一题又和大家见面啦&#xff0c;今天要讲的是104.二叉树的最大深度&#xff0c;思路互相学习&#xff0c;有什么不足的地方欢迎指正&#xff01;好啦让我们开始吧&#xff01;&#xff01;&#xff01; 二、题目简介 给定一个二…...

基于dlib/face recognition人脸识别推拉流实现

目录 一.环境搭建 二.推拉流代码 三.人脸检测推拉流 一.环境搭建 1.下载RTSP服务器MediaMTX与FFmpeg FFmpeg是一款功能强大的开源多媒体处理工具,而MediaMTX则是一个轻量级的流媒体服务器。两者结合,可以实现将本地视频或者实时摄像头画面推送到RTSP流,从而实现视频…...

【kong gateway】5分钟快速上手kong gateway

kong gateway的请求响应示意图 安装 下载对应的docker 镜像 可以直接使用docker pull命令拉取&#xff0c;也可以从以下地址下载&#xff1a;kong gateway 3.9.0.0 docker 镜像 https://download.csdn.net/download/zhangshenglu1/90307400&#xff0c; postgres-13.tar http…...

webrtc入门系列(五)amazon-kinesis-video-streams-webrtc-sdk-c编译

《webrtc入门系列&#xff08;一&#xff09;easy_webrtc_server 入门环境搭建》 《webrtc入门系列&#xff08;二&#xff09;easy_webrtc_server 入门example测试》 《webrtc入门系列&#xff08;三&#xff09;云服务器coturn环境搭建》 《webrtc入门系列&#xff08;四&…...

通过亚马逊云科技Bedrock打造自定义AI智能体Agent(上)

大家对于智能体代理Agent一定已经非常熟悉&#xff0c;自主代理&#xff08;Autonomous Agents&#xff09; 目前在AI行业极其热门并具有巨大的潜力&#xff0c;能够显著提升开发者日常的工作效率、自动化日常琐碎、重复性任务&#xff0c;并生成全新的内容。Agent可以理解用户…...

【Nacos】负载均衡

目录 前言 一、服务下线二、权重配置三、同一个集群优先访问四、环境隔离 前言 我们的生产环境相对是比较恶劣的&#xff0c;我们需要对服务的流量进行更加精细的控制.Nacos支持多种负载均衡策略&#xff0c;包括配置权重&#xff0c;同机房&#xff0c;同地域&#xff0c;同环…...

小智 AI 聊天机器人

小智 AI 聊天机器人 &#xff08;XiaoZhi AI Chatbot&#xff09; &#x1f449;参考源项目复现 &#x1f449; ESP32SenseVoiceQwen72B打造你的AI聊天伴侣&#xff01;【bilibili】 &#x1f449; 手工打造你的 AI 女友&#xff0c;新手入门教程【bilibili】 项目目的 本…...

HTML一般标签和自闭合标签介绍

在HTML中&#xff0c;标签用于定义网页内容的结构和样式。标签通常分为两类&#xff1a;一般标签&#xff08;也称为成对标签或开放闭合标签&#xff09;和自闭合标签&#xff08;也称为空标签或自结束标签&#xff09;。 以下是这两类标签的详细说明&#xff1a; 一、一般标…...

怎么用u盘怎么重装系统_用u盘重装系统详细图文教程【新手教程】

怎么用u盘怎么重装系统&#xff1f;如果需要重装操作系统的话&#xff0c;以往采用光盘使用的比较多&#xff0c;随着技术的进步&#xff0c;用u盘制作一个启动盘安装系统比较方便&#xff0c;只需要用u盘制作好pe启动盘就可以帮助别人安装系统了&#xff0c;那么用u盘怎么重装…...

记录一次k8s起不来的排查过程

我在k8s集群&#xff0c;重启了一个node宿主机&#xff0c;竟然发现kubelet起不来了&#xff01;报错如下 这个报错很模糊&#xff0c;怎么排查呢。这样&#xff0c;开两个界面&#xff0c;一个重启kubelet&#xff0c;一个看系统日志(/var/log/message:centos&#xff0c;/va…...

代码练习2

求数组中的第二大值 #include <stdio.h> #include <stdlib.h> int main() {int arr[10]{1,9,2,8,7,3,4,6,5,10};int first, second,i;if (arr[0] > arr[1]) {first arr[0];second arr[1];} else {first arr[1];second arr[0];}for(i 2; i < 10; i) {if…...

2.1.3 第一个工程,点灯!

新建工程 点击菜单栏左上角&#xff0c;新建工程或者选择“文件”-“新建工程”&#xff0c;选择工程类型“标准工程”选择设备类型和编程语言&#xff0c;并指定工程文件名及保存路径&#xff0c;如下图所示&#xff1a; 选择工程类型为“标准工程” 选择主模块机型&#x…...

Qt Designer and Python: Build Your GUI

1.install pyside6 2.pyside6-designer.exe 发送到桌面快捷方式 在Python安装的所在 Scripts 文件夹下找到此文件。如C:\Program Files\Python312\Scripts 3. 打开pyside6-designer 设计UI 4.保存为simple.ui 文件&#xff0c;再转成py文件 用代码执行 pyside6-uic.exe simpl…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑

精益数据分析&#xff08;98/126&#xff09;&#xff1a;电商转化率优化与网站性能的底层逻辑 在电子商务领域&#xff0c;转化率与网站性能是决定商业成败的核心指标。今天&#xff0c;我们将深入解析不同类型电商平台的转化率基准&#xff0c;探讨页面加载速度对用户行为的…...

AWS vs 阿里云:功能、服务与性能对比指南

在云计算领域&#xff0c;Amazon Web Services (AWS) 和阿里云 (Alibaba Cloud) 是全球领先的提供商&#xff0c;各自在功能范围、服务生态系统、性能表现和适用场景上具有独特优势。基于提供的引用[1]-[5]&#xff0c;我将从功能、服务和性能三个方面进行结构化对比分析&#…...