一直以來,筆者都在不停尋找一種更人性化的數據庫訪問方式(并不是說默認的方式不好,而是有時候的確在模塊化設計中不太方便)。
后來有幸在php中找到codeigniter的ActiveReord,詳細參考這篇文章: 抽離CodeIgniter的數據庫訪問類!
然而c++卻始終用著最原始的方式,昨天趁著項目要用的機會,在網上搜索了好久,總算讓我找到兩套c++的數據庫訪問框架:
soci
litesql
兩套代碼我都拿下來看了一下,litesql實現了一套完整的代碼自動生成,功能強大,但是也很重;soci相對要輕量,但是同樣也實現了數據結構到數據庫表的映射。本人還是比較喜歡輕量的東西,所以最終選擇了soci。經過這兩天的試用,感覺非常不錯。
官方的文檔也很詳細,所以這里就用我寫的單元測試代碼來做一下簡單的講解:
首先創建庫表:
| create database soci;CREATE TABLE `tb_test` ( `id` int(11) NOT NULL auto_increment, `name` varchar(32) default "", `sex` int(11) default 0, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`)); create database soci;CREATE TABLE `tb_test` ( `id` int(11) NOT NULL auto_increment, `name` varchar(32) default "", `sex` int(11) default 0, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`)); |
1.簡單的select單條記錄
| TEST(soci,select_one){ try { session sql(mysql, "host=localhost db=soci user=dantezhu"); indicator ind; string name = "dandan"; int sex; sql << "select sex from tb_test where name = :name", into(sex, ind), use(name); ASSERT_EQ(ind, i_ok) << name; } catch (exception const &e) { FAIL()<<e.what(); }} TEST(soci,select_one){ try { session sql(mysql, "host=localhost db=soci user=dantezhu"); indicator ind; string name = "dandan"; int sex; sql << "select sex from tb_test where name = :name", into(sex, ind), use(name); ASSERT_EQ(ind, i_ok) << name; } catch (exception const &e) { FAIL()<<e.what(); }} |
select的結果,如果成功則ind會為i_ok,同值sex被賦值;如果失敗則反之
2.簡單的select多條記錄
| TEST(soci,select_multi2){ try { session sql(mysql, "db=soci user=dantezhu"); indicator ind; int count; sql << "select count(*) from tb_test", into(count, ind); ASSERT_EQ(ind, i_ok) << count; if (count == 0) { SUCCEED(); return; } int sex = 1; vector<string> vec_name(count); vector<int> vec_sex(count); sql << "select name,sex from tb_test where sex = :sex", into(vec_name), into(vec_sex), use(sex); } catch (exception const &e) { FAIL()<<e.what(); }} TEST(soci,select_multi2){ try { session sql(mysql, "db=soci user=dantezhu"); indicator ind; int count; sql << "select count(*) from tb_test", into(count, ind); ASSERT_EQ(ind, i_ok) << count; if (count == 0) { SUCCEED(); return; } int sex = 1; vector<string> vec_name(count); vector<int> vec_sex(count); sql << "select name,sex from tb_test where sex = :sex", into(vec_name), into(vec_sex), use(sex); } catch (exception const &e) { FAIL()<<e.what(); }} |