Qt 之数据库QSqlite应用

数据库的优点

1、一条记录中字段内容
如1条货号记录,在文本记录方式下,限制了其长度,如从原来的10个字节变成20个字。这是很困难的。此时数据库为你解决了这个问题
2、记录管理
仪表称重记录的读取、查询及修改比较是一个复杂的处理。往往会根据不同的硬件设计更高的效率。
数据库解决了这个问题。
3、数据库统一结构,适合于不同平台下的通讯

数据库网络上的应用

数据库在这里只作为存储。具体的数据交互还是由用户应用层来解决。目前不考虑网络直接共享数据库
,更何况SQLite也不适用于这种场合

QSqlite的应用笔记

https://www.runoob.com/sqlite/sqlite-data-types.html
一、查询数据库是否正确
数据库查询与修改软件: SQLiteStudio
应用方法略
二、网站
https://www.cnblogs.com/lifexy/p/10921958.html
比较详细的介绍,但没有成功,原因为其exec之间的输入命令用了大写。
实测:大写与小定都可识别
1、 关键字中,有的文章写大写,有的写小写,是否不同
答:实测相同:
query.exec(“CREATE table student (id int primary key,name varchar)”);

query.exec(“create table student (id int primary key,name varchar)”);
相同
2、SQL描述符格式中空格是否有要求
答:一个与多个都相同,如
query.exec(“CREATE table student (id int primary key,name varchar)”);

query.exec(“CREATE table student(id int primary key,name varchar)”);
3、一行写不下时,可以换行吗?
答:可以,如下
原:
query.exec(“CREATE table student (id int primary key,name varchar)”);
换行为
query.exec(“CREATE table student
(id int primary key,name varchar)”);
4、需要确认QSQLite:能否没有
设置数据库主机名
数据库用户名
数据库密码
答:不需要,因为SQLite中已指明不需要管理员。
如果设置了,也是无效的。比如用SQLiteStudio工具不输入密码照样能读写数据.
设置方法如下:
db.setHostName(“D38Weight”);
db.setDatabaseName(QApplication::applicationDirPath()+"/D38Weight.dat");
db.setUserName(“guojintao”);
db.setPassword(“123456”);
5、原数据库已存在,还能建相同的表吗?
答:不行,必须将原来的删除,才能建新的表。从这来年表只能建一次,要想新建表,则需删除原表。

6、原数据库已存在,还能建不同的表吗?
答:可以。直接添加新的表。与原表不冲突。
7、创建表及表列内容的方法:
答:query.exec(“CREATE table student1(id int primary key,name varchar,name2 varchar)”);
8、在指定表中添加数据
答:query.exec(“insert into student values(1,‘xiaogang1’,‘你好1’)”)
9、采用bindValue方式添加数据。
答:
第一步:query.prepare(“insert into student values(?,?,?)”); //?,?,?表示三个列,此时必须相同
第二步:输入数据:
query.bindValue(0,2); //(列号,内容)
query.bindValue(1,“00”);
query.bindValue(2,“002”);
success = query.exec();
注1:原则上“内容”格式要与列格式相同,比如(1,123),此时发现也能存储为0x31,0x32和0x03,那说明bindValue具有将int转为varchar的功能。
注2:再写同一行内容,如
query.bindValue(0,2); //(列号,内容)
query.bindValue(1,“22”);
query.bindValue(2,“22”);
success = query.exec();
此时将失败,原内容保持不变。
10、插入数据耗时情况
QTime t;
t.start();
success = query.prepare(“insert into student values(?,?,?)”);
for(int i=0;i<100;i++)
{
query.bindValue(0,i);
query.bindValue(1,QString(“name_%1”).arg(i));
query.bindValue(2,QString(“name2_%1”).arg(i));
success = query.exec();
}
qDebug()< 结果: “插入 10 条记录,耗时: 7761 ms”
说明挺费时的。平均一条记录要80ms;原因可能是,写一条记录就直接操作硬盘。

