C++ Qt开发:QSqlDatabase数据库组件

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QSqlDatabase数据库模块的常用方法及灵活运用。

Qt SQL模块是Qt框架的一部分,它提供了一组类和函数,用于在Qt应用程序中进行数据库操作。这个模块的目标是简化数据库访问和操作,并提供一致的接口,使得开发者可以方便地与不同数据库系统进行交互。一般SQL组件常用的操作,包括读取数据、插入数据、更新数据、删除数据功能,这四个功能我将分别介绍它是如何使用的。

在使用此模块时必须要引入对应文件,需要在*.pro文件内增加QT += sql,并在头文件内导入QSqlDatabase模块才可以正常使用,该模块是用于管理数据库连接的核心类之一。它提供了一系列方法,使得在Qt应用程序中进行数据库操作变得方便和灵活。QSqlDatabase类的灵活性使得开发者能够与多种数据库系统(如SQLite、MySQL、PostgreSQL等)进行交互,而不必担心底层数据库细节。这有助于实现跨数据库的可移植性和更高层次的数据库访问抽象。

下面是QSqlDatabase类中一些常用的方法,以表格形式进行说明和概述:

方法描述
QSqlDatabase::addDatabase(const QString &type, const QString &connectionName = QLatin1String(defaultConnection))添加一个数据库连接,其中type指定数据库驱动类型,connectionName指定连接的名称,默认为默认连接。返回创建的数据库连接对象。
QSqlDatabase::database(const QString &connectionName = QLatin1String(defaultConnection), bool open = true)获取指定连接名称的数据库连接对象。如果数据库连接不存在,会创建一个新的连接。如果opentrue,则尝试打开数据库连接。
QSqlDatabase::removeDatabase(const QString &connectionName = QLatin1String(defaultConnection))移除指定连接名称的数据库连接。如果该连接当前处于打开状态,则会被关闭。
QSqlDatabase::setHostName(const QString &host)设置数据库服务器的主机名。
QSqlDatabase::setDatabaseName(const QString &name)设置要连接的数据库的名称。
QSqlDatabase::setUserName(const QString &name)设置用于连接数据库的用户名。
QSqlDatabase::setPassword(const QString &password)设置用于连接数据库的密码。
QSqlDatabase::setPort(int port)设置数据库服务器的端口号。
QSqlDatabase::open()打开数据库连接。如果连接成功,返回true,否则返回false
QSqlDatabase::close()关闭数据库连接。
QSqlDatabase::isOpen()判断数据库连接是否打开。返回true表示连接已打开,false表示连接未打开。
QSqlDatabase::tables(QSql::TableType type = QSql::Tables)返回数据库中的表的列表。可以指定表的类型,如QSql::Tables表示用户表,QSql::SystemTables表示系统表。
QSqlDatabase::commit()提交当前事务。
QSqlDatabase::rollback()回滚当前事务。
QSqlDatabase::transaction()开始一个新事务。

这些方法提供了管理和操作数据库连接的基本功能,包括连接数据库、设置连接参数、打开和关闭连接、执行事务等。在实际使用中,开发者可以根据需要选择适当的方法来管理数据库连接和执行数据库操作。

1.1 逐条记录插入

初始化数据库我们可以通过调用QSqlDatabase::addDatabase来打开,在打开参数中支持多种数据库类型的选择,包括但不限于 SQLiteMySQLPostgreSQLOracleODBC 等,每种数据库类型对应一个特定的驱动,开发者可以通过指定数据库类型和连接名称创建相应的数据库连接。

QSqlDatabase::addDatabase 是一个静态方法,用于向应用程序中添加一个数据库连接。此方法允许你为不同的数据库类型添加连接,并且你可以为每个连接指定一个唯一的名称。

static QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName = QLatin1String(defaultConnection));

参数说明

  • type: 字符串,表示数据库的类型,例如 “QSQLITE”、“QMYSQL” 等,具体取决于你所使用的数据库驱动。
  • connectionName: 字符串,表示连接的名称,默认为 defaultConnection。可以通过这个名称在应用程序中区分不同的数据库连接。

返回值

返回创建的 QSqlDatabase 对象,可以使用这个对象进行进一步的数据库配置和操作。如果不提供连接名称,将使用默认的连接名称 defaultConnection。在一个应用程序中,你可以同时拥有多个数据库连接,每个连接都有一个唯一的名称。

