Qt5.6+MySql实现图书馆在线管理系统(小白初笔,欢迎交流)第一天

      嗯。。导师让做一个与大数据相关的图书馆系统。硬着头皮一边学 一边做吧。只会一点C++,所以打算用Qt实现。把学习的记录下来,与大家一起分享吧,写的顺序可能会比较随意,欢迎交流。

   大笑适合人群:对qt  mysql稍微懂一点

      大笑 针对具体功能一步步写,整体性可能会稍微差一点,欢迎留言交流。 

                                                                                                                    学不在多,贵在坚持。一起加油!

主要分为客户端 服务器端  和数据库。服务器端与数据库连接。

实现功能:客户端:图书搜索 ,网友聊天 ,文件传输 ,图书推荐(具体实现可能很复杂,尽量研究出来),建议留言

服务器端:图书的管理  接收留言反馈

废话不多说,直接上干货。

(一)服务器端 与 数据库连接

    1.配置数据库

一般会选择mysql数据库,我原本想连接ORACLE(感觉ORACLE上档次一些,哈哈),但是Qt连接ORACLE需要的驱动需要自己去编译,小编捣鼓了半天也没搞好,最后还是从一个大神的博客下载了,可以用,所以建议想用oracle的同学们直接去下载动态库吧,自己编译。。。好难搞。最后我还是选择了Mysql,比oracle简答太多。

  干货1:Qt与mysql连接。

从mysql官网下载后,不能可视化的编辑,只有自带的窗口编辑模式,所以一般下载navicat,网上有中文破解版,大家自行百度。安装完成后,将navicat与mysql连接起来。我新建了一个数据库 library,aaa随便取名。

在aaa里面新建表,用到三个表,。分别是所有图书的表,学生借阅的图书表,学生信息表。

右键单击aaa 查找连接信息,这里很有用,用qt连接时会用到


2.回到qt,连接数据库。

  (1)打开服务器端工程文件,在工程文件.pro中 Qt+=后加入模块 network(网络编程中会用到) 、sql(数据库需要用到的模块),在.pro文件最后加入CONFIG+=C++11   因为会使用到lambda表达式

在main.cpp文件中 包含下列头文件

#include<QSqlDriver>
#include<QSqlDatabase>
#include <QLibrary>
#include<QSqlQuery> 
在main主函数中 加入  这时就需要navicat中的连接信息了
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("127.0.0.1"); //数据库的主机名 或者 Ip地址  可以写localhost或者127.0.0.1 也就是本地的ip地址
    db.setDatabaseName("library");// 使用的数据库名 这里我用的是library 
    db.setUserName("root");
    db.setPassword("****"); //密码就是 安装mysql时的密码了 我就用****隐藏了 因为我所有的密码都是一样的  哈哈哈
    bool ok = db.open();
    if(ok){
          qDebug()<<"成功连接数据库";
    }else{
          QMessageBox::warning(NULL,"警告","无法连接数据库");
    }
这时连接应该是不成功的 还缺少了一步  需要将mysql中的一个动态库黏贴到qt的动态库中,具体说:
 把在MySQL的安装目录中的libmysql.dll复制到QT_home/Qt5.3.15.3/mingw482_32/bin的目录下

此时应该成功了 如果还不行 可以参考这篇文章 写的很好 很详细点击打开链接

https://blog.csdn.net/yy64578537/article/details/71006042


(二)客户端输入用户名 密码 进行验证

思路:客户端输入用户名 密码后 使用tcp通信 将信息发给服务器 服务器进行检索验证 如果存在这个用户 则分配线程给他 若不存在 提示他重新输入 并断开此次连接。


登陆按钮转到槽 转到clicked()槽

void MainWindow::on_pushButtonDL_clicked()
{
    username=ui->lineEdituesr->text().trimmed();   //获取输入的用户名 密码 去掉空格
    password=ui->lineEditpasseord->text();
    QString information=username+"##"+password;  //用 ## 分隔开 用户名 和  密码  拆包时会用到
  socket->abort();//取消已有的连接
    socket->connectToHost(QHostAddress(serverIp),8888);    //QTcpsocket指对象 先连接到服务器 使用connecttohost函数 指定tcp通信的端口8888
    quint64 num=socket->write(information.toLatin1().data());  //用write函数 发送消息 返回发送的字节  若发送失败,返回-1
 }

