更多精彩内容 |
---|
个人内容分类汇总 |
数据库开发 |
开发环境说明
- 通过按键新建 空白数据行;
- 使用自增Key;
- 通过按键更新数据;
- 判断表是否存在,不存在则创建。
- 用户登录功能,默认创建超级管理员账号root
- 支持用户后台管理,通过后台创建、修改、删除用户
- 用户分为超级管理员、普通管理员、普通用户三个等级;
- 超级管理员有所有权限,可创建、修改、删除普通管理员、普通用户;
- 普通管理员可创建、修改、删除普通用户,可新建、修改、查询数据;
- 普通用户不可修改用户信息,不可新建、修改数据库信息,只可查询。
实现效果如下:
啥也不说了,直接上代码,一切有注释
pro文件: Qt使用到数据库,上来什么都别管,先在pro文件添加上QT += sql
;
dialog.cpp文件:登录界面
#include "dialog.h"
#include "ui_dialog.h"
#include
#include
#include
bool Dialog::m_loggedIn = false; // 登录状态
QString Dialog::m_userName; // 登录的用户名
UserBackstage::UserType Dialog::m_userType; // 用户类型
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
this->setWindowTitle("登录");
m_db = QSqlDatabase::addDatabase("QSQLITE"); // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库
m_db.setDatabaseName("SignIn.db"); // 使用文件数据库(可生成数据库文件,数据一直有效)
if(!m_db.open()) // 打开数据库
{
QMessageBox::critical(nullptr, "Error", "打开数据库失败!");
return ;
}
// 创建一个用于保存用户信息的表
if(!isTableExists("User"))
{
QSqlQuery query;
// 创建一个表person,包含id、firstname、lastname三个字段
bool ret = query.exec("create table User ("
"id integer primary key," // 索引(自增key)
"userName varchar(20)," // 用户名
"password varchar(20)," // 密码
"type int)"); // 用户类型
if(!ret)
{
qDebug() << "创建表失败:";
}
else
{
QSqlQuery query;
query.prepare("insert into User(userName, password, type)"
"values (:userName, :password, :type)");
query.bindValue(":userName", "root");
query.bindValue(":password", "123456");
query.bindValue(":type", int(UserBackstage::Root));
query.exec();
}
}
}
Dialog::~Dialog()
{
if(m_db.isOpen())
{
m_db.close(); // 关闭数据库
}
delete ui;
}
/**
* @brief 返回登录状态
* @return true登录 false未登录
*/
bool Dialog::loggedIn()
{
return m_loggedIn;
}
/**
* @brief 返回登录的用户名
* @return 如果没有则为空
*/
QString Dialog::userName()
{
return m_userName;
}
/**
* @brief 返回登录的用户类型
* @return
*/
UserBackstage::UserType Dialog::type()
{
return m_userType;
}
/**
* @brief 判断表是否存在
* @param table
* @return
*/
bool Dialog::isTableExists(const QString &table)
{
QSqlQuery query;
QString sql = QString("select * from sqlite_master where name = '%1';").arg(table); // 查询sqlite_master表中是否存在表名
if(query.exec(sql))
{
return query.next();
}
return false;
}
/**
* @brief 登录
*/
void Dialog::on_but_signIn_clicked()
{
QString userName = ui->line_user->text().trimmed();
QString password = ui->line_password->text().trimmed();
if(userName.isEmpty())
{
QMessageBox::about(this, "注意!", "用户名不能为空");
return;
}
if(password.isEmpty())
{
QMessageBox::about(this, "注意!", "用户密码不能为空");
return;
}
// 从数据库中查询用户和密码,完成登录功能
QSqlQuery query;
QString sql = QString("select * from User where userName = '%1';").arg(userName); // 查询用户
if(query.exec(sql))
{
if(query.next()) // true则用户存在
{
if(password == query.value("password").toString()) // 密码相等
{
m_userName = userName;
m_userType = UserBackstage::UserType(query.value("type").toInt());
m_loggedIn = true;
this->close();
}
else
{
QMessageBox::about(this, "注意", "输入密码错误!");
}
}
else
{
QMessageBox::about(this, "注意", "用户不存在!");
}
}
else
{
QMessageBox::about(this, "注意", "sql指令执行失败!");
}
}
widget.cpp文件: 数据显示界面
#include "widget.h"
#include "ui_widget.h"
#include "dialog.h"
#include "userbackstage.h"
#include
#include
#include
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QString user;
switch (Dialog::type())
{
case UserBackstage::User:
{
ui->but_user->setVisible(false); // 隐藏用户管理功能
ui->but_add->setVisible(false); // 隐藏数据新建功能
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); // 普通用户禁用修改数据功能
user = QString("普通用户:%1").arg(Dialog::userName());
break;
}
case UserBackstage::Admin:
{
user = QString("普通管理员:%1").arg(Dialog::userName());
break;
}
case UserBackstage::Root:
{
user = QString("超级管理员:%1").arg(Dialog::userName());
break;
}
}
this->setWindowTitle(QString("QSql-用户登录Demo - V%1 %2").arg(APP_VERSION).arg(user));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_but_connect_clicked()
{
if(ui->but_connect->text() == "关闭数据库")
{
ui->but_connect->setText("连接数据库");
m_db.close();
}
else
{
m_db = QSqlDatabase::addDatabase("QSQLITE"); // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库
// qDebug() << QSqlDatabase::defaultConnection; // 打印默认数据库连接名称
m_db.setDatabaseName("SignIn.db"); // 使用文件数据库(可生成数据库文件,数据一直有效)
if(!m_db.open()) // 打开数据库
{
QMessageBox::critical(nullptr, "Error", "打开数据库失败!");
return ;
}
// 如果表不存在则创建表
if(!isTableExists("person"))
{
QSqlQuery query;
// 创建一个表person,包含id、firstname、lastname三个字段
bool ret = query.exec("create table person ("
"id integer primary key," // 索引(自增key),使用integer默认为自增, int不能设置主键自增
"firstname varchar(20)," // 名
"lastname varchar(20))"); // 姓
if(!ret)
{
qDebug() << "创建表失败:";
}
}
initModel();
ui->but_connect->setText("关闭数据库");
}
}
/**
* @brief 判断表是否存在
* @param table 表名称
* @return true存在 false不存在
*/
bool Widget::isTableExists(const QString &table)
{
QSqlQuery query;
QString sql = QString("select * from sqlite_master where name = '%1';").arg(table); // 查询sqlite_master表中是否存在表名
if(query.exec(sql))
{
return query.next();
}
return false;
}
/**
* @brief SQL 表模型(QSqlTableModel)来编辑数据库中的信息
*/
void Widget::initModel()
{
if(m_model)
{
m_model->clear();
delete m_model;
m_model = nullptr;
}
m_model = new QSqlTableModel(this, m_db);
m_model->setTable("person"); // 设置需要显示的数据库表
#if 1
m_model->setEditStrategy(QSqlTableModel::OnFieldChange); // 在界面上修改后数据立刻保存到数据库
#else
m_model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 将将编辑数据库中值的策略设置为[在调用 submitAll() 或 revertAll() 之前,所有更改都将缓存在模型中(即在界面上修改数据后不会立刻存入数据库)]
#endif
m_model->setHeaderData(0, Qt::Horizontal, "ID");
m_model->setHeaderData(1, Qt::Horizontal, "名称");
m_model->setHeaderData(2, Qt::Horizontal, "姓氏");
ui->tableView->setModel(m_model);
}
/**
* @brief 添加空白数据行
*/
void Widget::on_but_add_clicked()
{
QSqlQuery query;
query.prepare("insert into person(firstname, lastname)" // 写入数据时不需写入id字段,实现自增
"values (:firstname, :lastname)");
query.bindValue(":firstname", "");
query.bindValue(":lastname", "");
query.exec();
m_model->select(); // 获取数据库中的数据
}
/**
* @brief 查询数据库更新界面
*/
void Widget::on_but_read_clicked()
{
if(!m_model) return;
m_model->select(); // 获取数据库中的数据
ui->tableView->resizeColumnsToContents(); // 根据表格中的内容自动调整列宽
}
void Widget::on_but_user_clicked()
{
UserBackstage user;
user.setUserType(Dialog::type());
user.exec();
}
userbackstage.cpp文件: 用户管理后台
#include "userbackstage.h"
#include "ui_userbackstage.h"
#include
#include
#include
UserBackstage::UserBackstage(QWidget *parent) :
QDialog(parent),
ui(new Ui::UserBackstage)
{
ui->setupUi(this);
m_model = new QSqlTableModel(this);
m_model->setTable("User"); // 设置需要显示的数据库表
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_model->setHeaderData(0, Qt::Horizontal, "ID");
m_model->setHeaderData(1, Qt::Horizontal, "用户名");
m_model->setHeaderData(2, Qt::Horizontal, "密码");
m_model->setHeaderData(3, Qt::Horizontal, "用户类型");
ui->tableView->setModel(m_model);
m_model->select(); // 获取数据库中的数据
ui->tableView->resizeColumnsToContents(); // 根据表格中的内容自动调整列宽
}
UserBackstage::~UserBackstage()
{
delete ui;
}
/**
* @brief 设置登录的用户类型
* @param type
*/
void UserBackstage::setUserType(UserBackstage::UserType type)
{
m_userType = type;
// 添加用户类型
ui->com_type->clear();
switch (type)
{
case User:
{
break;
}
case Admin:
{
ui->com_type->addItem("普通用户", User);
m_model->setFilter(QString("type = '%1'").arg(int(User))); // 只显示普通用户的信息
break;
}
case Root:
{
ui->com_type->addItem("普通用户", User);
ui->com_type->addItem("管理员", Admin);
break;
}
}
}
/**
* @brief 设置用户信息
*/
void UserBackstage::on_but_set_clicked()
{
QString userName = ui->line_user->text().trimmed();
QString password = ui->line_password->text().trimmed();
UserType userType = UserType(ui->com_type->currentIndex());
if(userName.isEmpty())
{
QMessageBox::about(this, "注意!", "用户名不能为空");
return;
}
if(password.isEmpty())
{
QMessageBox::about(this, "注意!", "用户密码不能为空");
return;
}
QSqlQuery query;
QString sql = QString("select * from User where userName = '%1';").arg(userName); // 查询用户
if(query.exec(sql))
{
if(query.next()) // true则用户存在则更新数据
{
int type = query.value("type").toInt();
if(type >= m_userType) // 如果修改的用户等级超过登录用户等级,则修改失败
{
return;
}
sql = QString("update User set password='%1', type=%2 where userName = '%3';")
.arg(password)
.arg(int(userType))
.arg(userName);
query.exec(sql);
}
else // 用户不存在则插入数据
{
query.prepare("insert into User(userName, password, type)"
"values (:userName, :password, :type)");
query.bindValue(":userName", userName);
query.bindValue(":password", password);
query.bindValue(":type", int(userType));
query.exec();
}
m_model->select(); // 获取数据库中的数据
}
else
{
qDebug() << "指令执行失败";
}
}
/**
* @brief 删除用户信息
*/
void UserBackstage::on_but_delete_clicked()
{
QString userName = ui->line_user->text().trimmed();
if(userName.isEmpty())
{
QMessageBox::about(this, "注意!", "用户名不能为空");
return;
}
QSqlQuery query;
QString sql = QString("delete from User where userName = '%1';").arg(userName); // 查询用户
if(query.exec(sql))
{
m_model->select(); // 获取数据库中的数据
}
else
{
qDebug() << "指令执行失败";
}
}