QxORM在Win7下的測試


  最近在用MySQL數據庫,QT提供了訪問MySQL數據庫的插件,但每次創建新表都要編寫訪問數據庫的SQL語句,覺得很麻煩。前幾天無意中發現了ORM開發方法。於是就想自己測試一下。沒想到只是讓QxORM中的Quick Sample例子運行起來,都用了差不多一個星期,當然其中也學到了很多東西。

  對象關系映射(Object Relation Mapping,簡稱ORM),ORM簡化了數據庫查詢過程,通過ORM持久層,用戶不需要知道數據庫的具體結構,就可以訪問數據庫。

由於我最近在使用QT,所以選了QxORM這個ORM產品。由於QxORM使用到了boost這個准C++庫,所以編譯QxORM之前要先安裝boost。

1 測試環境

  操作系統:win7

  開發平台:Qt

2 boost的下載和編譯

2.1 boost的下載

  我開始選擇了最新版boost_1_54_0,但在編譯QxORM時出現了一系列的錯誤,后來為了排除錯誤就改為QxOrm 1.2.5使用的默認版本boost_1_42_0。Boost很多功能不用編譯就可以直接使用,簡單的測試如下。 

#include <boost/timer.hpp>

#include <QDebug>

int main(int argc, char *argv[])

{

  QApplication a(argc, argv);

  MainWindow w;

  w.show();

    boost::timer tmr;

  qDebug() << tmr.elapsed() << "S" << endl;

  return a.exec();

}

 

當然不要忘了在QT的pro工程文件中添加boost源碼的路徑。

2.2 boost的編譯

  QxORM使用到了boost的serialization庫,則需要單獨編譯該庫。首先運行boost-1_42_0目錄下的bootstrap.bat文件生成bjam.exe ,如果生成失敗則可能是找不到C++編譯器,我是直接裝了VS2010(不知道gcc可不可以,沒測過)編譯命令為:

>bjam --with-serialization runtime-link=shared link=shared

   但是默認情況下是使用VS的編譯器,使用QtCreator+MinGW不能使用該編譯器編譯出來的庫,所以我們要指定編譯器,上面的命令改為:

>bjam toolset=gcc --with-serialization runtime-link=shared link=shared

  其中link=shared link=shared表示生成動態運行庫、動態鏈接庫,在這里需要生成動態庫,因為QxORM的例子是使用動態鏈接庫,如果對靜態鏈接感興趣,則另外研究。

  編譯成功后會在stage/lib下生成很多lib,其中就有release版本的boost_serialization-mgw44-mt-1_42.dll、boost_serialization-mgw44-mt-1_42.lib以及debug版本的boost_serialization-mgw44-mt-d-1_42.dll、boost_serialization-mgw44-mt-d-1_42.lib。簡單測試如下:

#include <boost/archive/text_oarchive.hpp>

#include <iostream>

#include <fstream>

void save(){

  std::ofstream file("archive.txt");

  boost::archive::text_oarchive oa(file);

  std::string s = "Hello World!\n";

  oa << s;

}

int main(int argc, char *argv[]){

    QApplication a(argc, argv);

    MainWindow w;

    w.show();

  save();
  
  return a.exec();
}

  在QT的pro工程文件中添加boost源碼的路徑以及boost_serialization-mgw44-mt-1_42.庫,具體添加方法可以參考下面的例子。 

3 QxORM的下載和編譯

  下載QxOrm 1.2.5,用Qt creatorn 打開QxORM根目錄的工程,修改該工程里面的QxOrm.pri配置文件。

isEmpty(QX_BOOST_INCLUDE_PATH) { QX_BOOST_INCLUDE_PATH = $$quote(D:/Dvlp/_Libs/Boost/1_42/include) }

isEmpty(QX_BOOST_LIB_PATH) { QX_BOOST_LIB_PATH = $$quote(D:/Dvlp/_Libs/Boost/1_42/lib_shared) }

isEmpty(QX_BOOST_LIB_SERIALIZATION_DEBUG) { QX_BOOST_LIB_SERIALIZATION_DEBUG = "boost_serialization-vc90-mt-gd-1_42" }

isEmpty(QX_BOOST_LIB_SERIALIZATION_RELEASE) { QX_BOOST_LIB_SERIALIZATION_RELEASE = "boost_serialization-vc90-mt-1_42" }

