2021.8.17课堂笔记

SQL语言主要由3部分组成:
(1) 数据定义语言(DDL,Data Desciption Language)。用于执行数据库定义的任务,对数据库以及数据库中的各种对象进行创建、删除、修改等操作(CREAT TABLE 或 DROP TABLE)。数据库对象主要包括表、默认约束、规则、视图、触发器、存储过程。
(2) 数据操纵语言(DML,Data Manipulation Language)。用于操纵数据库中各种对象,检索和修改数据词(INSERT,UPDATE和DELETE)。
(3) 数据查询语言(DQL:Data Query Language)。也称为“数据检索语句”,用以从表中获得数据,确定数据怎样在应用程序给出。保留字SELECT是DQL(也是所有SQL)用得最多的动词,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。
===============================================================
视图是从一个或多个表(或视图)导出的表。
视图与表不同,它是一个虚表,即视图所对应的数据不进行实际存储,数据库中只存储视图的定义,对视图的数据进行操作时,系统根据视图的定义去操作与视图相关联的基本表。视图一经定义以后,就可以像表一样被查询、修改、删除和更新。
【重点】:视图不进行实际的存储,而只是存储视图的定义

===============================================================
Qt使用数据库编程:
1. 加入头文件:#include <QtSql>
2. 在 .pro文件中添加:QT += sql
3. QSqlDatabase类;实现了数据库连接的操作
4. Open()
5. QSqlQuery类;执行SQL语句
QSqlRecord类;封装数据库所有记录

上述语句里的重点是:在 .pro文件中添加:QT += sql !!!~

要有个意识:如果你在编程中发现你写的类或者函数未定义的话,你要第一个考虑是这个类或者函数的头文件有没有写???

==================================================================
QSqlDatabase db = QSqlDatabase::addDatabase(“QMYSQL”,”conn1”);
db.setHostName("127.0.0.1");   // 这边的127.0.0.1表示的是本地的数据库 
db.setDatabaseName("test");
db.setUserName("root");
db.setPassword("123");
bool ok = db.open();
db.close()

==================================================================
QtSqlQuery执行查询(SELECT)语句.
【结果集:select的执行结果,指针位于第一条结果的前面。】

=================================================================
  QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "conn1"); //连接哪个类型数据库
    db.setHostName("127.0.0.1");  //设置连接属性
    db.setDatabaseName("test.db");   //设置连接属性
    db.setUserName("root");         //设置连接属性
    db.setPassword("123");      //设置连接属性
    bool ok = db.open();        //开始物理连接数据库
    if(ok)
    {
        qDebug()<<"打开数据库成功";
    }
    else {
        return ;
    }

  //这边运用的函数要和上面的db联系起来,不然就不知道你打开的是哪个数据库了!~
   QSqlQueryModel* model = new QSqlQueryModel;
   //设置查询语句
   model->setQuery("select * from student", db);
   for(int i=0; i<model->rowCount(); i++)
   {
       int id =  model->record(i).value("id").toInt();
       QString name = model->record(i).value("name").toString();

       qDebug()<<"id:"<<id<<" "<<"name:"<<name;
   }
   db.close();         //关闭数据库连接
===============================================================
【QSqlTableModel类】
QSqlTableModel:提供了一个可读写的数据模型用于操作表,例如修改,插入,删除,查询,和排序;
函数:
• settable()//指定数据库表
• rowCount () // 返回行数
• columnCount () // 返回列数
• removeColumns() //删除列
• submitAll (),//提交所有被修改的数据,然后修改的数据被保存在数据库中
• revertAll () //撤销所有的修改
• setFilter() //筛选,相当于SQL中的WHERE语句
• select () //在筛选和排序的条件下,将数据库中符合要求的在表格中显示出来
• setSort ( int column, Qt::SortOrder order ) //排序操作
• insertRow () //插入行
• insertColumn () // 插入列
• setEditStrategy(); //设置编辑策略

=============================================================
 QSqlTableModel* model = new QSqlTableModel(this, db);
    model->setTable("student");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();
    model->setFilter("name='xiaopang'"); //根据姓名进行筛选,要注意的单引号的使用
    model->select(); //显示结果

    QTableView* view = new QTableView;
    view->setModel(model);
    view->show();
===========================================================
QSqlTableModel* model = new QSqlTableModel(this, db);  //插入的示例
    model->setTable("student");
    int rowNum = model->rowCount();
    int id = 11;
    model->insertRow(rowNum);
    model->setData(model->index(rowNum,0),id);
    model->setData(model->index(rowNum,1), "xiaoli");
    model->submit();
