This article introduces a MySQL access library soci and mysqlsoci for C ++ programs.

Source: Internet
Author: User

This article introduces a MySQL access library soci and mysqlsoci for C ++ programs.

For a long time, I have been constantly looking for a more user-friendly database access method (not to say that the default method is not good, but sometimes it is not very convenient in modular design ).
Later, I was lucky enough to find the ActiveReord of codeigniter in php. For details, refer to this article: getting away from CodeIgniter's database category class!
However, c ++ has always been using the most primitive method. Yesterday, taking advantage of the project's opportunities, I searched the internet for a long time and finally found two c ++ database access frameworks:

Soci
Litesql

Let me take a look at both sets of code. litesql implements a complete set of code automatically generated, which is powerful, but also very heavy; soci is relatively lightweight, however, the ing between data structures and database tables is also realized. I still like simple things, so I finally chose soci. After the two-day trial, I feel very good.

The official documentation is also very detailed, so here I will use the unit test code to give a simple explanation:
First, create a database table:

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. Simple select single record

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();  }}

If the select result is successful, ind will be I _ OK, and the same value of sex will be assigned; otherwise

2. Simple select multiple records

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();  }}

The only difference from a single select record is that the into () parameter is a vector. In fact, using multiple vectors is not a good choice. We will introduce the data structure-based method later.

3. Simple insert

TEST(soci,insert_exist){  try  {    session sql(mysql, "db=soci user=dantezhu");    string name = "dandan";    int sex = 1;    sql << "insert into tb_test(name, sex) values(:name, :sex)",      use(name), use(sex);  }  catch (exception const &e)  {    SUCCEED()<<e.what();  }} TEST(soci,insert_exist){  try  {    session sql(mysql, "db=soci user=dantezhu");     string name = "dandan";    int sex = 1;     sql << "insert into tb_test(name, sex) values(:name, :sex)",      use(name), use(sex);  }  catch (exception const &e)  {    SUCCEED()<<e.what();  }}

Insert, update, and delete both have the same problem:
A) affect_rows (number of rows in the operation) cannot be returned
B) The operation id cannot be known, especially when the insert primary key is auto-incrementing, the value of the inserted primary key cannot be known.

The update and delete operations are similar to insert operations.

Next is an important feature of this framework, that is, binding database tables to data structures:

First, we need to define a struct and tell soci how to match the column name with the data structure field:

struct Person{  int id;  std::string name;  int sex;};namespace soci{  template<> struct type_conversion<Person>  {    typedef values base_type;    static void from_base(values const & v, indicator /* ind */, Person & p)    {      p.id = v.get<int>("id");      p.name = v.get<std::string>("name");      p.sex = v.get<int>("sex");    }    static void to_base(const Person & p, values & v, indicator & ind)    {      v.set("id", p.id);      v.set("name", p.name);      v.set("sex", p.sex);      ind = i_ok;    }  };} struct Person{  int id;  std::string name;  int sex;}; namespace soci{  template<> struct type_conversion<Person>  {    typedef values base_type;    static void from_base(values const & v, indicator /* ind */, Person & p)    {      p.id = v.get<int>("id");      p.name = v.get<std::string>("name");      p.sex = v.get<int>("sex");    }    static void to_base(const Person & p, values & v, indicator & ind)    {      v.set("id", p.id);      v.set("name", p.name);      v.set("sex", p.sex);      ind = i_ok;    }  };}

About

template<> struct type_conversion<Person> template<> struct type_conversion<Person>

Here, the official document is incorrect. I checked it for a long time and wrote it according to the above method.

1. Use the data structure to select

TEST(soci,select_obj_one){  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;    string name = "dandan";    Person p;    sql << "select id,name,sex from tb_test where name = :name",      into(p, ind), use(name);    ASSERT_EQ(ind, i_ok) << name;    if (sql.got_data())    {      cout<< p.id         << ","         << p.name         << ","         << p.sex         << endl;    }  }  catch (exception const &e)  {    FAIL()<<e.what();  }} TEST(soci,select_obj_one){  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;     string name = "dandan";    Person p;    sql << "select id,name,sex from tb_test where name = :name",      into(p, ind), use(name);     ASSERT_EQ(ind, i_ok) << name;     if (sql.got_data())    {      cout<< p.id         << ","         << p.name         << ","         << p.sex         << endl;    }   }  catch (exception const &e)  {    FAIL()<<e.what();  }}

2. insert with Data Structure

TEST(soci,insert_obj_noexist){  try  {    session sql(mysql, "db=soci user=dantezhu");    Person p = {      0,      "niuniu",      2    };    sql << "insert into tb_test(name, sex) values(:name, :sex)",      use(p);  }  catch (exception const &e)  {    FAIL()<<e.what();  }} TEST(soci,insert_obj_noexist){  try  {    session sql(mysql, "db=soci user=dantezhu");     Person p = {      0,      "niuniu",      2    };     sql << "insert into tb_test(name, sex) values(:name, :sex)",      use(p);  }  catch (exception const &e)  {    FAIL()<<e.what();  }}

This is the case ~~ The download path of the code file is as follows:
Http://code.google.com/p/vimercode/source/browse/#svn%2Ftrunk%2Fsoci_test

In addition, although mysql access in python is relatively simple, I still want to know if there is a more Pythonic library or interface. If you have any friends, please do not hesitate to inform me.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.