• 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()

                   {

                        //...

                   } 

      

  • 相关阅读:
    牛客(46)孩子们的游戏(圆圈中最后剩下的数)
    牛客(45)扑克牌顺子
    牛客(44)翻转单词顺序列
    牛客(43)左旋转字符串
    牛客(42)和为S的两个数字
    牛客(41)和为S的连续正数序列
    牛客(40)数组中只出现一次的数字
    牛客(39)平衡二叉树
    牛客(38)二叉树的深度
    牛客(37)数字在排序数组中出现的次数
  • 原文地址:https://www.cnblogs.com/cxwx/p/1765332.html
Copyright © 2020-2023  润新知