C++/CLR写的Data Blocks

简介: 

从Microsoft Enterprise Library 5.0 Data Blocks剥离出的数据库操作方法,重新用C++/clr语言封装的一个模块!

只实现几个简单常用的接口,用于c++/clr项目中。

 

 

写在代码前面:

项目是c++/clr的,所以他只需要c++/clr的代码,他不需要我提供dll方式的功能模块,他只需要.h和.cpp文件;

不想说了,其他事情还是放在心里吧,直接贴代码就好了!

 

 

 项目结构:

 

 实现的接口:


 

代码片段:

DataBase.h
public ref class DataBase
    {
    
public:
        DataBase(String 
^connectionString,DbProviderFactory ^dbProviderFactory)
        {
            
if(String::IsNullOrEmpty(connectionString))
                
throw gcnew ArgumentException("连接字符串不允许为空");
            
if (dbProviderFactory == nullptr) 
                
throw gcnew ArgumentNullException("数据库提供类型不允许为空");
            
this->m_connectionString=connectionString;
            
this->m_dbProviderFactory=dbProviderFactory;
        }
        
//连接字符串
        property String ^ConnectionString
        {
            String 
^get(){return m_connectionString;}
        }

        
virtual int ExecuteNonQuery(DbCommand ^command);
        
virtual int ExecuteNonQuery(CommandType commandType,String ^commandText);
        
virtual Object ^ExecuteScalar(DbCommand ^command);
        
virtual Object ^ExecuteScalar(CommandType commandType,String ^commandText);
        
virtual DataSet ^ExecuteDataSet(DbCommand ^command);
        
virtual DataSet ^ExecuteDataSet(CommandType commandType,String ^commandText);
        
virtual IDataReader ^ExecuteReader(DbCommand ^command);
        
virtual IDataReader ^ExecuteReader(CommandType commandType,String ^commandText);
        
enum class UpdateBehavior
        {
            
/// <summary>
            
/// No interference with the DataAdapter's Update command. If Update encounters
            
/// an error, the update stops.  Additional rows in the Datatable are uneffected.
            
/// </summary>
            Standard,
            
/// <summary>
            
/// If the DataAdapter's Update command encounters an error, the update will
            
/// continue. The Update command will try to update the remaining rows. 
            
/// </summary>
            Continue,
            
/// <summary>
            
/// If the DataAdapter encounters an error, all updated rows will be rolled back.
            
/// </summary>
            Transactional  
        };
    
private:
         String 
^m_connectionString;
         DbProviderFactory 
^m_dbProviderFactory;

         DbConnection 
^GetNewOpenConnection();
         DbCommand 
^CreateCommandByCommandType(CommandType commandType,String ^commandText);
    
protected:
        
virtual DatabaseConnectionWrapper ^GetWrappedConnection();
        
static void PrepareCommand(DbCommand ^command,DbConnection ^connection);
        
int DoExecuteNonQuery(DbCommand ^command);
        Object 
^DoExecuteScalar(IDbCommand ^command);
        IDataReader 
^DoExecuteReader(DbCommand ^command,CommandBehavior cmdBehavior);
        
void DoLoadDataSet(DbCommand ^command,DataSet ^dataSet,array<String^> ^tableNames);
        DbDataAdapter 
^GetDataAdapter(UpdateBehavior updateBehavior);
        
virtual void SetUpRowUpdatedEvent(DbDataAdapter ^adapter) { }

    };
DataBase.cpp

#include 
"DataBase.h"
using namespace DBManager;


/*返回数据库语句执行所影响的行数:int*/
int DataBase::ExecuteNonQuery(DbCommand ^command)
{
    DatabaseConnectionWrapper 
^wrapper=GetWrappedConnection();
    PrepareCommand(command,wrapper
->Connection);
    
int ret=DoExecuteNonQuery(command);
    delete command;
    delete wrapper;
    
return ret;
}
int DataBase::ExecuteNonQuery(CommandType commandType,String ^commandText)
{
    DbCommand 
^command = CreateCommandByCommandType(commandType, commandText);
    
return ExecuteNonQuery(command);
}
int DataBase::DoExecuteNonQuery(DbCommand ^command)
{
    
try{
        
int rowsAffected = command->ExecuteNonQuery();
        
return rowsAffected;
    }
    
catch(Exception ^e)
    {
        
throw e;
    }
}