11、修改某一行数据
答:(耗时80ms1条记录,与写新的记录相同)
第一步:query.clear(); //必须执行
第二步: query.prepare(QString(“update student set name=?,name2=? where id=%1”).arg(i)); //确定哪一行记录中的哪些项。
第三步:
query.bindValue(0,QString(“tao_%1”).arg(i10));
query.bindValue(1,QString(“tao2_%1”).arg(i));
第四步:
query.exec();//执行修改
注bindValue中编号“0”,的作用同QString(%1,%2).arg(
).arg(#)相同。表示第几项。应用时可任意指定.比如:
query.prepare(QString(“update student set name2=?,name=? where id=%1”).arg(i));
这时你会发现数据tao_10,写入name2列了。
注:where 后面是条件
12、能否修改key
答:能修改,但不同修改成与其它key相同。操作会失败(即不让你操作)。
13、删除一条记录
query.exec(“delete from student where name = ‘汉好’”);
14、称重记录中的数据类型
1)车号、货号、客户等字符串的以varchar类型
这是一种变长类型,可满足各种长度的输入。如果采用定长,如char[25]。则可能25个字节都不够,那就设成50个,这时将导致资源极大浪费。
所以对于定长的名称可以采用定长,如车号.但长远考虑兼容问题,且也不担心存储容量问题,所以定为变长型,即varchar
经实验,QSqlite就算设成定长的char[10],测试结果仍是变长。
存储的格式为UTF-8。
通过
QTextCodec *codec = QTextCodec::codecForName(“IOS 8859-1”);
QTextCodec::setCodecForLocale(codec);
也无效果
2)数值
整数类型为 integer
其值至少包含了-99999999~9999999999
足够仪表的使用.其它类型在QSQLITE中没有效果,另外直接输入12.3254,也正确。这令人不解,那要real干麻。
浮点类型为real
15、显示
void queryDisplayAll(QSqlDatabase &db)
{
QSqlQuery query(db);
query.exec(“select * from student”);
QSqlRecord rec =query.record();
qDebug()<< QObject::tr("student表字段数: “)< while(query.next())
{
for(int index = 0;index<3;index++)
{
qDebug()< }
qDebug() <<”\n”;
}

}
query.value(index)中index表示第几列内容
内容可以转换为指令格式,如query.value(*).toFloat(),toInt(),toString()等,最后放入显示控件。
16、QSqlQuery query问题
1)推荐作法QSqlQuery query(QSqlDatabase db);
2)也能运行的作法:
QSqlDatabase db = QSqlDatabase::addDatabase(“QSQLITE”);
db.setDatabaseName(QApplication::applicationDirPath()+"/D38Weight.dat");
db.setUserName(“guojintao”);
db.setPassword(“123456”);
qDebug()< if(!db.open())//

之后
QSqlQuery query;
17、删除表
query.exec(“drop table student”);

18、数据库和表的存在问题
1、db.open()时,如果本目录下没有此文件,则会生成文件,否则连接该文件
2、查表是否存在的方法
QSqlQuery query(db);
query.exec(“select * from student”);//此句相当于将表数据导入query中,之后才能操作
QSqlRecord rec =query.record();
qDebug()< if(rec.count()>0)
{
qDebug()<<“exist”;
}
else
{
qDebug()<<“no exist”;
query.exec(“CREATE table student(id int primary key,name char[10],name2 varchar,age integer)”);
}

19、关键工工具QSqlRecord
今后主要用的工具,以上总结已满足当前称重记录的应用,今后再学

20、数据库显示

明天再实验,显示与保存查询结果
https://www.cnblogs.com/lsgxeva/p/7852102.html

21、QSqlTableModel在qt中的使用

