在学习QT的过程中,在sqlite数据库中插入中文乱码的问题,用下面方法最简单有效,即QString::fromLocal8Bit,就可以解决现实乱码的问题。
qt fromLocal8Bit()函数可以设置编码。
QT默认的编码是unicode,不能显示中文的
windows默认使用(GBK/GB2312/GB18030)
使用fromLocal8Bit()函数,实现了从本地字符集GB到Unicode的转换,用于处理汉语显示乱码等问题
static inline QString fromLocal8Bit(const QByteArray &str);该函数返回的是String类型的数
query.exec(QString::fromLocal8Bit("insert into automobile values( 2, '四轮','轿车','富康',rand() % 100 ,123,123,123,123,123)"));
75
#include <QtWidgets/QApplication>
2 #include <QtCore>
3 #include <QTextCodec>
4 #include <QSqlDatabase>
5 #include <QMessageBox>
6 #include <QSqlQuery>
7 #include <QTime>
8 #include <QSqlError>
9 #include <QSqlDriver>
10 #include <QSqlRecord>
11 #include <QtDebug>
12
13
14 int main(int argc, char *argv[])
15 {
16 QApplication a(argc, argv);
17
18 QFile::remove("qtDB.db"); //it's very necessary to testing many times!
19
20 QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
21 db.setHostName("easybook-3313b0"); //设置数据库主机名
22 db.setDatabaseName("qtDB.db"); //设置数据库名,setHostName/setDatabaseName/setUserName/setPassword是非必须的
23 //因为在Qt中,由于QSQLITE数据库驱动对应的SQLite数据库是一种进程内的本地数据库,无需数据库名、用户名、密码、主机名和端口等特性
24 db.setUserName("zhouhejun"); //设置数据库用户名
25 db.setPassword("123456"); //设置数据库密码
26 db.open(); //打开连接
27
28 //创建数据库表automobile1------一个数据库中可以创建多个互不重名的数据库表
29 QSqlQuery query1;
30 bool success1 = query1.exec("create table automobile1(id int primary key,attribute varchar(100),type varchar(100),kind varchar(100),nation int,carnumber int,elevaltor int,distance int,oil int,temperature int)");
31
32 if (success1)
33 qDebug() <<"Create automobile1 Successful";
34 else
35 qDebug() <<"Create automobiles1 Fail";
36
37 //创建数据库表automobile
38 QSqlQuery query;
39 bool success = query.exec("create table automobile(id int primary key,attribute varchar(100),type varchar(100),kind varchar(100),nation int,carnumber int,elevaltor int,distance int,oil int,temperature int)");
40
41 if (success)
42 qDebug() << "Create automobile Successful";
43 else
44 qDebug() << "Create automobiles Fail";
45
46 //查询
47 query.exec("select * from automobile");
48 QSqlRecord rec = query.record();
49 qDebug() << "automobile records' num:" << rec.count();
50
51 //插入记录
52 QTime t;
53 t.start();
54
55 //像这种带有string类型的table,进行插入元组时,应带有QString::fromLocal8Bit("insert into...")才能保证正确显示.
56 //元组0中因为没有加QString::fromLocal8Bit(...),所以string类型显示不全或乱码
57 success = query.exec(("insert into automobile values( 0, '四轮','轿车','富康',123,123,123,123,123,123)"));
58 if (!success)
59 {
60 QSqlError lastError = query.lastError();
61 qDebug() << lastError.driverText() << "insert row 0 failed";
62 }
63
64 //元组1中的string类型均可显示成功
65 //值得注意的是,如果直接使用这种query.exec(...)进行插入元组时,里面所有的列元素必须是确定的,可以带有计算,但不能带入函数
66 success = query.exec(QString::fromLocal8Bit("insert into automobile values( 1, '四轮','轿车','富康',(6+6)*12/3,123,123,123,123,123)"));
67 if (!success)
68 {
69 QSqlError lastError = query.lastError();
70 qDebug() << lastError.driverText() << "insert row 1 Failed";
71 }
72
73 //元组2插入失败
74 success = query.exec(QString::fromLocal8Bit("insert into automobile values( 2, '四轮','轿车','富康',rand() % 100 ,123,123,123,123,123)"));
75 if (!success)
76 {
77 QSqlError lastError = query.lastError();
78 qDebug() << lastError.driverText() << "insert row 2 Failed";
79 }
80
81 //如果直接使用这种query.exec(...)进行插入元组时,id/nation等int类型的数据,则必须是具体已确定的数值,而不能用变量进行替代;
82 //元组3插入失败
83 int fourthRowId = 3;
84 success = query.exec(QString::fromLocal8Bit("insert into automobile values(fourthRowId, '四轮','轿车','富康',123,123,123,123,123,123)"));
85 if (!success)
86 {
87 QSqlError lastError = query.lastError();
88 qDebug() << lastError.driverText() << "insert row 3 Failed";
89 }
90
91 //同上,元组4插入失败
92 int thirdRowNation = rand() % 100;
93 success = query.exec(QString::fromLocal8Bit("insert into automobile values( 4, '四轮','轿车','富康',thirdRowNation,123,123,123,123,123)"));
94 if (!success)
95 {
96 QSqlError lastError = query.lastError();
97 qDebug() << lastError.driverText() << "insert row 4 Failed";
98 }
99
100 //另外一种query.exec();可以通过query.prepare()进行预插值,然后通过query.bindValue(...)进行数据绑定,
101 //这种方式更加随性一些,因为插入元组的列元素可以是变量,也可以是符合条件的函数
102 query.prepare(QString::fromLocal8Bit("insert into automobile values(?,?,?,?,?,?,?,?,?,?)"));
103 int records1 = 10;
104 for (int i = 0; i < records1; i++)
105 {
106
107 query.bindValue(0, i+5); ok, 可以正确显示
108 query.bindValue(1, "四轮"); //完全显示不出来
109 query.bindValue(2, QString::fromLocal8Bit("轿车")); //ok,可以正确显示
110 query.bindValue(3, '富康'); //单引号,可以显示,但是显示错误
111 query.bindValue(4, (6+8)*12/4); //显示42,ok,可以正确显示
112 query.bindValue(5, rand() % 10000); //ok, 可以正确显示
113 query.bindValue(6, rand() % 300);
114 query.bindValue(7, rand() % 200000);
115 query.bindValue(8, rand() % 52);
116 query.bindValue(9, rand() % 100);
117
118 success = query.exec();
119 if (!success)
120 {
121 QSqlError lastError = query.lastError();
122 qDebug() << lastError.driverText() << "insert row " << i + 5 << "Failed";
123 }
124 }
125 qDebug() << "first insert " << records1 << " records, time:" << t.elapsed() << " ms";
126
127
128
129
130 //query.prepare(QString::fromLocal8Bit("insert into automobile values(?,?,?,?,?,?,?,?,?,?)"))中的QString::fromLocal8Bit在此没有作用,可以不加
131 query.prepare(("insert into automobile values(?,?,?,?,?,?,?,?,?,?)"));
132
133 long records2 = 10;
134 for (int i = 0; i < records2; i++)
135 {
136
137 query.bindValue(0, i + records1 + 5);
138 query.bindValue(1, QString::fromLocal8Bit("四轮"));
139 query.bindValue(2, QString::fromLocal8Bit("轿车"));
140 query.bindValue(3, QString::fromLocal8Bit("富康")); //结合以上可以看出,在当前环境下,使用字符串显示中文,需在中文字符的外面加上QString::fromLocal8Bit
141 query.bindValue(4, rand() % 100);
142 query.bindValue(5, rand() % 10000);
143 query.bindValue(6, rand() % 300);
144 query.bindValue(7, rand() % 200000);
145 query.bindValue(8, rand() % 52);
146 query.bindValue(9, rand() % 100);
147
148 success = query.exec();
149 if (!success)
150 {
151 QSqlError lastError = query.lastError();
152 qDebug() << lastError.driverText() << "insert row" << i + records1 + 5 << "Failed";
153 }
154 }
155
156 qDebug() << "second insert " << records2 << " records, time:" << t.elapsed() << " ms";
157
158 db.close();
159
160 return a.exec();
161 }