/*返回数据库语句执行结果:Object*/
Object 
^DataBase::ExecuteScalar(DbCommand ^command)
{
    DatabaseConnectionWrapper 
^wrapper=GetWrappedConnection();
    PrepareCommand(command,wrapper
->Connection);
    Object 
^ret=DoExecuteScalar(command);
    delete command;
    delete wrapper;
    
return ret;
}
Object 
^DataBase::ExecuteScalar(CommandType commandType,String ^commandText)
{
    DbCommand 
^command = CreateCommandByCommandType(commandType, commandText);
    
return ExecuteScalar(command);
}
Object 
^DataBase::DoExecuteScalar(IDbCommand ^command)
{
    
try{
        Object 
^returnValue = command->ExecuteScalar();
        
return returnValue;
    }
    
catch(Exception ^e)
    {
        
throw e;
    }
}

/*返回数据库语句执行结果:DataSet*/
DataSet 
^DataBase::ExecuteDataSet(DbCommand ^command)
{
    DataSet 
^dataSet = gcnew DataSet();
    dataSet
->Locale = System::Globalization::CultureInfo::InvariantCulture;  //获取不依赖于区域性(固定)的 CultureInfo。
    DatabaseConnectionWrapper ^wrapper=GetWrappedConnection();
    PrepareCommand(command,wrapper
->Connection);
    DoLoadDataSet(command, dataSet, gcnew array
<String^>{"Table"});
    delete wrapper;
    
return dataSet;
}
DataSet 
^DataBase::ExecuteDataSet(CommandType commandType,String ^commandText)
{
    DbCommand 
^command = CreateCommandByCommandType(commandType, commandText);
    
return ExecuteDataSet(command);
}
void DataBase::DoLoadDataSet(DbCommand ^command,DataSet ^dataSet,array<String^> ^tableNames)
{
    
if (tableNames == nullptr) 
        
throw gcnew ArgumentNullException("表名数组不允许为空");
    
if (tableNames->Length == 0)
    {
        
throw gcnew ArgumentException("表名数组长度为0");
    }
    
for (int i = 0; i < tableNames->Length; i++)
    {
        
if (String::IsNullOrEmpty(tableNames[i])) 
            
throw gcnew ArgumentException(String::Concat("表名数组第[", i, "]项为空"));
    }
    DbDataAdapter 
^adapter = GetDataAdapter(UpdateBehavior::Standard);
    ((IDbDataAdapter
^)adapter)->SelectCommand = command;
    
try
    {
        String 
^systemCreatedTableNameRoot = "Table";
        
for (int i = 0; i < tableNames->Length; i++)
        {
            String 
^systemCreatedTableName = (i == 0)
                
? systemCreatedTableNameRoot
                : systemCreatedTableNameRoot 
+ i; //Table,Table1,Table2

            adapter
->TableMappings->Add(systemCreatedTableName, tableNames[i]);
        }
        adapter
->Fill(dataSet);
    }
    
catch(Exception ^e)
    {
        
throw e;
    }
    
finally
    {
        delete adapter;
    }
}
DbDataAdapter 
^DataBase::GetDataAdapter(UpdateBehavior updateBehavior)
{
    DbDataAdapter 
^adapter = m_dbProviderFactory->CreateDataAdapter();

    
if (updateBehavior == UpdateBehavior::Continue)
    {
        SetUpRowUpdatedEvent(adapter);  
//define in ".h"
    }
    
return adapter;
}


/*返回数据库语句执行结果:DataReader*/
IDataReader 
^DataBase::ExecuteReader(DbCommand ^command)
{
    DatabaseConnectionWrapper 
^wrapper=GetWrappedConnection();
    PrepareCommand(command,wrapper
->Connection);
    IDataReader 
^realReader = DoExecuteReader(command, CommandBehavior::Default);
    RefCountingDataReader 
^reader=gcnew RefCountingDataReader(wrapper, realReader);
    
return reader->InnerReader;
}
IDataReader 
^DataBase::ExecuteReader(CommandType commandType,String ^commandText)
{
    DbCommand 
^command = CreateCommandByCommandType(commandType, commandText);
    
return ExecuteReader(command);
}
IDataReader 
^DataBase::DoExecuteReader(DbCommand ^command,CommandBehavior cmdBehavior)
{
    
try{
        IDataReader 
^reader = command->ExecuteReader(cmdBehavior);
        
return reader;
    }
    
catch(Exception ^e)
    {
        
throw e;
    }
}