在打开后接着我们就可以通过执行db.exec()的方式向特定数据库内插入数据,如下代码所示,通过在编辑框内提取出所需参数并对数据库进行初始化,当出事后成功后则调用db.exec()函数插入记录,最后通过db.commit()提交事务刷新到数据库中。

void MainWindow::on_pushButton_clicked()
{// 指定数据库驱动类型QSqlDatabase db = QSqlDatabase::addDatabase(ui->lineEdit_type->text());db.setDatabaseName(ui->lineEdit_dir->text());if (!db.open()){QMessageBox::information(nullptr, "信息", db.lastError().text(), QMessageBox::Ok);}// 获取文本内容QString plainText = ui->plainTextEdit->toPlainText();// 使用 split() 函数分割成行QStringList lines = plainText.split('\n', Qt::SkipEmptyParts);// 遍历每一行for (const QString &line : lines){db.exec(line);}// 提交事务请求bool ref = db.commit();if(ref == true){QMessageBox::information(nullptr, "信息", "初始化失败", QMessageBox::Ok);}else{QMessageBox::information(nullptr, "信息", "执行初始化成功", QMessageBox::Ok);}db.close();
}

在初始化部分,我们通过create table语句创建一个LyShark的数据表,并插入三个字段,分别是id,name,age,当点击初始化时则会使用QSQLITE引擎,在当前目录下生成一个名为database.sqlite的数据库文件;

同理,只要准备合理的SQL语句就可以实现对应的数据库记录的插入功能;

1.2 多条记录插入

多条记录的插入依赖于QSqlQuery类,该类是Qt中用于执行和处理SQL查询的类。它允许你向数据库发送 SQL 查询并检索查询结果。以下是QSqlQuery类中一些常用的方法,以表格形式进行说明和概述:

方法描述
QSqlQuery::QSqlQuery(QSqlDatabase db = QSqlDatabase())构造函数,创建一个数据库查询对象。如果提供了数据库连接对象 db,则该查询对象将与指定的数据库连接关联。
QSqlQuery::~QSqlQuery()析构函数,释放查询对象。在对象销毁时,会自动关闭查询。
exec(const QString &query)执行指定的 SQL 查询。返回 true 表示执行成功,false 表示执行失败。
execBatch(BatchExecutionMode mode = ValuesAsRows)批量执行多个 SQL 查询。可以设置批量执行模式。
isActive() const判断查询是否处于活动状态(已执行并且未关闭)。
isSelect() const判断当前查询是否是 SELECT 查询。
lastError() const获取最后一次执行的查询的错误信息。如果查询成功,返回一个空的 QSqlError 对象。
next()移动到结果集中的下一条记录。返回 true 表示移动成功,false 表示已经没有更多记录。
seek(int index, bool relative = false)定位到结果集中的指定记录。
value(int index)获取当前记录中指定列的值。
value(const QString &name)获取当前记录中指定列名的值。
prepare(const QString &query)准备一个 SQL 查询。可以在查询中使用占位符 ? 作为参数的占位符。
bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType type = QSql::In)绑定参数到查询。可以使用占位符 ? 或者命名占位符 :name
executedQuery() const获取实际执行的 SQL 查询。当使用占位符时,这个方法返回实际执行的 SQL 语句。
record() const获取查询的元数据信息,包括字段名、字段类型等。
size() const获取结果集的记录数。

这些方法提供了一些基本的数据库查询和结果处理功能,包括执行查询、处理结果、错误处理、绑定参数、获取元数据等。在实际应用中,可以根据具体的需求选择适当的方法来操作数据库。

如下代码所示,首先我们通过split的方式将两个plainEditText中的内容进行分割,并分别将结果存储至QStringList容器内,接着通过使用query.prepare绑定一个SQL语句对应关系,并通过循环的方式以此插入数据,代码如下所示;

