70 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			70 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								## 前言
							 | 
						|||
| 
								 | 
							
								因为Sqlite的源代码中只提供了Sqlite3_key()的接口,没有实现。所以Qt中的Sqlite没有密码功能。于是我找了一下资料,,并且总结一下思路。现成的方法在最后。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## SQLite历代版本与下载
							 | 
						|||
| 
								 | 
							
								所有ReleaseTag:https://www.sqlite.org/cgi/src/taglist
							 | 
						|||
| 
								 | 
							
								SQLite不提供明确的下载地址,所以地址需要开发者去猜……,也就是通过最新的地址以及你所需要的版本号去推:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								例如:
							 | 
						|||
| 
								 | 
							
								- sqlite-amalgamation-3240000:https://www.sqlite.org/2018/sqlite-amalgamation-3240000.zip
							 | 
						|||
| 
								 | 
							
								- sqlite-dll-win32-x86-3240000.zip:https://www.sqlite.org/2018/sqlite-dll-win32-x86-3240000.zip
							 | 
						|||
| 
								 | 
							
								- sqlite-dll-win64-x64-3240000.zip:https://www.sqlite.org/2018/sqlite-dll-win64-x64-3240000.zip
							 | 
						|||
| 
								 | 
							
								- sqlite-amalgamation-3270200.zip:https://www.sqlite.org/2019/sqlite-amalgamation-3270200.zip
							 | 
						|||
| 
								 | 
							
								- sqlite-dll-win64-x64-3270200.zip:https://www.sqlite.org/2019/sqlite-dll-win64-x64-3270200.zip
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								注意:
							 | 
						|||
| 
								 | 
							
								- 年份
							 | 
						|||
| 
								 | 
							
								- 版本号的小数点位在百位上
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 解决思路与大致过程
							 | 
						|||
| 
								 | 
							
								编写一个QSQLDriver Plugins,并且实现Sqlite3_key()。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 大致步骤
							 | 
						|||
| 
								 | 
							
								- 在QtCreator中文件-新建文件或者项目-Library-c++Library来创建QSQLDriver Plugins(库类型选择Qt Plugin)。
							 | 
						|||
| 
								 | 
							
								- 下载Qt源代码,并将\qtbase\src\plugins\sqldrivers\sqlite下的qsql_sqlite_p.h与qsql_sqlite.cpp文件复制到新建的插件目录下。
							 | 
						|||
| 
								 | 
							
								- 修改2个文件中类名与创建插件的类名一致。并且修改open()函数(具体的请看参考资料)。
							 | 
						|||
| 
								 | 
							
								- 下载sqlite源代码,并且实现Sqlite3_key(),注意该函数被宏设置为不编译。可以通过在项目中设置来解决也可以在头文件中直接设置宏为1来解决。
							 | 
						|||
| 
								 | 
							
								- Sqlite3_key()的实现方法可以参考wxsqlite3或CipherSqlite。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 现成的解决方法
							 | 
						|||
| 
								 | 
							
								国人编写的插件:QtCipherSqlitePlugin。经测试5.14.2 MSVC2017  x64可以使用。使用起来很方便,直接用Qt打开sqlitecipher文件夹中的工程,直接切成release模式编译即可。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								作者推荐的方法是将编译出lib与dll都放入源代码中的,不过我个人还是喜欢使用在项目中直接加载Plugin的方式来实现。这样可以方便后续的项目迁移与后续维护。大致代码如下:
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								QPluginLoader driverload(qApp->applicationDirPath()+"/plugin/sqldrivers/sqlitecipher.dll");
							 | 
						|||
| 
								 | 
							
								    if(driverload.load())
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        QSqlDriverPlugin *plugin=qobject_cast<QSqlDriverPlugin*>(driverload.instance());
							 | 
						|||
| 
								 | 
							
								        if(plugin)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            QSqlDriver *driver=plugin->create("SQLITECIPHER");
							 | 
						|||
| 
								 | 
							
								            QSqlDatabase db;
							 | 
						|||
| 
								 | 
							
								                       db=QSqlDatabase::addDatabase(driver);
							 | 
						|||
| 
								 | 
							
								                       db.setDatabaseName("mydatabase.db");
							 | 
						|||
| 
								 | 
							
								                       db.setPassword("123456");
							 | 
						|||
| 
								 | 
							
								                       if(db.open())
							 | 
						|||
| 
								 | 
							
								                       {
							 | 
						|||
| 
								 | 
							
								                           QSqlQuery qry(db);
							 | 
						|||
| 
								 | 
							
								                           qry.exec("create table t_trade(order_id varchar(100))");
							 | 
						|||
| 
								 | 
							
								                           qry.exec("insert into t_trade(order_id) values('10001')");
							 | 
						|||
| 
								 | 
							
								                           qry.exec("insert into t_trade(order_id) values('10002')");
							 | 
						|||
| 
								 | 
							
								                           qry.exec("select * from t_trade");
							 | 
						|||
| 
								 | 
							
								                           while(qry.next())
							 | 
						|||
| 
								 | 
							
								                           {
							 | 
						|||
| 
								 | 
							
								                               qDebug()<<qry.value(0).toString();
							 | 
						|||
| 
								 | 
							
								                           }
							 | 
						|||
| 
								 | 
							
								                       }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								PS.debug与release的dll是不通用的,所以需要编译两份dll,并且载入时进行判断!
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								- QtCipherSqlitePlugin地址:
							 | 
						|||
| 
								 | 
							
								https://github.com/devbean/QtCipherSqlitePlugin
							 | 
						|||
| 
								 | 
							
								- 编译方法:https://github.com/devbean/QtCipherSqlitePlugin/wiki/How-to-compile
							 | 
						|||
| 
								 | 
							
								- 使用方法:https://github.com/devbean/QtCipherSqlitePlugin/wiki/How-to-use
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 参考资料
							 | 
						|||
| 
								 | 
							
								- https://www.devbean.net/2012/07/qt-sqlite-plugin-with-encryption/
							 | 
						|||
| 
								 | 
							
								- https://www.cnblogs.com/WushiShengFei/p/9707244.html
							 |