这样就将用户名 和密码成功发送给服务器  服务器端接收传来的信息

服务器端:将接收的函数写在 窗口的构造函数中

笔记1:tcp通信时 服务端需要两个套接字 监听套接字和通信套接字 分别用QTcpServer 和 QTcpSocket类初始化  客户端发送的信息都保存在通信套接字中

笔记2:监听的端口 必须与客户端发送时的端口一致  否则监听不到

笔记3:lambda表达式的使用

[=]()                                                        =的作用:  将外面的局部变量添加进来 

{

        //函数体

}

ServerWindow::ServerWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ServerWindow)
{
    ui->setupUi(this);
    port=8888;
    server=new QTcpServer(this);
    socket=new QTcpSocket(this);
    server->listen(QHostAddress::Any,port);//监听
    //获取通信套接字
    connect(server,&QTcpServer::newConnection,     //newConnection信号  当有新的连接发生时 会触发这个信号
            [=]()                                  //lambda表达式  注意在.pro文件中需要添加config+=c++11才能使用 
    {
        socket=server->nextPendingConnection(); //当有新的连接进入时 使用nextpendingconnection获取通信套接字
        connect(socket,&QTcpSocket::readyRead,    //当有数据传送过来是  触发readyread信号 udp通信中也是用到这个信号
                [=]()
        {
            QByteArray array;
            array=socket->readAll();        //用字节数组读取所有内容
            //获取用户名  密码               发送过来的是  用户名##密码  用section拆包  section函数用法请自行百度
           username=QString(array).section("##",0,0);
           password=QString(array).section("##",1,1);
           //执行sql查询 判断是否正确  如果正确 服务器端向客户端发送字符串true
           if(Testinfo(username,password))
           {          
               QString temp="true";
               socket->write(temp.toUtf8());
           }
           }
        //如果错误 断开连接
           else
           {
               QString temp="false";
               qDebug()<<temp;
               socket->disconnectFromHost();
               socket->close();
               socket=NULL;
           }

           //如果错误 断开连接 并告诉客户端重新输入
        });
    });

qt中执行sql语句 并对数据库内容产生影响:

笔记1:QT中使用QSqlQUery这个类来实现  先初始化QsqlQuery对象 query

//检验用户是否存在  并且防止sql注入攻击   
// sql注入攻击  简单说 就是 当sql语句的某些部分需要传参时,如果用户输入or1=1,那将会把数据库所有内容
读出来
bool ServerWindow::Testinfo(QString username, QString password)
{
    QString s1="select count(*) from student where sid=:username and spassword=:password;";
    query.prepare(s1); //用paepare方式解析sql语句
    query.bindValue(":username",username);//bindValue函数 实现占位符的替换
    query.bindValue(":password",password);
    query.exec(); //执行sql语句
    if(query.next()) //如果执行后有返回值  说明学生表中存在该用户名和密码
    {
        return true;
    }
    return false;
}

在客户端增加一个槽函数  处理服务器发来的消息

成功时

 connect(socket,&QTcpSocket::readyRead,
            [=]()
    {
        QByteArray array;
        array=socket->readAll();
        QString temp=QString(array);
        qDebug()<<temp;
        if(temp.compare(QString("true"))==0)
        {
             QMessageBox::information(this,tr("消息"),tr("登陆成功"));
             //登录到主界面  隐藏登陆界面
             this->hide();
             zjm=new zhujiemian();
             zjm->show();
        }
     }
    );
//如果账号密码错误  服务器端断开连接  此时客户端触发disconnected信号
 connect(socket,&QTcpSocket::disconnected,
            [=]()
    {
         //登陆失败 重置输入框
            QMessageBox::warning(this,tr("警告"),tr("用户名或密码错误"),QMessageBox::Yes);
            ui->lineEdituesr->clear();
            ui->lineEditpasseord->clear();
            ui->lineEdituesr->setFocus();//将焦点 重置在 用户名输入框
    });

好了 第一天先到这里 后续再更新 笔者小白一枚,代码可能比较low,有疑惑或者补充欢迎交流

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页