void MainWindow::on_pushButton_3_clicked()
{// 指定数据库驱动类型QSqlDatabase db = QSqlDatabase::addDatabase(ui->lineEdit_type->text());db.setDatabaseName(ui->lineEdit_dir->text());if (!db.open()){QMessageBox::information(nullptr, "信息", db.lastError().text(), QMessageBox::Ok);}// 定义字符串链表QStringList user_name;QStringList user_age;// 获取文本内容QString plainText_uname = ui->plainTextEdit_uname->toPlainText();QString plainTextEdit_uage = ui->plainTextEdit_uage->toPlainText();// 使用 split() 函数分割成行QStringList lines_uname = plainText_uname.split('\n', Qt::SkipEmptyParts);QStringList lines_uage = plainText_uname.split('\n', Qt::SkipEmptyParts);// 遍历每一行for (const QString &line : lines_uname){user_name.append(line);}for (const QString &line : lines_uage){user_age.append(line);}// 绑定数据记录QSqlQuery query;query.prepare("INSERT INTO LyShark(name,age) ""VALUES (:name, :age)");// 判断两张表中字段数据量是否一致if(user_name.size() == user_age.size()){// 循环插入数据for(int x=0;x< user_name.size(); x++){query.bindValue(":name",user_name[x]);query.bindValue(":age",user_age[x]);query.exec();}}// 提交事务请求bool ref = db.commit();if(ref == true){QMessageBox::information(nullptr, "信息", "插入数据失败", QMessageBox::Ok);}else{QMessageBox::information(nullptr, "信息", "插入数据成功", QMessageBox::Ok);}db.close();
}

运行后则可以将如下所示的字段依次插入到数据库中存储,如下图所示;

1.3 查询表中记录

查询表中记录离不开QSqlRecord 类,它是Qt中用于表示数据库记录(行)的元数据的类。提供了关于记录中字段(列)的信息,包括字段名、字段类型等。通常用于表示数据库查询的结果集中的一行记录的元数据,以便在程序中处理这些记录的信息。

以下是QSqlRecord类中一些常用的方法,以表格形式进行说明和概述:

方法描述
QSqlRecord::QSqlRecord(const QSqlRecord &other)复制构造函数,创建一个 QSqlRecord 对象,复制另一个记录的信息。
QSqlRecord::~QSqlRecord()析构函数,释放 QSqlRecord 对象。
append(const QSqlField &field)向记录中添加一个字段。
clear()清空记录中的所有字段。
field(int index) const获取指定索引的字段信息。
field(const QString &name) const获取指定字段名的字段信息。
fieldName(int index) const获取指定索引的字段名。
indexOf(const QString &name) const获取指定字段名的索引。如果字段不存在,返回 -1。
isEmpty() const判断记录是否为空(没有字段)。
isGenerated(int index) const判断指定索引的字段是否为自动生成的。
setGenerated(int index, bool generated)设置指定索引的字段是否为自动生成的。
setGenerated(const QString &name, bool generated)设置指定字段名的字段是否为自动生成的。
setField(int index, const QSqlField &field)设置指定索引的字段信息。
count() const获取记录中字段的数量。
contains(const QString &name) const判断记录中是否包含指定字段名的字段。
operator=()赋值运算符重载,将一个记录的内容复制给另一个记录。

这些方法提供了一些基本的记录处理功能,包括添加字段、获取字段信息、设置字段信息、判断字段是否存在等。在实际应用中,可以根据具体的需求选择适当的方法来操作记录。

在查询数据时,我们只需要通过QSqlQuery得到完整的数据表记录条数,然后就可以使用QSqlRecord来创建一个查询对象,此时每次调用query.next()都会向后遍历一行记录,通过rec.indexOf就可以得到对应字段的参数值,而query.value则可以将其提取出来,最后我们将其插入到TreeWidget中用于展示,代码如下所示;

// 查询表中数据
void MainWindow::on_pushButton_4_clicked()
{// 指定数据库驱动类型QSqlDatabase db = QSqlDatabase::addDatabase(ui->lineEdit_type->text());db.setDatabaseName(ui->lineEdit_dir->text());if (!db.open()){QMessageBox::information(nullptr, "信息", db.lastError().text(), QMessageBox::Ok);}// 查询数据QSqlQuery query("SELECT * FROM LyShark;",db);QSqlRecord rec = query.record();// 循环所有记录while(query.next()){// 判断当前记录是否有效if(query.isValid()){// 读出数据int id_ptr = rec.indexOf("id");int id_value = query.value(id_ptr).toInt();int name_ptr = rec.indexOf("name");QString name_value = query.value(name_ptr).toString();int age_ptr = rec.indexOf("age");int age_value = query.value(age_ptr).toInt();// 设置treeWidget属性ui->treeWidget->setColumnCount(3);         // 设置总列数ui->treeWidget->setColumnWidth(0,300);     // 设置最后一列宽度自适应ui->treeWidget->setIndentation(0);         // 设置表头缩进为0// 设置表头数据QStringList headers;headers.append("UID");headers.append("用户名");headers.append("年龄");ui->treeWidget->setHeaderLabels(headers);// 模拟插入数据到表中QTreeWidgetItem* item=new QTreeWidgetItem();item->setText(0,QString::number(id_value));item->setText(1,name_value);item->setText(2,QString::number(age_value));ui->treeWidget->addTopLevelItem(item);}}
}

编译并运行程序,当点击查询按钮时,则可以将数据库中的数据输出到组件中显示,如下图所示;

1.5 更新表中记录

最后一项是对记录的更新,其实更新记录同样是使用exec()函数,只不过是将插入语句修改为了update而已,如下代码通过数据库查询并根据特定条件填充了界面上的两个文本框 (ui->lineEdit_select_unameui->lineEdit_select_uage)。下面是这段代码的概述:

  1. 建立数据库连接:
    • 通过 QSqlDatabase::addDatabase 设置数据库的驱动类型,例如 “QSQLITE”、“QMYSQL” 等。
    • 使用 setDatabaseName 设置数据库名称,这可能是一个本地文件名或者服务器地址。
    • 尝试打开数据库连接,如果连接失败,通过 QMessageBox 显示错误信息。
  2. 执行数据库查询:
    • 使用 QSqlQuery 对象执行 SQL 查询语句 “SELECT * FROM LyShark;”。
    • 通过 QSqlRecord 获取查询结果的记录结构,包括字段名和字段类型。
  3. 循环处理查询结果:
    • 使用 while (query.next()) 循环遍历查询结果中的每一行记录。
    • 对于每个有效的记录,获取 “id” 字段的值,并与用户输入的 “uid” 进行匹配。
    • 如果匹配成功,获取 “name” 和 “age” 字段的值,并将其分别填充到 ui->lineEdit_select_unameui->lineEdit_select_uage 中。
    • 如果没有匹配的记录,或者记录无效,将 ui->lineEdit_select_unameui->lineEdit_select_uage 的文本设置为 “-1”。

这段代码主要完成了从数据库查询数据并将结果填充到用户界面的操作。需要注意的是,如果涉及用户输入的 ui->lineEdit_select_uid->text() 不是数字,可能需要额外的验证和处理。此外,数据库的表结构和字段名需要与代码中的对应关系一致。

void MainWindow::on_pushButton_5_clicked()
{// 指定数据库驱动类型QSqlDatabase db = QSqlDatabase::addDatabase(ui->lineEdit_type->text());db.setDatabaseName(ui->lineEdit_dir->text());if (!db.open()){QMessageBox::information(nullptr, "信息", db.lastError().text(), QMessageBox::Ok);}// 查询数据QSqlQuery query("SELECT * FROM LyShark;",db);QSqlRecord rec = query.record();// 循环所有记录while(query.next()){// 判断当前记录是否有效if(query.isValid()){// 读出数据int id_ptr = rec.indexOf("id");int id_value = query.value(id_ptr).toInt();// 如果是则填充表格if(QString::number(id_value) == ui->lineEdit_select_uid->text()){int name_ptr = rec.indexOf("name");QString name_value = query.value(name_ptr).toString();ui->lineEdit_select_uname->setText(QString(name_value.data()));int age_ptr = rec.indexOf("age");QString age_value = query.value(age_ptr).toString();ui->lineEdit_select_uage->setText(QString(age_value.data()));}}else{ui->lineEdit_select_uname->setText("-1");ui->lineEdit_select_uage->setText("-1");}}
}

读者可通过输入一个唯一的标识符,例如UID号,来实现对特定数据的查询功能,如下图所示;

数据的跟新只需要调用update语句即可实现,其他的功能与查询保持一致,如下代码实现了数据的共恶心操作,以下是代码的概述:

  1. 建立数据库连接:
    • 使用 QSqlDatabase::addDatabase 设置数据库的驱动类型,例如 “QSQLITE”、“QMYSQL” 等。
    • 使用 setDatabaseName 设置数据库名称,这可能是一个本地文件名或者服务器地址。
    • 尝试打开数据库连接,如果连接失败,通过 QMessageBox 显示错误信息。
  2. 执行数据库更新:
    • 从用户界面的输入框中获取更新所需的数据,包括 uidname、和 age
    • 构建 SQL 更新语句,例如 UPDATE LyShark SET name='newName', age=25 WHERE id=123;
    • 使用 db.exec(sql) 执行 SQL 更新语句。
  3. 事务的提交和关闭:
    • 尝试提交事务,如果成功,显示更新数据成功的消息,否则显示更新数据失败的消息。
    • 关闭数据库连接。