修改為:

isEmpty(QX_BOOST_INCLUDE_PATH) { QX_BOOST_INCLUDE_PATH = $$quote(D:/boost_1_42_0) }

isEmpty(QX_BOOST_LIB_PATH) { QX_BOOST_LIB_PATH = $$quote(D:/boost_1_42_0/stage/lib) }

isEmpty(QX_BOOST_LIB_SERIALIZATION_DEBUG) { QX_BOOST_LIB_SERIALIZATION_DEBUG = "boost_serialization-mgw44-mt-d-1_42" }

isEmpty(QX_BOOST_LIB_SERIALIZATION_RELEASE) { QX_BOOST_LIB_SERIALIZATION_RELEASE = "boost_serialization-mgw44-mt-1_42" }

  當然要根據自己實際的路徑配置,這里只是給出一個例子。

  分別編譯release和debug兩個版本,把生成的libQxOrm.a,QxOrm.dll(release版本)libQxOrmd.a,QxOrmd.dll(debug版本)四個文件拷貝到QxORM根目錄的lib文件夾下。

4 QxORM的Quick Sample測試 

  新建Qt工程QxORMQuickSample,在該工程下新建文件夾QxORM,在QxORM文件夾下新建drug.h,drug.cpp,export.h,precomplied.h四個文件。

* -----------------------------------------------------------------------------------------------------

* 1- drug.h file : drug class definition with 3 properties : id, name and description

* -----------------------------------------------------------------------------------------------------

#ifndef _CLASS_DRUG_H_

#define _CLASS_DRUG_H_

class drug

{

public:

   long id;

   QString name;

   QString description;

   drug() : id(0) { ; }

   virtual ~drug() { ; }

};

QX_REGISTER_HPP_MY_TEST_EXE(drug, qx::trait::no_base_class_defined, 1)

/* This macro is necessary to register 'drug' class in QxOrm context */

/* param 1 : the current class to register => 'drug' */

/* param 2 : the base class, if no base class, use the qx trait => 'qx::trait::no_base_class_defined' */

/* param 3 : the class version used by serialization to provide 'ascendant compatibility' */

#endif // _CLASS_DRUG_H_ 

* ----------------------------------------------------------------------------------------------------

* 2- drug.cpp file : 'setting function' implementation : void qx::register_class()

* ---------------------------------------------------------------------------------------------------- 

#include "precompiled.h"   // Precompiled-header with '#include <QxOrm.h>' and '#include "export.h"'

#include "drug.h"          // Class definition 'drug'

#include <QxMemLeak.h>     // Automatic memory leak detection



QX_REGISTER_CPP_MY_TEST_EXE(drug)   // This macro is necessary to register 'drug' class in QxOrm context

namespace qx {

template <> void register_class(QxClass<drug> & t)

{

  t.id(& drug::id, "id");               // Register 'drug::id' <=> primary key in your database

  t.data(& drug::name, "name", 1);      // Register 'drug::name' property with key 'name' and version '1'

  t.data(& drug::description, "desc");  // Register 'drug::description' property with key 'desc'

}}

 

* ----------------------------------------------------------------------------------------------------

* 3- export.h file 

* ---------------------------------------------------------------------------------------------------- 

#ifndef _QX_QUICK_SAMPLE_EXPORT_H_

#define _QX_QUICK_SAMPLE_EXPORT_H_

 

#define QX_REGISTER_HPP_MY_TEST_EXE         QX_REGISTER_HPP_EXPORT_DLL

#define QX_REGISTER_CPP_MY_TEST_EXE             QX_REGISTER_CPP_EXPORT_DLL

#endif 

 

* ----------------------------------------------------------------------------------------------------

* 4- precomplied.h file 

* ---------------------------------------------------------------------------------------------------- 

#ifndef _QX_PRECOMPILED_HEADER_H_

#define _QX_PRECOMPILED_HEADER_H_

#include <QxOrm.h>

#include "export.h"

#endif

 

* -----------------------------------------------------------------------------------------------

* 5- main.cpp file : basic functionalities of QxOrm library with drug class

* ----------------------------------------------------------------------------------------------- 

#include "QxORM/precompiled.h"

#include "QxORM/drug.h"

#include <QxMemLeak.h>

int main(int argc, char * argv[])