基本设置
QSqlDatabase a = QSqlDatabase::addDatabase(“QSQLITE”);
//a.setDatabaseName(“D38Weight.dat”);
a.setDatabaseName(QApplication::applicationDirPath()+"/D38Recorde.db");
if(!a.open())
{
QMessageBox::warning(this,“错误”,a.lastError().text(),QMessageBox::Ok);
return;
}
model = new QSqlTableModel(this);
model->setTable(“WeightRecord”);//指定哪个表
ui->tableView->setModel(model);//指定model
model->setHeaderData(0,Qt::Horizontal,“ID号”);//第0列设置别名
model->setFilter(“time2 =‘20200326183132’”);
model->select();//显示所有列
model->setEditStrategy(QSqlTableModel::OnManualSubmit);//设置手动提交后才可以修改
操作一、过滤器
model->setFilter(“time2 =‘20200326183132’ and Tare = 25000”);
表现“
只显示time2 ='20200326183132’和皮重 = 25000的结果,这个效果同where…。操作上省去简化了很多.
注意事项是,先设置过滤器,再调取并显示所有列model->select();与sql指令相比,像是两行一起执行.

操作二、只显示指定的列内容
比如:D38中有些列是否使用的,那就不要显示出来.
方法一、设置不显示的列的宽度为0
ui->tableView->setColumnWidth(1,0);
优点:保持原数据结构
缺点:用鼠标仍可拉出。且还变不回来。需要考虑设定不准拉动

操作三、为列内容设置别名
model->setHeaderData(0,Qt::Horizontal,“ID号”);//第0列设置别名
操作四、排序
model->setSort(0,Qt::AscendingOrder); //id属性,即第0列,升序排列
model->setSort(0,Qt::DescendingOrder); //id属性,即第0列,降序排
操作五、查扫描到的记录总数
qDebug()<<“记录数:” 操作六、查扫描到的记录表的列数
qDebug()<<“列数:” 操作七、读某一行记录
QSqlRecord record = model->record(2);
qDebug()< 操作八、插入一条新的记录
QSqlRecord record = model->record();

record.setValue("CargoNumber","new");

model->insertRecord(1,record);

问题:在数据库QSqlite、QSqlTableModel、QSqlRecord和QTableView的关系
答:
数据库QSqlite:数据源,我们一般用适应用于嵌入式系统的迷你数据库,其也适用于电脑,但不适用网络共享
QSqlTableModel:直接对接当前所打开的数据库的一个表。
model->setTable(“WeightRecord”);
之后就可能实现QSqlQuery那样对数据库的表进行操作。其大大简化了或增强了对数据库存表的操作。
QSqlRecord:是针对数据库表中记录的操作。读取、修改记录
QtableView:与QSqlTableModel对接。显示QSqlTableModel中的内容.

数据库QSqlite----------》QSqlTableModel QtableView(可显示与编辑)

                  QSqlRecord(对单个记录操作)

操作九:禁止编辑表格
在称重记录查询中,是禁止编辑数据的
设置:
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
操作十:往数据库添加新记录
第一步:得到记录结构
QSqlRecord record = model->record();
第二步:设置一条内容
例 :添加新记录
QSqlRecord record = model->record();
qDebug()< int start = model->rowCount();
int end = start +6;
for(int i = start;i {
QString str = QString(“20200326142%1”).arg(i,3,10,QChar(‘0’));
record.setValue(“time1”,str);
str = QString(“20200327142%1”).arg(i,3,10,QChar(‘0’));
record.setValue(“time2”,str);
str = QString(“浙BR3%1”).arg(i,3,10,QChar(‘0’));
record.setValue(“CarNumber”,str);
str = QString(“苹果%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“CargoNumber”,str);
unsigned char mark = 0x01;
mark = mark<<(i%8);
record.setValue(“State0”,mark);
record.setValue(“Gross”,100000+i);
record.setValue(“Tare”, 15000);
record.setValue(“Net”, 85000+i);
str = QString(“出货厂家%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“chuName”,str);
str = QString(“进货厂家%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“jinName”,str);
str = QString(“运货公司%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“yunName”,str);
record.setValue(“picTime”,i);
record.setValue(“picNum”,8);
str = QString(“司磅员%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“siName”,str);
str = QString(“地磅单位%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“bangName”,str);
record.setValue(“jia”,10.0);
record.setValue(“jin”,1000.0);
record.setValue(“kou”,5.0);
str = QString(“备注1_%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“RemarkNumber1”,str);
str = QString(“备注2_%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“RemarkNumber2”,str);
str = QString(“备注3_%1号”).arg(i,3,10,QChar(‘0’));
record.setValue(“RemarkNumber3”,str);
model->insertRecord(i,record);
}
model->submitAll();
操作十一:删除指定的行
//删除选中的行
int curRow = ui->tableView->currentIndex().row();
model->removeRow(curRow);
model->submitAll();

删除

试验

1、对5000条记录下,写100条记录,并提交,与5条时写100条记录的情况。所写耗时相同。
2、删除一条记录,这条记录不管在何位置,都只需30~40ms
5、读所有记录并显示,所用时间都相同,约8ms

结论

1、D38采用QSqlite管理称重记录内容
2、称重记录内容方面,则只是显示与不显示的问题。所有格式都是相同
3、在Qt平台上,直接采用QSqlTableModel管理数据库,这比原始的数据库管理要方便。
4、称重记录平时只能查看,禁止修改。在特殊权限下,将可修改。此时采用专用 界面
原因是,非故意录错时,需要更改数据,此功能在设计仪表时要考虑。

不错的总结:
1) 常见问题总结
2)应用

