Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

简易版仿C#的sql访问接口 - C++实现 #6

Open
coneo opened this issue Oct 22, 2014 · 0 comments
Open

简易版仿C#的sql访问接口 - C++实现 #6

coneo opened this issue Oct 22, 2014 · 0 comments
Labels

Comments

@coneo
Copy link
Owner

coneo commented Oct 22, 2014

前段时间在做一个C++的mysql的api封装,对于接口使用上来说,一直没有找到一种比较合适的方案。后来看了下C#的sql访问接口,发现还不错,遂实现了一个简易版的sql接口集合。

先说说C#的sql访问接口

C#是采用了面向对象的方式来实现sql访问接口的,使用起来相当的方便,先说说几个重要的对象:

  1. SqlConnection:每一个对数据库的连接都封装在SqlConnection中,执行sql之前必须先保证已连接数据库;
  2. SqlCommand:把查询语句封装在SqlCommand中,在执行语句的时候主要有两种执行方式:ExecuteReader和ExecuteNonQuery,他们之间的区别是前者要返回查询的数据库内容,后者则只需执行sql操作;
  3. SqlDataReader:封装查询结果,如果执行了SqlCommand的ExecuteReader,则会返回一个SqlDataReader,里面包含了查询结果;
  4. SqlParameter:这个是对查询语句的拼装作一层封装,可以有效的防止sql注入问题。

我们直接来看看C#的使用实例,连接数据库,并执行查询操作

private static void ReadOrderData(string connectionString)
{
     SqlConnection connection = new SqlConnection("server= .; uid=hxq; pwd=123456; database=testlazy");
    string queryString = 
        "SELECT OrderID, CustomerID FROM dbo.Orders;";
    using (SqlConnection connection = new SqlConnection(
               connectionString))
    {
        SqlCommand command = new SqlCommand(
            queryString, connection);
        connection.Open();
        SqlDataReader reader = command.ExecuteReader();
        try
        {
            while (reader.Read())
            {
                Console.WriteLine(String.Format("{0}, {1}",
                    reader[0], reader[1]));
            }
        }
        finally
        {
            // Always call Close when done reading.
            reader.Close();
        }
    }
}

下面开始谈谈C++简易版实现

我们的简易版sql访问接口与C#版有很多的区别:

  • 无异常处理
  • 无SqlParameter(必要时在后面会实现一个)
  • 仅支持mysql封装,不支持其他数据库
  • C++版使用SqlCommand::getAffectedRows来获取影响的行数,C#版ExecuteNonQuery会返回影响行数,通过ExecuteReader返回的SqlDataReader中有个成员RecordsAffected也表示影响行数。

初始化数据库:

DB db;

db.init("localhost", "hxq", "123456", "testlazy");

查询使用实例:

void testSelect()
{
    Connection* con = db.getConnection();
    SqlCommand* cmd = new SqlCommand("SELECT * FROM USER", con);
    DataReader reader = cmd->executeReader();
    stUser user;     //此处stUser是一个结构体
    while (reader.read())
    {
        reader.get("ID", user.id);
        reader.get("AGE", user.age);
        reader.get("NAME", user.name);
        reader.get("CITY", user.city);
        user.print();
    }
    cout << "affected rows: " << cmd->getAffectedRows() << endl;
    delete cmd;
}

插入数据实例:

void testInsert()
{
    stringstream ss;
    ss << "INSERT INTO USER(AGE,NAME,CITY) VALUES (";
    ss << "'24'" <<","<< "'lazy'"<< "," << "'fuling'";
    ss << ")";
    Connection* con = db.getConnection();
    SqlCommand* cmd = new SqlCommand(ss.str(), con);
    cmd->executeNoQuery();
    cout << "affected rows: " << cmd->getAffectedRows() << endl;
    delete cmd;
}

更新数据实例:

void testUpdate()
{
    stringstream ss;
    ss << "UPDATE USER SET NAME='lazyqiang' WHERE ID=1;";
    Connection* con = db.getConnection();
    SqlCommand* cmd = new SqlCommand(ss.str(), con);
    cmd->executeNoQuery();
    cout << "affected rows: " << cmd->getAffectedRows() << endl;
    delete cmd;
}

总的来说,这版使用接口还算清晰,具体使用中,sql语句拼接比较繁琐,后续考虑添加一个sql拼接器,也为防止sql注入作一定保证。

代码放在这里

@coneo coneo added the mysql label Oct 22, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant