当前位置: 首页 > news >正文

网站的地图要怎么做用什么软件做网站设计

网站的地图要怎么做,用什么软件做网站设计,共振设计公司官网,北京发布重磅消息前言 之前没怎么在项目中使用数据库#xff0c;对数据库这块只了解一点皮毛#xff0c;只能说能用。这次涉及了在多线程中使用数据库#xff0c;看了看源码#xff0c;和吸取了网上的一些经验#xff0c;整理封装了一下。 环境 Qt5.15.2 QSqlDatabase原理 因为不太懂数…前言 之前没怎么在项目中使用数据库对数据库这块只了解一点皮毛只能说能用。这次涉及了在多线程中使用数据库看了看源码和吸取了网上的一些经验整理封装了一下。 环境 Qt5.15.2 QSqlDatabase原理 因为不太懂数据库连接的使用就看了源码Qt5.15.2版本源码只是简单的看了一下了解到数据库连接是保存在一个容器中可以称之为数据库连接池它负责分配、管理和释放连接。这样的话就可以重复使用数据库连接而不需每次创建新的连接。 创建连接 创建连接源码如下QConnectionDict 为所说的连接池在添加连接之前使用了锁QWriteLocker locker(dict-lock);所以它是线程安全的。若是连接名重复会先移除之前的连接再添加新的连接。 QSqlDatabase QSqlDatabase::addDatabase(const QString type, const QString connectionName) {QSqlDatabase db(type);QSqlDatabasePrivate::addDatabase(db, connectionName);return db; }void QSqlDatabasePrivate::addDatabase(const QSqlDatabase db, const QString name) {QConnectionDict *dict dbDict();Q_ASSERT(dict);QWriteLocker locker(dict-lock);if (dict-contains(name)) {invalidateDb(dict-take(name), name);qWarning(QSqlDatabasePrivate::addDatabase: duplicate connection name %s, old connection removed., name.toLocal8Bit().data());}dict-insert(name, db);db.d-connName name; } 获取数据库连接 根据连接名获取之前创建的数据库连接默认打开数据库连接。还可以看到里面有判断之前创建的数据库实例的线程是否为当前线程如果不是就返回了空的数据库实例也就是说创建的数据库实例只能在本线程内使用。 我在网上的博客  https://www.cnblogs.com/findumars/p/5634462.html 看到说 “一个线程创建的数据库对象如 addDatabase 的返回值只能在同一线程使用但是addDatabase 注册的连接名字是开发者定可以跨线程使用唯一需要注意的是在调用全局方法的时候要有原子保护。” 我理解的意思是可以在其他线程中通过连接名获取此连接也就是使用database但是源码也看到了连接名是跟addDatabase返回的db数据库对象成对存在连接池中的所以就不存在“连接本身用名字可以多线程使用”。 所以在多线程中使用数据库时候应该保持每个线程都使用一次addDatabase创建连接创建后可在当前线程中使用database(connectionName)获取连接使用数据库。 QSqlDatabase QSqlDatabase::database(const QString connectionName, bool open) {return QSqlDatabasePrivate::database(connectionName, open); }QSqlDatabase QSqlDatabasePrivate::database(const QString name, bool open) {const QConnectionDict *dict dbDict();Q_ASSERT(dict);dict-lock.lockForRead();QSqlDatabase db dict-value(name);dict-lock.unlock();if (!db.isValid())return db;if (db.driver()-thread() ! QThread::currentThread()) {qWarning(QSqlDatabasePrivate::database: requested database does not belong to the calling thread.);return QSqlDatabase();}if (open !db.isOpen()) {if (!db.open())qWarning() QSqlDatabasePrivate::database: unable to open database: db.lastError().text();}return db; } 移除连接 移除连接只要连接池中有此连接名就会移除连接。如果有其他地方还在使用只会警告此连接该失效还是会失效。 void QSqlDatabase::removeDatabase(const QString connectionName) {QSqlDatabasePrivate::removeDatabase(connectionName); }void QSqlDatabasePrivate::removeDatabase(const QString name) {QConnectionDict *dict dbDict();Q_ASSERT(dict);QWriteLocker locker(dict-lock);if (!dict-contains(name))return;invalidateDb(dict-take(name), name); } void QSqlDatabasePrivate::invalidateDb(const QSqlDatabase db, const QString name, bool doWarn) {if (db.d-ref.loadRelaxed() ! 1 doWarn) {qWarning(QSqlDatabasePrivate::removeDatabase: connection %s is still in use, all queries will cease to work., name.toLocal8Bit().constData());db.d-disable();db.d-connName.clear();} } 有时候数据库的对象和移除数据库连接在同一个函数内就会有此警告如果不想打印此警告可将数据库的对象用大括号括起来 将 void test() {QSqlDatabase db QSqlDatabase::addDatabase(QSQLITE,QString(Two));db.open();db.close();QSqlDatabase::removeDatabase(QString(Two)); } 改为 void test() {{QSqlDatabase db QSqlDatabase::addDatabase(QSQLITE,QString(Two));db.open();db.close();}QSqlDatabase::removeDatabase(QString(Two)); } 注意事项 在多线程中操作数据库前需要注意以下几点 QSqlDatabase对象和QSqlQuery 对象只能在创建所在线程内使用。连接使用完后记得删除QSqlDatabase::removeDatabase。 关于资源竞争问题的异常 在网上查资料时看到“线程内注册与连接数据库的存在竞争问题Qt 会动态的加载数据库的plugin, 加载 plug in 的部分涉及到对本地库文件的管理这一部分出现了竞争从 addDatabase / database到 open 的部分要保证其原子性”。 我看了源码只有在初始化时而且仅限addDatabse第一个参数为数据库驱动类型时使用了插件加载数据库驱动。 本想复现所说的资源竞争的问题写了一个Demo两个线程内同时执行了数百次addDatabase、open、removeDatabase操作未加锁也没出现异常。 但是害怕在此出问题所以在后续封装时还是加了锁。 QSqlDatabase QSqlDatabase::addDatabase(const QString type, const QString connectionName) {QSqlDatabase db(type);QSqlDatabasePrivate::addDatabase(db, connectionName);return db; }QSqlDatabase::QSqlDatabase(const QString type) {d new QSqlDatabasePrivate(this);d-init(type); }void QSqlDatabasePrivate::init(const QString type) {drvName type;if (!driver) {DriverDict dict QSqlDatabasePrivate::driverDict();for (DriverDict::const_iterator it dict.constBegin();it ! dict.constEnd() !driver; it) {if (type it.key()) {driver ((QSqlDriverCreatorBase*)(*it))-createObject();}}}if (!driver loader())driver qLoadPluginQSqlDriver, QSqlDriverPlugin(loader(), type);if (!driver) {qWarning(QSqlDatabase: %s driver not loaded, type.toLatin1().data());qWarning(QSqlDatabase: available drivers: %s,QSqlDatabase::drivers().join(QLatin1Char( )).toLatin1().data());if (QCoreApplication::instance() nullptr)qWarning(QSqlDatabase: an instance of QCoreApplication is required for loading driver plugins);driver shared_null()-driver;} } 封装 根据QSqlDatabase的一些特性封装了一个单例模式的数据库管理类 由于创建的连接只能在本线程内使用所以每个线程都会创建一个连接根据连接名跟数据库连接一一对应的关系并且线程ID的唯一性将线程ID作为连接名。考虑到后续释放内存移除数据库连接用容器保存数据。 .h文件 class SQLiteHelper {public:static SQLiteHelper* GetInstance();/*** brief removeDatabases 释放内存*/static void removeDatabases();private:SQLiteHelper();~ SQLiteHelper();public:/*** brief insertTableData 表格内插入数据* param tableName 表名* param rowData 需要插入的一行数据* param id 返回的自增的ID值* return*/bool insertTableData(const QString tableName,const QVariantMap rowData ,int id);...private:static QMutex mutexSql;QString m_strConnName;static QHashQt::HANDLE, SQLiteHelper* databaseMap;//所有数据库链接,key: 线程ID //value 数据库操作实例指针} .cpp文件 QMutex SQLiteHelper::mutexSql; QHashQt::HANDLE, SQLiteHelper* SQLiteHelper::databaseMap;SQLiteHelper *SQLiteHelper::GetInstance() {if(!databaseMap.contains(QThread::currentThreadId())) {databaseMap.insert(QThread::currentThreadId(), new SQLiteHelper());}return databaseMap[QThread::currentThreadId()]; }void SQLiteHelper::removeDatabases() {qDebug()SQLiteHelper::removeDatabases();QListQt::HANDLE keys databaseMap.keys();for(int i 0; ikeys.count();i){Qt::HANDLE id keys[i];//释放内存delete databaseMap.take(id);QSqlDatabase::removeDatabase(QString::number(long(id)));} }SQLiteHelper::SQLiteHelper() {mutexSql.lock();m_strConnName QString::number((long)QThread::currentThreadId());QSqlDatabase database QSqlDatabase::addDatabase(QSQLITE, m_strConnName);database.setDatabaseName(car.db);mutexSql.unlock(); }SQLiteHelper::~SQLiteHelper() { }bool SQLiteHelper::insertTableData(const QString tableName, const QVariantMap rowData,int id) {bool r false;QString fieldNames,placeholderVals;QStringList strList rowData.keys();for(int i 0; i strList.count(); i){const QString name strList[i];fieldNames.append(name);placeholderVals.append(QStringLiteral(:%1).arg(name));if(i ! (strList.count()-1)){fieldNames.append(,);placeholderVals.append(,);}}QString sqlStr QString(INSERT INTO %1 (%2) VALUES (%3);).arg(tableName,fieldNames,placeholderVals);QSqlDatabase sqlDb QSqlDatabase::database(m_strConnName);if(!sqlDb.isOpen()){mutexSql.lock();sqlDb.open();mutexSql.unlock();}QSqlQuery sqlQuery(sqlDb);sqlQuery.prepare(sqlStr);QMapQString,QVariant::const_iterator it rowData.constBegin();for(; it ! rowData.constEnd(); it){sqlQuery.bindValue(QString(:%1).arg(it.key()),it.value());}r sqlQuery.exec();if(r){sqlStr QString(select last_insert_rowid() from %1).arg(tableName);if(sqlQuery.exec(sqlStr)){if(sqlQuery.next()){id sqlQuery.value(0).toInt();}}}sqlDb.close();return r; }... 使用 数据库添加一行数据示例 QVariantMap varMap;varMap.insert(xm,QStringLiteral(张晓明));varMap.insert(xb,QStringLiteral(男));varMap.insert(sfzh,QStringLiteral(123123));SQLiteHelper* sqlHelper SQLiteHelper::GetInstance();for(int i 0; i size; i){int id -1;sqlHelper-insertTableData(studentInfo,varMap,id);qDebug()id;} 在不再使用数据库时释放内存移除连接 SQLiteHelper::removeDatabases(); 结束语 根据自己的理解封装的代码后续根据实践再调整。
http://www.zqtcl.cn/news/600957/

相关文章:

  • 婚纱摄影网站模板之家专业seo网站优化公司
  • 商丘市住房和城乡建设局网站广西网站建设timkee
  • php网站开发是做什么的网站策划总结
  • 站长工具seo推广秒收录WordPress注册插件中文
  • 目前个人网站做地最好是哪几家做汽配网站需要多少钱
  • php做网站多少钱网络营销推广方案3篇
  • 浙江坤宇建设有限公司 网站省直部门门户网站建设
  • 直播类网站怎么做上海市建设质量协会网站
  • 筑巢做网站怎么样网站设计接单
  • 会ps的如何做网站wordpress 仿虎嗅
  • 免费响应式网站建设嘉兴建企业网站
  • 织梦网站首页幻灯片不显示建设银行网站特色
  • php企业网站开发东莞网站建设时间
  • 仿win8网站模板网站开发接私活的经理
  • 仿牌网站 域名注册衡水安徽网站建设
  • 合肥义城建设集团有限公司网站专业建站公司电话咨询
  • 国外平面设计网站有哪些建商城网站公司
  • 深圳做响应式网站网站建设公司行业现状
  • 网站部署城阳网站开发公司
  • 旅游网站的网页设计素材如何网络推广运营
  • 惠州网站建设多少钱注册邮箱
  • 视频制作网站都有哪些网站优化的公司
  • 网站开发运营推广叫什么苏州seo关键词优化推广
  • 龙泉驿区建设局网站引流推广平台软件
  • 做盗版网站韩国服装网站建设
  • 网站策划书籍推荐高端网站设计制作的
  • 优秀电商设计网站有哪些微博网站可以做兼职吗
  • 网站建设 验证码电子商务网站建设流程图
  • 做内贸什么网站资源比较多岳阳网上房地产
  • 去国外网站开发客户中的contact us 没有邮箱失败营销案例100例