=======================================================
 QSqlTableModel* model = new QSqlTableModel(this, db);      //修改方式1
    model->setTable("student");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select(); //选取整个表的所有行,就是选中表中的数据

    //record记录model的第5(4+1)行数据
    QSqlRecord record = model->record(4);
    //record把记录的值修改下
    record.setValue("name",record.value("name").toString()+"5555");
    record.setValue("id", record.value("id").toInt()+20);
    //model的第5(4+1)行记录重新set下
    model->setRecord(4, record);

    if(model->submitAll())
    {
        qDebug()<<"success";
    }
=============================================
QSqlTableModel* model = new QSqlTableModel(this, db);  //修改方式2
    model->setTable("student");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select(); //选取整个表的所有行,就是选中表中的数据
    model->setData(model->index(0,0), 100);       //这里的index函数指明是 具体哪一个数据,是通过数据下标来定位具体数据
    model->setData(model->index(0,1), "1111");   
    model->setData(model->index(1,1), "hello11");

    if(model->submitAll())
    {
        qDebug()<<"success";
    }
=============================================
线程中最根本一个知识点:
线程的启动:myThread[i]->start();    //这个start函数就是myThread类的run函数

myThread[i]->terminate();  //使线程停止运行,具体什么时候结束看系统的调度
myThread[i]->wait();  //等待线程结束   ->就是run函数运行结束!~

1)线程就是你创建一个线程类A(继承QThread类);
2)在线程类A里,创建一个成员函数run
3)在其他主类里,创建线程类A的对象a
4)启动线程是a->start(),这个就是启动线程,就是启动线程类A里的run函数
====================================================
【QWaitCondition类来实现】
void Producer::run()
{
    for(int i=0;i<DataSize;i++)
    {
        mutex.lock(); // 互斥量变为加锁状态

        if(numUsedBytes==BufferSize)    //资源池里已经满了,无法继续填充了
            bufferEmpty.wait(&mutex);     //阻塞等待,此时的互斥量处于解锁状态

        buffer[i%BufferSize]=numUsedBytes;   //资源池里不满,可以继续填充
        ++numUsedBytes;
        bufferFull.wakeAll();                 //唤醒所有的线程, 互斥量处于加锁状态

        mutex.unlock();
    }
}
===========================================================
【网络基础知识点】
• TCP/IP:传输控制协议/因特网互联协议(网络通讯协议),是Internet最基本的协议,由传输层的TCP协议和网络层的IP协议等组成; 
• HTTP(Hyper Text Transfer Protocol):超文本传输协议,面向网页,传输被包装成TCP协议传输;
• FTP(File Transfer Protocol):文件传输协议,面向文件;
• SOCKET:是实现传输层协议的一种编程API,可以是TCP,也可以是UDP;
• URL(Uniform Resoure Locator):统一资源定位符,是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。URL由三部分组成:资源类型、存放资源的主机域名、资源文件名。
• IP地址:Internet上的每台主机(Host)都有一个唯一的IP地址。IP协议就是使用这个地址在主机之间传递信息,分为IPv4与IPv6两大类。
• 端口:TCP/IP协议通过不同的逻辑端口来区分不同的服务(HTTP-80、FTP-20/21、SMTP-25等)。端口号,范围是从0 到65535,1024以下被占用。
• socket起源于Unix,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。

•socket类型:
1)数据流SOCK_STREAM:基于TCP的Socket,面向连接,提供给应用层可靠的流式数据服务,使用TCP的Socket应用程序协议:HTTP,FTP等。优点:基于数据传输的可靠性。
2)数据报SOCK_DGRAM:基于UDP的Socket,无连接,适用于数据传输可靠性要求不高的场合。基于UDP的Socket应用程序或协议有:RIP,SNMP,L2TP等。

=======================================================================
【★★★★★★★★★★★★★★★★★★★★TCP连接的步骤★★★★★★★★★★★★★★★★★★】
• TCP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket(); 
2、设置socket属性,用函数setsockopt(); * 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、开启监听,用函数listen(); 
5、接收客户端上来的连接,用函数accept();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
8、关闭监听;
• TCP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect(); 
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;