需要注意:

  • 在一般情况下,Qt 的数据库操作会自动处理事务,你不必显式调用 commit()
  • 使用 std::cout 输出日志不太符合 Qt 的风格,Qt 提供了 qDebug() 用于输出调试信息。
  • 对于事务,通常在更新操作后关闭数据库连接,而不是在提交事务之前。
void MainWindow::on_pushButton_6_clicked()
{// 指定数据库驱动类型QSqlDatabase db = QSqlDatabase::addDatabase(ui->lineEdit_type->text());db.setDatabaseName(ui->lineEdit_dir->text());if (!db.open()){QMessageBox::information(nullptr, "信息", db.lastError().text(), QMessageBox::Ok);}// 执行SQL更新记录int uid = ui->lineEdit_select_uid->text().toInt();QString name = ui->lineEdit_select_uname->text();int age = ui->lineEdit_select_uage->text().toInt();QString sql = QString("UPDATE LyShark SET name='%1', age=%2 WHERE id=%3;").arg(name).arg(age).arg(uid);db.exec(sql);std::cout << "update => " << sql.toStdString() << std::endl;// 提交事务请求bool ref = db.commit();if(ref == true){QMessageBox::information(nullptr, "信息", "更新数据失败", QMessageBox::Ok);}else{QMessageBox::information(nullptr, "信息", "更新数据成功", QMessageBox::Ok);}db.close();
}

读者可通过输入一个UID编号查询数据记录,接着在修改对应的字段值,并点击更新按钮刷新数据库,如下图所示将第一个记录的姓名刷新为lyshark

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

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

相关文章

Cloudstack多个管理服务器节点

https://docs.cloudstack.apache.org/en/4.18.0.0/adminguide/reliability.html 参考翻译&#xff1a; 代理上支持多个管理服务器 在具有多个管理服务器的Cloudstack环境中&#xff0c;可以根据算法配置代理&#xff0c;将其连接到哪个管理服务器。这对于内部负载均衡器或高可…

【机器学习】人工智能概述

人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是一门研究如何使机器能够像人一样思考、学习和执行任务的学科。它是计算机科学的一个重要分支&#xff0c;涉及机器学习、自然语言处理、计算机视觉等多个领域。 人工智能的概念最早可以追溯到20世…

3.docker 安装失败

1、错误描述 2、报错前操作 ① 安装yum工具 yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken ② 更新本地镜像源 # 设置docker镜像源 yum-config-manager \--add-repo \https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo…

扫描全能王启动鸿蒙原生应用开发,系HarmonyOS NEXT智能扫描领域首批

近期&#xff0c;“鸿蒙合作签约暨扫描全能王鸿蒙原生应用开发启动仪式”&#xff08;简称“签约仪式”&#xff09;正式举行。合合信息与华为达成鸿蒙合作&#xff0c;旗下扫描全能王将基于HarmonyOS NEXT正式启动鸿蒙原生应用开发。据悉&#xff0c;扫描全能王是鸿蒙在智能扫…

DM、HIVE和Kingbase8(人大金仓数据库)给列增加备注

DM数据库给列增加备注 1、创建表 CREATE TABLE test222 ( id int NOT NULL PRIMARY KEY, name varchar(1000) DEFAULT NULL, email varchar(1000) DEFAULT NULL, phone varchar(1000) DEFAULT NULL ) 2、给列添加注释 comment on column TEST222.NAME is 这是一个列注释; 例如…

说说 Spring Boot 实现接口幂等性有哪几种方案?

一、什么是幂等性 幂等是一个数学与计算机学概念&#xff0c;在数学中某一元运算为幂等时&#xff0c;其作用在任一元素两次后会和其作用一次的结果相同。 在计算机中编程中&#xff0c;一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数或幂等…

关联规则+聚类分析+分类算法(数据挖掘)

3.关联规则 经典案例 : 尿布与啤酒的故事&#xff1b; 基本概念 : 设I {i1,i2,....im}是项(Item)的集合。 D 是 事务(transaction)的集合(事务数据库)。 事务T是项的集合&#xff0c;且对每个事务具有唯一的标识: 事务号&#xff0c;记作TID; 设A是I中的一个项集&#xf…

Redis分布式缓存之主从哨兵分片集群

Redis主从 数据同步原理 Redis哨兵 Redis分片集群 集群伸缩&#xff1a;在集群中插入或删除某个节点 集群故障转移

