sqlite封装库SmartDB1.3发布

来源:互联网 发布:铜陵网络台视频 编辑:程序博客网 时间:2024/05/19 18:42

最近终于稍微有点空对SmartDB进行升级了,SmartDB1.3比之前的版本做了简化,增强了易用性和灵活性。
  SmartDB对sqlite做了一层封装,屏蔽了诸多细节,使得我们使用起来很方便。在注重易用性的基础上还兼顾了性能和灵活性。

易用性

接口很简单,基本接口有如下几个:

复制代码
void Open(const string& fileName);bool Close();//数据库操作接口template <typename... Args>bool Excecute(const string& sqlStr, Args && ... args);//返回一个值,如执行简单的汇聚函数template < typename R = sqlite_int64, typename... Args>R ExecuteScalar(const string& sqlStr, Args&&... args);//查询接口template <typename... Args>std::shared_ptr<rapidjson::Document> Query(const string& query, Args&&... args);//事务bool Begin();bool RollBack();bool Commit();
复制代码

通过这几个接口,你就可以做所有的事情了。看一个简单的例子吧:

复制代码
void Test(){    SmartDB db;    db.Open("test.db");    const string sqlcreat = "CREATE TABLE if not exists PersonTable(ID INTEGER NOT NULL, Name Text, Address BLOB);";    if (!db.Excecute(sqlcreat))        return;    const string sqlinsert = "INSERT INTO PersonTable(ID, Name, Address) VALUES(?, ?, ?);";    int id = 2;    string name = "Peter";    string city = "zhuhai";    blob bl = { city.c_str(), city.length() + 1 };    if (!db.Excecute(sqlinsert, id, "Peter", nullptr))        return;}
复制代码

上面的例子创建了数据库和数据表,并插入了一行记录,都是通过Excecute搞定,是不是很简单。

灵活性

  对数据库接口做了增强,使我们可以接收tuple和json,因为有时候我们需要将要保存的值先保存起来,在需要的时候再存到数据库,这时就需要一个载体来事先保存这些数据,这里通过json或者tuple是最合适的。来看看tuple和json接口:

template<typename Tuple>bool ExcecuteTuple(const string& sqlStr, Tuple&& t);bool ExcecuteJson(const string& sqlStr, const char* json);

和上面的Excecute很相似吧。看看他们的用法:

db.ExcecuteTuple(sqlinsert, std::forward_as_tuple(id, "Peter", bl));

json接口稍微复杂一点,这里我们用到了rapidjson。它的用法:

复制代码
void TestJson(SmartDB& db, const string& sqlinsert){    rapidjson::StringBuffer buf;    rapidjson::Writer<rapidjson::StringBuffer> writer(buf);    writer.StartArray();    for (size_t i = 0; i < 10; i++)    {        writer.StartObject();        writer.String("ID");        writer.Int(i + 1);        writer.String("Name");        writer.String("Peter");        writer.String("Address");        writer.String("Zhuhai");        writer.EndObject();    }    writer.EndArray();    auto r = db.ExcecuteJson(sqlinsert, buf.GetString());}
复制代码

上面写json对象有点繁琐,没关系,可以通过我封装的JsonCpp来简化:

复制代码
void TestJson(SmartDB& db, const string& sqlinsert){    //这里通过jsoncpp封装类来简化json对象的创建    JsonCpp jcp;    jcp.StartArray();    for (size_t i = 0; i < 10; i++)    {        jcp.StartObject();        jcp.WriteJson("ID", i);        jcp.WriteJson("Name", "Peter");        jcp.WriteJson("Address", "zhuhai");        jcp.EndObject();    }    jcp.EndArray();    auto r = db.ExcecuteJson(sqlinsert, buf.GetString());}
复制代码

灵活性

  将查询结果直接放到json对象中,避免了物理表需要和业务实体一一对应的问题,底层物理表即使修改了,数据库这层不需要修改,是稳定的,因为查询的结果是json对象,它本身就是一个自描述的结构体,不关心底层数据表的变化。返回json的另外一个好处是,我可以将json串通过网络传输出去,或者直接传给其它的语言,因为json是一个标准的格式,所以,不同的语言都能轻松的识别它,它不仅仅是查询的结果还是一个联系其它语言或者系统的纽带,非常灵活。看看它的基本用法:

auto p = db.Query("select * from TestInfoTable");

返回的是一个json对象,要访问它也很简单:

复制代码
rapidjson::Document& doc = *p;    for (size_t i = 0, len = doc.Size(); i < len; i++)    {        for (size_t j = 0, size = doc[i].GetSize(); j < size; ++j)        {            //doc[i][j];键值对        }    }const char* json = doc.GetString(); //返回json串
复制代码

性能

启用事务,插入性能很高,双核笔记本上插入一个七字段的表能达到二十多万行每秒的速度。查询结果的速度也较快,也能达到二十万行每秒的速度。看看性能测试的代码:

复制代码
void TestPerformance(){    SmartDB db;    db.Open("test.db");    const string sqlcreat = "CREATE TABLE if not exists TestInfoTable(ID INTEGER NOT NULL, KPIID INTEGER, CODE INTEGER, V1 INTEGER, V2 INTEGER, V3 REAL, V4 TEXT);";    if (!db.Excecute(sqlcreat))        return;    boost::timer t;    const string sqlinsert = "INSERT INTO TestInfoTable(ID, KPIID, CODE, V1, V2, V3, V4) VALUES(?, ?, ?, ?, ?, ?, ?);";    bool ret = db.Prepare(sqlinsert);    db.Begin();    for (size_t i = 0; i < 1000000; i++)    {        ret = db.ExcecuteArgs(i, i, i, i, i, i + 1.25, "it is a test");        if (!ret)            break;    }    if (ret)        db.Commit(); //提交事务    else        db.RollBack(); //回滚    cout << t.elapsed() << endl;    t.restart();    auto p = db.Query("select * from TestInfoTable");    cout << t.elapsed() << endl;    cout << "size: " << p->Size() << endl;}
复制代码

  双核笔记本上显示:4.6s和5s。这个性能完全满足平时的开发。

如果你发现还有比这更简洁、灵活和高效的sqlite封装库请告诉我,如果没有请点一下推荐,谢谢。^_^

SmartDBV1.03

欢迎使用,如果发现有问题请向我反馈。

c++11 boost技术交流群:296561497,欢迎大家来交流技术。

一点梦想:尽自己一份力,让c++的世界变得更美好!
0 0
原创粉丝点击