【★★★★★★★★★★★★★★★★★★★★TCP三次握手★★★★★★★★★★★★★★★★★★】
TCP三次连接:
① 客户端发送一个SYN段(同步序号)指明客户打算连接的服务器端口,以及初始化序号(ISN) 。
② 服务器发回包含服务器的初始序号的SYN报文段作为应答。同时,将确认序号(ACK)设置为客户的ISN加1以对客户的SYN 报文段进行确认。一个SYN将占用一个序号。
③ 客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认。

【★★★★★★★★★★★★★★★★★★★★UDP连接的步骤★★★★★★★★★★★★★★★★★★】
• UDP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接;
• UDP编程的客户端一般步骤是:
1、创建一个socket,用函数socket(); 
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置对方的IP地址和端口等属性; 
5、发送数据,用函数sendto();
6、关闭网络连接;

===============================================================================
Qt提供了QtNetwork模块来进行编程。Linux网络编程使用socket接口来进行,Qt对其进行封装,形成其他类。
• 应用层:QFtp类等
• 底层:QTcpSocket类、QUdpSocket类、QTcpServer等 
• 网络操作: QNetworkRequest类、 QNetworkAccessManagement类、QNetworkReply类 
• 其他负载管理类,代理类等

Qt中提供了几个用于获取主机网络信息的类,包括QHostInfo、QHostAddress、QNetworkInterface以及QNetworkAddress等。
• QHostInfo:查询主机名或IP地址
• QHostAddress:主机地址
• QNetworkInterface:获取主机IP列表和网络接口
• QNetworkAddress:网络地址

===============================================
    //获取电脑的主机名
    QString strLocalHost = QHostInfo::localHostName();
    qDebug()<<strLocalHost;
    //获取电脑里所有的IP地址
    QHostInfo ipinfo = QHostInfo::fromName(strLocalHost);
    qDebug()<< ipinfo.addresses();

==================================================
构造函数写:int id = QHostInfo::lookupHost("www.baidu.com", this, SLOT(lookedUp(QHostInfo)));

//lookedUp这个函数是槽函数,需要在类里面进行槽函数的声明
void Widget::lookedUp(const QHostInfo &host)
{
    if (host.error() != QHostInfo::NoError)
    {
        qDebug() << "Lookup failed:" << host.errorString();
        return;
    }
    foreach (const QHostAddress &address, host.addresses())
    {
        // 输出IPV4、IPv6地址
        if (address.protocol() == QAbstractSocket::IPv4Protocol)
            qDebug() << "Found IPv4 address:" << address.toString();
        else if (address.protocol() == QAbstractSocket::IPv6Protocol)
            qDebug() << "Found IPv6 address:" << address.toString();
        else
            qDebug() << "Found other address:" << address.toString();
    }
}

【程序运行结果】
Found IPv4 address: "36.152.44.95"
Found IPv4 address: "36.152.44.96"
=================================================
 QHostInfo host = QHostInfo::fromName("127.0.0.1");
    if (host.error() != QHostInfo::NoError)
    {
        qDebug() << "Lookup failed:" << host.errorString();
        return;
    }
    qDebug() << "Found hostName:" << host.hostName();
}
【程序运行结果】
Found hostName: "DESKTOP-EUHF45F"
====================================================
【★★★★★★★★★★★★★★★★★★★★UDP C/S编程模型★★★★★★★★★★★★★★★★★★】
Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收,继承于QAbstractSocket。
服务器端建立一个UDP Socket并绑定在固定端口后,用信号与槽的方式进行监听是否有数据来临。
函数:
• bind():绑定IP地址和端口号
• writeDatagram():写/发送数据报,函数有四个参数,分别是数据报的内容,数据报的大小,主机地址和端口号, 广播地址QHostAddress::Broadcast:同时给网络中所有的主机发送数据报
• readDatagram():读数据报
• hasPendingDatagrams():判断是否有等待读取的数据报
• pendingDatagramSize():获取数据报大小
===============================================
QUdpSocket类最通用的使用方式是:
• 用 bind() 函数绑定一个IP地址和端口Port,然后调用 writeDatagram() 和 readDatagram() 函数传输数据。
• 如果要使用QIODevice中的read(), readLine(), write()等函数,必须首先调用connectToHost()函数,
直接建立一个和对方的连接。
• 只要向网络写入了一个数据报,SOCKET就产生一个 bytesWritten() 信号,如果仅仅是发送数据报,无需调用bind()。 
• 数据报到来,readyRead()信号被产生,此时hasPendingDatagrams()函数返回真(true)。调用pendingDatagramSize()获取第一个数据报的长度(size),readDatagram()读取数据报内容。
• 注意 :接收到readyRead()信号后,应当读取该数据报,否则下一个数据报到来后将不再产生readyRead()信号。

================================================================
Qt中提供了:
QTcpSocket 类来进行TCP协议的连续数据流的发送和接收,继承于QAbstractSocket。
QTcpServer类在服务器端处理来自TCP客户端连接数据,需要注意的是,该类直接继承于QObject基类,而不是QAbstractSocket抽象套接字类。

======================================================================
【★★★★★★★★★★★★★★★★★★★★TCP C/S编程模型★★★★★★★★★★★★★★★★★★】
QTcpServer类:
• listen() :监听连接
• bool hasPendingConnections()const :如果服务端有一个待处理的连接,就返回真,否则返回假。
QTcpSocket* nextPendingConnection():返回一个套接字来处理一个连接,这个套接字作为服务端的一个子对象,意味着当QTcpServer对象销毁时候,这个套接字也自动删除,当使用完后明确的删除这个套接字也好,这样可以避免内存浪费。当没有可处理的连接时候,这个函数返回0。 
• serverAddress():服务端的地址
• serverPort():服务器端口。
• void setMaxPendingConnections(int numConnections):设定待处理的连接最大数目为numConnections,当超过了最大连接数后,客户端仍旧可以连接服务端,但是服务端不在接受连接,操作系统会把这些链接保存在一个队列中。
close():关闭套接字,停止对连接的监听。


QTcpSocket 继承于QAbstractSocket继承于QIODevice,可以通过使用QTextStream和QDataStream来进行读取和写入。
• peerAddress():获取IP地址 ,peer指用TCP协议连接在一起的主机的通称
• peerName():获取名称
• peerPort():获取端口号
• read()和write():进行读写
• bytesAvailable():返回包的字节数,读数据之前,确保里面有数据
• 关联connect(Socket, SIGNAL(readyRead()), this, SLOT(readMessage())); 当有数据发送过来指定的套接字,便执行槽函数
• close();套接字的关闭/服务器的关闭
• 发送数据时一定要最开始写入实际数据大小信息(占两个字节) 用quint16表示

信号:connected()成功与服务器建立连接后产生的信号;
readyRead ()有数据读信号;
bytesWritten()数据成功发送后产生的信号;
error()产生错误的信号;

【★★★★★★★★★★★★★★★★★★★★TCP C/S编程模型★★★★★★★★★★★★★★★★★★】
QTcpServer的基本操作: 
1、调用listen监听端口,每当一个新的客户端连接到服务端就会发射信号newConnection()。
2、连接信号newConnection,在槽函数里调用nextPendingConnection()获取,返回一个连接的QTcpSocket(),我们可以用这个返回的套接字和客户端进行连接。

QTcpSocket的基本操作:
1、调用connectToHost连接服务器。
2、调用waitForConnected判断是否连接成功。
3、连接信号readyRead槽函数,异步读取数据。
4、调用waitForReadyRead,阻塞读取数据。

有一个连接就触发incomingConnection(qintptr socketDescriptor)   //注意参数的数据类型qintptr

=================================================================
实现HTTP文件下载
• QNetworkAccessManager类:网络操作的协同工作,允许应用程序发送网络请求和接收网络应答。一旦一个请求被创建,那么应用程序就
可以使用它在网络上发送请求。它提供了一组标准的函数,可以承载网络请求和一些可选的数据,并且每一个请求返回一个QNetworkReply对
象。该返回的对象包含着返回的请求应带的所有数据。
• QNetworkRequest类:包含着在网络上发送请求的必要信息。它包含了一个URL和一些可以用来修改请求的附加信息。在一个请求对象被创
建的时候,指定的URL就可用来决定该请求所使用的协议。目前对于HHTP、FTP和本地文件的URL都支持下载和上传

• QNetworkReply类:网络请求的应答,当一个请求被分发后它就会由QNetworkAccessManager创建。
• QNetworkReply提供的信号可以被用来单独的检测每一个应答,或者开发者也可以选择使用manager的信号来达到这种目的,而放弃使用查询应答信息的方式。由于QNetworkReply是QIODevice的子类,应答信息可以被同步或者异步处理;例如阻塞或者非阻塞操作。
• 每一个应用都可以创建一个或者多个QNetworkAccessManager实例来处理网络通信。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值