//数据库
QSqlDatabase db = QSqlDatabase::addDatabase(“QSQLITE”);
db.setDatabaseName(QApplication::applicationDirPath()+"/D38Data.dat");
if(!db.open()){如果本目录下没有该文件,则会在本目录下生成,否则连接该文件
qDebug()<<“db.open fail!”;
}
else
{
//操作数据库
QSqlQuery query(db);
query.exec(“DROP TABLE students”);

    query.exec("CREATE TABLE students ("
               "id INTEGER PRIMARY KEY AUTOINCREMENT, "
               "name VARCHAR(40) NOT NULL, "
               " score INTEGER NOT NULL, "
               "class VARCHAR(40) NOT NULL)");
    //方法1、一条条写
    query.exec("INSERT INTO students (name, score,class)"
               "VALUES ('小张',85,'01234567890123456789')");
    //方法2、批量写入
    QStringList names;
    names<<"小A"<<"小B"<<"小C"<<"小D"<<"小E"<<"小F"<<"小G"
               <<"小H"<<"小I"<<"小G"<<"小K"<<"小L"<<"小M"<<"小N";

    QStringList clases;
    clases<<"初1-1班"<<"初1-2班"<<"初1-3班"<<"初2-1班"
             <<"初2-2班"<<"初2-3班"<<"初3-1班"<<"初3-2班"<<"初3-3班";
   query.prepare("INSERT INTO students (name, score,class) "
                 "VALUES (:name, :score, :class)");
   foreach(QString name,names)
   {
       query.bindValue(":name",name);
       query.bindValue(":score", (qrand() % 101));      //成绩
       query.bindValue(":class", clases[qrand()%clases.length()] );    //班级
       query.exec();//加入库
   }
   query.exec("UPDATE students set score = '999' where class = '初3-1班'");
   //query.exec ("select * FROM students WHERE score >= 60 AND score <= 80");
   //  query.exec("SELECT * FROM students WHERE class GLOB '*3-2*';");
   //query.exec("SELECT  * FROM students ORDER BY score LIMIT 5 ");
   //query.exec("SELECT * FROM students WHERE id BETWEEN 3 AND 10");
   //query.exec("SELECT * FROM students WHERE class not LIKE '初3%'");
   //query.exec("SELECT id || '(' || class FROM students ");
   //query.exec("SELECT TRIM(id) || '(' || TRIM(class) FROM students ");
   //query.exec("SELECT id,score,id*score AS aa FROM students ");
   //query.exec("SELECT AVG(score),COUNT(score),MAX(id),MIN(id) FROM students ");
   //query.exec("SELECT class,count(*) from students where class GLOB '*3-*' GROUP BY class");
   //query.exec("SELECT class,count(*) from students GROUP BY class HAVING COUNT(*) >=2");
   query.exec("SELECT * FROM students ");
   while(query.next())
   {
       QString id = query.value(0).toString();
       QString name = query.value(1).toString();
       QString score = query.value(2).toString();
       QString classs = query.value(3).toString();

       qDebug()<

试验:
原数据
“1” “浙B3M0” “货物#0号” “1000”
“2” “浙B3M1” “货物#1号” “1010”
“3” “浙B3M2” “货物#2号” “1020”
“4” “浙B3M3” “货物#3号” “1030”
“5” “浙B3M4” “货物#4号” “1040”
“6” “浙B3M5” “货物#5号” “1050”
“7” “浙B3M6” “货物#6号” “1060”
“8” “浙B3M7” “货物#7号” “1070”
“9” “浙B3M8” “货物#8号” “1080”
“10” “浙B3M9” “货物#9号” “1090”
“11” “浙B3M10” “货物#10号” “1100”
“12” “浙B3M11” “货物#11号” “1110”
“13” “浙B3M12” “货物#12号” “1120”
“14” “浙B3M13” “货物#13号” “1130”
“15” “浙B3M14” “货物#14号” “1140”
“16” “浙B3M15” “货物#15号” “1150”
“17” “浙B3M16” “货物#16号” “1160”
“18” “浙B3M17” “货物#17号” “1170”
“19” “浙B3M18” “货物#18号” “1180”
“20” “浙B3M19” “货物#19号” “1190”
“21” “浙B3M20” “货物#20号” “1200”
“22” “浙B3M21” “货物#21号” “1210”
“23” “浙B3M22” “货物#22号” “1220”
“24” “浙B3M23” “货物#23号” “1230”
“25” “浙B3M24” “货物#24号” “1240”
“26” “浙B3M25” “货物#25号” “1250”
“27” “浙B3M26” “货物#26号” “1260”
“28” “浙B3M27” “货物#27号” “1270”
“29” “浙B3M28” “货物#28号” “1280”
“30” “浙B3M29” “货物#29号” “1290”
“31” “浙B3M30” “货物#30号” “1300”
“32” “浙B3M31” “货物#31号” “1310”
“33” “浙B3M32” “货物#32号” “1320”
“34” “浙B3M33” “货物#33号” “1330”
“35” “浙B3M34” “货物#34号” “1340”
“36” “浙B3M35” “货物#35号” “1350”
“37” “浙B3M36” “货物#36号” “1360”
“38” “浙B3M37” “货物#37号” “1370”

试验一、查询一条车号为"浙B3M90"的记录

     query.exec("select * from weightRecord where CarNumber = '浙B3M90'");
     while(query.next())
     {
         qDebug()<

结果:
“91” “浙B3M90” “货物#90号” “1900”
正确

//测试2、取最新记录

    //打印出数据库内所有数据
    query.exec("select  *  from weightRecord  order by id desc LIMIT 1 offset 0;");
    while(query.next())
    {
        qDebug()<

结果:
“100” “浙B3M99” “货物#99号” “1990”

//测试3、取最老记录

    //打印出数据库内所有数据
    query.exec("select  *  from weightRecord  order by id LIMIT 1 offset 0;");
    while(query.next())
    {
        qDebug()<

结果:
“1” “浙B3M0” “货物#0号” “1000”
耗时:0ms

//测试4、id号为关键字,增加记录时会自动 增1,若将最新记录删除如id = 100,同增加1个新的记录,此时id号为多少。

  测试结果:id = 101中间没有了id = 100号记录

//测试5、接测试4的问题,能否直接改id

    query.prepare("INSERT INTO weightRecord (id,CarNumber,CargoNumber,Gross,Tare,Net,date1,time1) "
                  "VALUES (:id,:CarNumber, :CargoNumber, :Gross, :Tare, :Net, :date1, :time1)");
          query.bindValue(":id",102);
         query.bindValue(":CarNumber",carId);
         query.bindValue(":CargoNumber",CargoNumber);
         query.bindValue(":Gross",Gross);
         query.bindValue(":Tare",Tare);
         query.bindValue(":Net",Net);
         query.bindValue(":date1",date1);
         query.bindValue(":time1",time1);
         query.exec();
         测试结果:若人为设定id,则id将不自动+1.而直接用设定的id

测试6、接测试5的问题,若之后用新增不指定id的记录,新id会是什么

   原:"101" "浙B3Mq0" "货物#0号" "1000"
          "103" "浙B3Mq0" "货物#0号" "1000"
          "104" "浙B3Mq0" "货物#0号" "1000"
    经过测试5后,再加1条不指定id的记录
    "101" "浙B3Mq0" "货物#0号" "1000"
   "103" "浙B3Mq0" "货物#0号" "1000"
 "104" "浙B3Mq0" "货物#0号" "1000" 

“105” “浙B3Mq0” “货物#0号” “1000”
测试结果: 数据库会自动记录id 号。当人员设定id小于记录的id,

测试7 按日期查询

    query.exec("select  *  from weightRecord where date1 >'2021-01-10' and date1 <'2021-01-13' order by id desc;");
    while(query.next())
    {
        qDebug()<

“98” “浙B3M97” “货物#97号” “1970” “2021-01-11” “12:03:37”
“70” “浙B3M69” “货物#69号” “1690” “2021-01-12” “12:03:09”
“69” “浙B3M68” “货物#68号” “1680” “2021-01-11” “12:03:08”
“41” “浙B3M40” “货物#40号” “1400” “2021-01-12” “12:03:40”
“40” “浙B3M39” “货物#39号” “1390” “2021-01-11” “12:03:39”
“12” “浙B3M11” “货物#11号” “1110” “2021-01-12” “12:03:11”
“11” “浙B3M10” “货物#10号” “1100” “2021-01-11” “12:03:10”
“耗时: 1 ms”
测试结果:对于数据类型为Date的录入数据“2021-01-11” ,如 QString(“2021-01-%1”).arg((i%29)+1,2,10,QLatin1Char(‘0’));

测试8 按日期查询,并以时间按小到大排序

query.exec(“select * from weightRecord where date1 >‘2021-01-10’ and date1 <‘2021-01-13’ order by time1 ;”);
while(query.next())
{
qDebug()< < }

   qDebug()<

“70” “浙B3M69” “货物#69号” “1690” “2021-01-12” “12:03:09”
“11” “浙B3M10” “货物#10号” “1100” “2021-01-11” “12:03:10”
“12” “浙B3M11” “货物#11号” “1110” “2021-01-12” “12:03:11”
“98” “浙B3M97” “货物#97号” “1970” “2021-01-11” “12:03:37”
“99” “浙B3M98” “货物#98号” “1980” “2021-01-12” “12:03:38”
“40” “浙B3M39” “货物#39号” “1390” “2021-01-11” “12:03:39”
“41” “浙B3M40” “货物#40号” “1400” “2021-01-12” “12:03:40”
“耗时: 1 ms”
测试结果:数据格式为 TIME 数据库支持排序

//测试8 搜索

     query.exec("select  *  from weightRecord where CarNumber like '浙B3M6%' ;");
     while(query.next())
     {
         qDebug()<

输出:
“7” “浙B3M6” “货物#6号” “1060” “2021-01-07” “12:03:06”
“61” “浙B3M60” “货物#60号” “1600” “2021-01-03” “12:03:00”
“62” “浙B3M61” “货物#61号” “1610” “2021-01-04” “12:03:01”
“63” “浙B3M62” “货物#62号” “1620” “2021-01-05” “12:03:02”
“64” “浙B3M63” “货物#63号” “1630” “2021-01-06” “12:03:03”
“65” “浙B3M64” “货物#64号” “1640” “2021-01-07” “12:03:04”
“66” “浙B3M65” “货物#65号” “1650” “2021-01-08” “12:03:05”
“67” “浙B3M66” “货物#66号” “1660” “2021-01-09” “12:03:06”
“68” “浙B3M67” “货物#67号” “1670” “2021-01-10” “12:03:07”
“69” “浙B3M68” “货物#68号” “1680” “2021-01-11” “12:03:08”
“70” “浙B3M69” “货物#69号” “1690” “2021-01-12” “12:03:09”
“耗时: 0 ms”
测试结果:搜索功能正确
同时:
query.exec(“select * from weightRecord where CarNumber like ‘浙B3M_6’ ;”);
将不出现
“7” “浙B3M6” “货物#6号” “1060” “2021-01-07” “12:03:06”
另外也有query.exec(“select * from weightRecord where CarNumber like ‘%B3M6%’ ;”);
注:输入字符串中包含通配符的处理方法
SELECT * FROM t_user t WHERE t.id LIKE ‘%739/%508%’ ESCAPE ‘/’
escape标注后,转义字符后面的_和%就不作为通配符了,而是作为一般字符串进行对待
query.exec(“select * from weightRecord where CarNumber like ‘浙B3M6/%’ escape ‘/’ ;”);

//测试9 autoincrement

当主键 为int时,会自动+1
比如:已有1,2,4,则新记录为5,
当删除4,则变为1,2,则新记录为3
由此可知主键会自动按当前最大的主键值进行+1
如果 主键增加了autoincrement
则主键会一直向上增加,而与当前最大主键值无关。且此主键值无法重置,只能重表来解决
同时官网也不建议使用autoincrement

//测试10 delete 数据库记录时,数 据库空间没有变小。

原因:DELETE只是标记删除,实际并没有删除
处理:调用 DELETE后,再调用 query.prepare(“VACUUM”);
如下:

 bool ret = false;
    out->ret = 0;
    QSqlQuery query(mp_instance->m_db);
    QString cmd;
        cmd = QString("DELETE from CarNumberInfo ")+in->condition;
    ret = query.exec(cmd);
    //qDebug()<
    if(ret == false)
    {
        out->ret = 0;
    }
    else
    {
        query.prepare("VACUUM");
        if (!query.exec())
        {
            out->ret = 0;
        }
        else
        {
            out->ret = 1;
        }
    }
    return ret;

补充1、 数据库操作

第一步:连接数据库
QSqlDatabase db1 = QSqlDatabase::addDatabase(“QSQLITE”,“连接名”);如果没有"connection0",如下
QSqlDatabase db1 = QSqlDatabase::addDatabase(“QSQLITE”);则应用中QSqlQuery query_my直接操作这个连接。
注:当需要连接多个数据库文件时,需要不同的连接,此时就需要不同的连接名,如"connection0",“connection0”,
第二步:设置所连接数据库文件信息
db.setHostName(“localhost”); //数据库主机名 //在QSQLITE下省
db.setDatabaseName(“databasex”); //数据库名
db.setUserName(“root”); //数据库用户名//在QSQLITE下省
db.setPassword(“123456”); //数据库密码//在QSQLITE下省
第三步:操作
1、打开文件
bool bisOpenn = db.open(); //打开数据库连接
2、操作
QSqlQuery query_my1(db);
//query_my1.exec(“insert into student values(0, ‘LiMing’)”);
3、关闭文件
db.close(); //释放数据库连接

补充2、同时打开两个数据库的操作

QSqlDatabase db1 = QSqlDatabase::addDatabase(“QSQLITE”,“connection0”);
db1.setDatabaseName(“my.db”);
if (!db1.open()) {
QMessageBox::critical(0, “Cannot open database1”,
“Unable to establish a database connection.”, QMessageBox::Cancel);
}
QSqlQuery query_my(db1);
// 创建登录用户表
//query.exec(“create table user (username varchar primary key, passwd varchar)”);
// db1.close();
query_my.exec(“insert into user values(‘admin’, ‘root’)”);
//db1.open();

   QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE","connection1");
   db2.setDatabaseName("my1.db");
      if (!db2.open()) {
          QMessageBox::critical(0, "Cannot open database1",
                                "Unable to establish a database connection.", QMessageBox::Cancel);
      }

      // 这里要指定连接
      QSqlQuery query_my1(db2);

// query1.exec("create table student (id int primary key, "
// “name varchar(20))”);
query_my1.exec(“insert into student values(0, ‘LiMing’)”);
query_my1.exec(“insert into student values(1, ‘LiuTao’)”);
query_my1.exec(“insert into student values(2, ‘WangHong’)”);

      query_my.exec("insert into user values('admin2', 'root2')");

      query_my1.exec("insert into student values(3, 'WangHong3')");

你可能感兴趣的:(Qt应用,数据库,qt,sqlite)