/*添加DbCommand对象的DbConnection属性*/
void DataBase::PrepareCommand(DbCommand ^command,DbConnection ^connection)
{
    
if (command == nullptr) throw gcnew ArgumentNullException("不允许空的DbCommand对象");
    
if (connection == nullptr) throw gcnew ArgumentNullException("不允许空的DbConnection对象");
    command
->Connection=connection;
}

/*返回一个DatabaseConnectionWrapper对象*/
DatabaseConnectionWrapper 
^DataBase::GetWrappedConnection()
{
   
return gcnew DatabaseConnectionWrapper(GetNewOpenConnection());
}

/*返回数据库连接对象:DbConnection*/
DbConnection 
^DataBase::GetNewOpenConnection()
{
    DbConnection 
^connection=nullptr;
    
try
    {
        
try
        {
            connection
=m_dbProviderFactory->CreateConnection();
            connection
->ConnectionString=m_connectionString;
            connection
->Open();
        }
        
catch(Exception ^ex)    
        {
            
throw ex;
        }
    }
    
catch(Exception ^e)
    {
        
if(connection!=nullptr)
            connection
->Close();
        
throw e;
    }
    
return connection;
}

/*返回一个DbCommand对象*/
DbCommand 
^DataBase::CreateCommandByCommandType(CommandType commandType,String ^commandText)
{
    DbCommand 
^command = m_dbProviderFactory->CreateCommand();
    command
->CommandType = commandType;
    command
->CommandText = commandText;
    
return command;
}
测试代码
void CallBack(Object ^obj)
    {

            
//Sql Server数据库测试
            String ^strConn="Data Source=localhost,8306;Initial Catalog=SensorLeadDB;User ID=sa;Password=HZ.bridge";
            SqlDataBase 
^sqlbase=gcnew SqlDataBase(strConn);
            
int m_count=sqlbase->SqlExecuteNonQuery("delete  from OriginalDatas where SendTime>'2010-06-15' and Sensorid='1-1-2'");
            Object 
^m_obj=sqlbase->SqlExecuteScalar("select Sensorid from Sensor");
            DataSet 
^m_set=sqlbase->SqlExecuteDataSet("select * from Sensor");
            SqlDataReader 
^m_reader=sqlbase->SqlExecuteReader("select Sensorid,SensorType from Sensor");
            Console::WriteLine(
"Delete Result:{0}",m_count);
            Console::WriteLine(
"Select Result:{0}",m_obj);
            
int tablesCount=m_set->Tables->Count;
            
for (int i=0;i<tablesCount;i++)
            {
                Console::WriteLine(
"DataSet Result:TableName ={0},RowCount={1}",m_set->Tables[i]->TableName,m_set->Tables[i]->Rows->Count);
            }
            Console::WriteLine(
"SqlDataReader Result:HasRows={0}",m_reader->HasRows);


            
//Access数据库测试
            strConn="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=mydatabase.mdb;";
            GenericDatabase 
^gdb=gcnew GenericDatabase(strConn,OleDbFactory::Instance);
            m_count
=gdb->ExecuteNonQuery(CommandType::Text,"insert into userinfo(name,pass) values('test','123456')");
            m_obj
=gdb->ExecuteScalar(CommandType::Text,"select count(*) from userinfo");
            Console::WriteLine(
"Delete Result:{0}",m_count);
            Console::WriteLine(
"Select Result:{0}",m_obj);

            frmShow 
^frm=gcnew frmShow(m_set,m_reader);
            frm
->ShowDialog();

        
    }
    
int main(array<System::String ^> ^args)
    {

        WaitCallback 
^call=gcnew WaitCallback(CallBack);
        
for (int i=0;i<3;i++)
        {
            ThreadPool::QueueUserWorkItem(call);  
//并发测试
        }
        Console::ReadLine();
        
return 0;
    }
项目文件下载: /Files/cxwx/DBManager.rar

文件DatabaseConnectionWrapper中如下部分稍作修改

//Dispose

~DatabaseConnectionWrapper()

{

int count = Interlocked::Decrement(refCount); //以原子操作的形式递减指定变量的值并存储结果  返回0 refCount=1

if (count == 0)

{

m_Connection->~DbConnection();

}

                !DatabaseConnectionWrapper()

               {

                    //...

               } 

  

原文地址:https://www.cnblogs.com/cxwx/p/1765332.html