Android 13 - Media框架(28)- ACodec(五)

前面几节我们了解了OMXNodeInstance是如何处理setPortMode、allocateBuffer、useBuffer的&#xff0c;这一节我们再回到ACodec&#xff0c;来看看 ACodec start 的其他部分。 我们首先来回顾一下&#xff0c;ACodec start 的状态切换以及处理的事务&#xff0c;我们用一张不太准…

「GPT」G、P、T分别是啥意思?

G意为Generative &#xff1a;生成式 比如&#xff0c;生成式的分类器&#xff08;模型&#xff09;包括---- generative classifiers: naive Bayes classifier and linear discriminant analysis 与之对应的为判别式----- discriminative model: logistic regression P意为…

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践 一、需求二、上传本地 Git 仓库2.1 初始版本2.2 优化版本 三、 GitHub 创建空仓库3.1 初始版本3.2 优化版本 一、需求 app目录下的每个文件夹都是一个git仓库&#xff0c;如何使用shell脚本将所有git仓库都上传到github上…

记一次Mac端mysql重置密码

在执行mysql命令的时候&#xff0c;报如下的错误&#xff0c;表示不支持mysql命令&#xff1a; zsh: command not found: mysql 1. 先查看mysql服务是否存在 在系统偏好设置中查看&#xff1a; 2. 发现mysql服务已经在运行&#xff0c;可能因为/usr/local/bin目录下缺失mysq…

如何使用设计模式来解决类与类之间调用过深的问题。

我们将使用责任链模式和装饰者模式的组合。 考虑一个简化的餐厅订单处理系统&#xff0c;其中包括服务员&#xff08;Waiter&#xff09;、厨师&#xff08;Chef&#xff09;和收银员&#xff08;Cashier&#xff09;。订单从服务员开始&#xff0c;然后传递给厨师&#xff0c…

ubuntu22.04搭建RTSP服务器

大致命令如下&#xff1a; git clone --depth 1 gitgithub.com:ZLMediaKit/ZLMediaKit.git sudo apt-get install build-essential sudo apt-get install cmake #除了openssl,其他其实都可以不安装 sudo apt-get install libssl-dev sudo apt-get install libsdl-dev sudo apt…

linux基于用户身份对资源访问进行控制的解析及过程

linux中用户分为三类 1.超级用户&#xff08;root&#xff09; 拥有至高无上的权限 2.普通用户 人为创建、权限小&#xff0c;权限受到控制 3.程序用户 运行程序的用户&#xff0c;不是给人使用的&#xff0c;给程序使用的&#xff0c;一般不给登录&#xff01; 组账…

【LeetCode刷题笔记(13-1)】【Python】【回文数】【反转整数】【简单】

文章目录 引言回文数题目描述提示 题意分析解决方案1&#xff1a;【反转字符串】解决方案2&#xff1a;【反转整数】题外话结束语 9. 回文数 引言 编写通过所有测试案例的代码并不简单&#xff0c;通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例&#xff0…

【AI】人工智能爆发推进器之卷积神经网络

目录 一、什么是卷积神经网络 1. 卷积层&#xff08;Convolutional Layer&#xff09; 2. 激活函数&#xff08;Activation Function&#xff09; 3. 池化层&#xff08;Pooling Layer&#xff09; 4. 全连接层&#xff08;Fully Connected Layer&#xff09; 5. 训练过程…

html table+css实现可编辑表格

要实现可编辑的 HTML 表格&#xff0c;你可以使用 JavaScript 和 HTML5 的 contenteditable 属性。 <!DOCTYPE html> <html> <head><style>table {border-collapse: collapse;width: 100%;}th, td {border: 1px solid black;padding: 8px;text-align:…

区块链白皮书:基础建设见成效,国产自主生态正发展壮大

“区块链是全球信任机器的重要组成部分”——比尔盖茨 随着科技的飞速发展&#xff0c;区块链技术已成为引领全球创新的重要力量。近日&#xff0c;中国信通院发布了《区块链白皮书&#xff08;2023年&#xff09;》&#xff0c;为我们揭示了这一领域的前沿动态和未来发展趋势…

JDK 14全景透视:每个Java开发者必知的新特性

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 JDK 14全景透视&#xff1a;每个Java开发者必知的新特性 前言&#xff1a;switch表达式标准化Switch表达式成为正式特性的意义&#xff1a;如何使用Switch表达式&#xff1a;注意事项&#xff1a; ins…