DIOCP开源项目-数据库连接池的使用<多帐套数据库>

       很久没有写DIOCP的Demo了,主要公司的事情太繁琐,工作之余都不想动了,之前承若的群里面朋友们的DEMO,昨天晚上恶补了一下,把对数据库连接池的操作加入到了Demo中,大家可以通过SVN下载到最新的代码和Demo。

       好了我带大家看看这次的DEMO,经过群里面朋友们的推荐,这次代码中引用了UntCobblerUniPool连接池代码来完成的本次的DEMO,研究了下代码,里面使用的线程时钟来做死连和多余连接的释放。感谢UntCobblerUniPool作者无私奉献的精神。

      先截个图,看看服务端的界面。

image

主要加入了多帐套的连接的配置。配置文件存放在config\dbpool.config,是一个json格式的文件配置

{
"account2013": {
  "connString": "Provider Name=SQL Server;Data Source=192.168.1.2;Database=xxxx;User ID=sa;Password=sa"
},
"account2012": {
  "connString": "Provider Name=SQL Server;Data Source=192.168.1.2;Database=xxx02;User ID=sa;Password=sa"
}
}

 

DEMO中我演示了两个帐套(实际运行中帐套个数是不固定),account2013和account2012代表帐套的ID,在clientContext中可以通过客户端传递过来的帐套ID,获取连接字符串,到连接池中获取一个连接。

看看服务端的代码

procedure TClientContext.dataReceived(const pvDataObject:TObject);
var
  lvJsonStream:TJSonStream;
  lvFile:String;
  lvCmdIndex:Cardinal;
  lvXMLData, lvEncodeData:AnsiString;
  lvSQL, lvID:String;
  lvDBDataOperator:TUniOperator;
  lvPoolObj:TUniCobbler;

begin
  lvJsonStream := TJSonStream(pvDataObject);
  try
    lvCmdIndex := lvJsonStream.JSon.I['cmdIndex'];

    //执行SQL的命令ID
    if lvCmdIndex= 1001 then
    begin
      //客户端传递过来的帐套ID
      lvID := lvJsonStream.Json.S['config.accountID'];
      if lvID = '' then
      begin
        raise Exception.Create('没有指定帐套ID(config.accountID)');
      end;

      //客户端指定要执行的SQL
      lvSQL := lvJsonStream.Json.S['script.sql'];
      if lvSQL = '' then
      begin
        raise Exception.Create('没有指定要执行的SQL!');
      end;

      //通过帐套ID获取一个连接池对象
      lvPoolObj := TUniPool.getConnObject(lvID);
      try
        //打开连接
        lvPoolObj.checkConnect;

        //Uni数据库操作对象<可以改用对象池效率更好>
        lvDBDataOperator := TUniOperator.Create;
        try
          //设置使用的连接池
          lvDBDataOperator.Connection := lvPoolObj.ConnObj;
          self.StateINfo := '借用了一个lvADOOpera,准备打开连接!';
          try
            //获取一个查询的数据
            lvXMLData := lvDBDataOperator.CDSProvider.QueryXMLData(lvSQL);
            self.StateINfo := 'lvADOOpera,执行SQL语句完成,准备回写数据';
          except
            raise;
          end;

          lvJsonStream.Clear();
          lvJsonStream.Stream.WriteBuffer(lvXMLData[1], Length(lvXMLData));
          lvJsonStream.setResult(True);
        finally
          lvDBDataOperator.Free;
        end;
      finally
        //归还连接池
        TUniPool.releaseConnObject(lvPoolObj);
      end;
      //回写数据给客户端
      writeObject(lvJsonStream);
    end else
    begin
      //返回数据
      writeObject(lvJsonStream);
    end;
  except
    on E:Exception do
    begin
      lvJsonStream.Clear();
      lvJsonStream.setResult(False);
      lvJsonStream.setResultMsg(e.Message);
      writeObject(lvJsonStream);
    end;

  end;
end;


注释写的比较清楚了,我就不再解释了,其他关联代码可以具体去看各单元的代码。

 

看看客户端界面。

image

客户端通过指定帐套ID,告诉服务端应该选用哪个数据库进行操作。

 

客户端执行的代码

procedure TfrmMain.btnOpenSQLClick(Sender: TObject);
var
  lvRecvObj, lvSendObj:TJsonStream;
  i, l, lvSize:Integer;
  lvData:AnsiString;
begin
  lvSendObj := TJsonStream.Create;
  lvRecvObj := TJsonStream.Create;
  try
    lvSendObj.Clear();

    //帐套ID
    lvSendObj.Json.S['config.accountID'] := txtAccount.Text;

    //执行SQL的命令ID
    lvSendObj.Json.I['cmdIndex'] := 1001;

    //要执行的SQL
    lvSendObj.Json.S['script.sql'] := mmoSQL.Lines.Text;

    //发送到服务端进行处理<使用Indy进行传输>,如果需要使用ICS,可以在IOCPCoder文件夹中找到对应的uICSClientJSonStreamCoder.pas单元
    TIdTcpClientJSonStreamCoder.Encode(self.IdTCPClient, lvSendObj);

    //接收服务端处理的数据<使用Indy接收数据>
    TIdTcpClientJSonStreamCoder.Decode(self.IdTCPClient, lvRecvObj);
    if not lvRecvObj.getResult then
    begin
      raise Exception.Create(lvRecvObj.getResultMsg);
    end;

    //获取数据
    SetLength(lvData, lvRecvObj.Stream.Size);
    lvRecvObj.Stream.Position := 0;
    lvRecvObj.Stream.ReadBuffer(lvData[1], lvRecvObj.Stream.Size);

    //放入CDS的XMLDATA
    cdsMain.XMLData := lvData;
  finally
    lvSendObj.Free;
    lvRecvObj.Free;
  end;
end;

在DIOCP\Demos\IOCPCoder代码中我写了一些客户端的界面和编码器,有ICS,和Indy的,有需要的朋友可以直接引用使用。

         基本上差不多了。刚刚群里面的朋友测试在XE4下面测试是通过的,我的环境是D2007。

>>>>>>DIOCP讨论群:320641073

>>>>>>SVN源码和DEMO下载:https://code.google.com/p/diocp/

posted @ 2013-09-17 10:56  D10.天地弦  阅读(3325)  评论(2编辑  收藏  举报