{

   QApplication app(argc, argv); // Qt application



   // Create 3 new drugs

   // It is possible to use 'boost' and 'Qt' smart pointer : 'boost::shared_ptr', 'QSharedPointer', etc...

   typedef boost::shared_ptr<drug> drug_ptr;

   drug_ptr d1; d1.reset(new drug()); d1->name = "name1"; d1->description = "desc1";

   drug_ptr d2; d2.reset(new drug()); d2->name = "name2"; d2->description = "desc2";

   drug_ptr d3; d3.reset(new drug()); d3->name = "name3"; d3->description = "desc3";

 
   // Insert drugs into container

   // It is possible to use a lot of containers from 'std', 'boost', 'Qt' and 'qx::QxCollection<Key, Value>'

   typedef std::vector<drug_ptr> type_lst_drug;

   type_lst_drug lst_drug;

   lst_drug.push_back(d1);

   lst_drug.push_back(d2);

   lst_drug.push_back(d3);

 
   // Init parameters to communicate with a database

   qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE");

   qx::QxSqlDatabase::getSingleton()->setDatabaseName("./test_qxorm.db");

   qx::QxSqlDatabase::getSingleton()->setHostName("localhost");

   qx::QxSqlDatabase::getSingleton()->setUserName("root");

   qx::QxSqlDatabase::getSingleton()->setPassword("");


   // Create table 'drug' into database to store drugs

   QSqlError daoError = qx::dao::create_table<drug>();

 
   // Insert drugs from container to database

   // 'id' property of 'd1', 'd2' and 'd3' are auto-updated

   daoError = qx::dao::insert(lst_drug);


   // Modify and update the second drug into database

   d2->name = "name2 modified";

   d2->description = "desc2 modified";

   daoError = qx::dao::update(d2);

 
   // Delete the first drug from database

   daoError = qx::dao::delete_by_id(d1);

 
   // Count drugs into database

   long lDrugCount = qx::dao::count<drug>();


   // Fetch drug with id '3' into a new variable

   drug_ptr d_tmp; d_tmp.reset(new drug());

   d_tmp->id = 3;

   daoError = qx::dao::fetch_by_id(d_tmp);

   // Export drugs from container to a file under xml format (serialization)

   qx::serialization::xml::to_file(lst_drug, "./export_drugs.xml");

 
   // Import drugs from xml file into a new container

   type_lst_drug lst_drug_tmp;

   qx::serialization::xml::from_file(lst_drug_tmp, "./export_drugs.xml");

 
   // Clone a drug

   drug_ptr d_clone = qx::clone(* d1);
 

   // Create a new drug by class name (factory)

   boost::any d_any = qx::create("drug");

 
   // Insert drugs container into 'qx::cache'

   qx::cache::set("drugs", lst_drug);

 
   // Remove all elements from 'qx::cache'

   qx::cache::clear();


   // Create a dummy memory leak

   drug * pDummy = new drug();

 
   return 0;
}

* -----------------------------------------------------------------------------------------------

* 6- QxORMQuickSample.pro file : 項目配置文件

* ----------------------------------------------------------------------------------------------- 

include(./QxOrm.pri)

###############################

# QXORM Library Configuration #

###############################

isEmpty(QXORM_INCLUDE_PATH) { QXORM_INCLUDE_PATH = $$quote(D:/QxORM/QxOrm/include) }

isEmpty(QXORM_LIB_PATH) { QXORM_LIB_PATH = $$quote(D:/QxORM/QxOrm/lib) }


QT       += core gui


TARGET = QxORMQuickSample

TEMPLATE = app


INCLUDEPATH += $${QXORM_INCLUDE_PATH}

PRECOMPILED_HEADER = ./QxORM/precompiled.h
 
LIBS += -L$${QXORM_LIB_PATH}


CONFIG(debug, debug|release) {

LIBS += -lQxOrmd

} else {

LIBS += -lQxOrm

} # CONFIG(debug, debug|release)

SOURCES += main.cpp\

        mainwindow.cpp \

    QxORM/drug.cpp

HEADERS  += mainwindow.h \

    QxORM/precompiled.h \

    QxORM/export.h \

    QxORM/drug.h

最后把前面編譯QxOrm時候改好的QxOrm.pri文件拷貝到QxORMQuickSample項目目錄下。

編譯運行后所得結果跟RxORM文檔中的Quick Samples所得的結果相同


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM