递归火山软件开发平台

标题: 能否封装一个Oracle数据库的连接池 [打印本页]

作者: 阳光甜橙    时间: 2024-4-23 15:03
标题: 能否封装一个Oracle数据库的连接池
这么强大的数据库,没有连接池。

作者: zqiz    时间: 2024-4-23 17:15
@阳光甜橙 能否把火山“斗地主”例程改为“掼蛋”?
作者: glbosom    时间: 2024-4-23 18:21
本帖最后由 glbosom 于 2024-4-23 22:17 编辑

<火山程序 类型 = "通常" 版本 = 1 />

类 ADO连接池类 <公开 注释 = "ADO数据库连接池" 折叠>
{
    变量 成员_未使用连接 <类型 = 整数到对象哈希表>
    变量 成员_已使用连接 <类型 = 整数到对象哈希表>
    变量 ""
    变量 成员_最大连接数 <类型 = 整数>
    变量 成员_连接文本 <类型 = 文本型>
    变量 成员_用户名称 <类型 = 文本型>
    变量 成员_用户密码 <类型 = 文本型>
    变量 成员_互斥锁 <类型 = 互斥锁类>

    方法 初始化 <公开 类型 = 整数 注释 = "初始化连接" 返回值注释 = "返回连接数量">
    参数 连接文本 <类型 = 文本型
            注释 = "提供包含连接信息的一个文本,具体信息可参阅文档\"https://docs.microsoft.com/zh-cn/sql/ado/reference/ado-api/connectionstring-property-ado?view=sql-server-ver15\"."
            注释 = "如果本参数为空,将使用\"连接文本\"属性作为该参数的值,如果本参数提供非空内容,将会优先于\"连接文本\"属性." @默认值 = "">
    参数 用户名称 <类型 = 文本型 注释 = "提供连接该数据库所需的用户名(如果连接文本中包含,此参数将会覆盖连接文本中的对应用户名信息)." @默认值 = "">
    参数 用户密码 <类型 = 文本型 注释 = "提供连接该数据库所需的密码(如果连接文本中包含,此参数将会覆盖连接文本中的对应密码信息)." @默认值 = "">
    参数 最大连接数 <类型 = 整数 注释 = "连接池中所能创建的最大连接数量." @默认值 = 50>
    参数 初始连接数 <类型 = 整数 注释 = "初始化时所欲创建的可用连接数." @默认值 = 10>
    {
        成员_最大连接数 = 最大连接数
        成员_连接文本 = 连接文本
        成员_用户名称 = 用户名称
        成员_用户密码 = 用户密码

        成员_互斥锁.加锁 ()
        成员_未使用连接.枚举循环 ()
        {
            ((数据库类)成员_未使用连接.取枚举值 ()).关闭 ()
        }

        成员_已使用连接.枚举循环 ()
        {
            ((数据库类)成员_已使用连接.取枚举值 ()).关闭 ()
        }

        成员_未使用连接.清空 ()
        成员_已使用连接.清空 ()
        计次循环 (初始连接数)
        {
            变量 局部_数据库 <类型 = 数据库类>
            如果 (局部_数据库.连接 (连接文本, 用户名称, 用户密码, 真, 假))
            {
                局部_数据库.标记值 = 取循环索引 ()
                成员_未使用连接.插入 ((整数)局部_数据库.标记值, 局部_数据库)
            }
            否则
            {
                跳出循环
            }
        }
        成员_互斥锁.解锁 ()
        返回 (成员_未使用连接.取成员数 ())
    }

    方法 初始化MySQL <公开 类型 = 整数 注释 = "初始化mysql." 注释 = "注意:使用前确保系统中已安装对应的数据库驱动程序." 返回值注释 = "返回连接数量"
            编辑时信息 = "9B4AB, 0, 0, 0">
    参数 连接地址 <类型 = 文本型 注释 = "提供数据库连接地址." 编辑时信息 = "9B4AB, 0, 0, 0">
    参数 数据库名称 <类型 = 文本型 注释 = "提供所欲打开的数据库名称." 编辑时信息 = "9B4AB, 0, 0, 0">
    参数 用户名称 <类型 = 文本型 注释 = "提供连接该数据库所需的用户名." 编辑时信息 = "9B4AB, 0, 0, 0">
    参数 用户密码 <类型 = 文本型 注释 = "提供连接该数据库所需的密码." 编辑时信息 = "9B4AB, 0, 0, 0">
    参数 连接端口 <类型 = 整数 注释 = "通过该数据库的连接端口." 编辑时信息 = "9B4AB, 0, 0, 0" @默认值 = 3306>
    参数 驱动程序 <类型 = 文本型
            注释 = "提供连接Mysql所需的驱动程序名称,例如\"MySQL ODBC 8.0 Unicode Driver\",使用前请确保系统中已安装该驱动,否则无法进行连接."
            注释 = "  驱动下载地址:https://dev.mysql.com/downloads/connector/odbc/" 编辑时信息 = "9B4AB, 0, 0, 0"
            @默认值 = "MySQL ODBC 8.0 Unicode Driver">
    参数 最大连接数 <类型 = 整数 注释 = "连接池中所能创建的最大连接数量." @默认值 = 50>
    参数 初始连接数 <类型 = 整数 注释 = "初始化时所欲创建的可用连接数." @默认值 = 10>
    {
        返回 (初始化 (取格式文本 ("rovider=MSDASQL; DRIVER=%s; SERVER=%s; PORT=%d; DATABASE=%s;", 驱动程序, 连接地址, 连接端口, 数据库名称), 用户名称, 用户密码, 最大连接数, 初始连接数))
    }

    方法 初始化Oracle <公开 类型 = 整数 注释 = "开始连接到指定的远程Oracle数据库." 注释 = "注意:使用前确保系统中已安装对应的数据库驱动程序." 返回值注释 = "返回连接数量">
    参数 连接地址 <类型 = 文本型 注释 = "提供数据库连接地址.">
    参数 用户名称 <类型 = 文本型 注释 = "提供连接该数据库所需的用户名.">
    参数 用户密码 <类型 = 文本型 注释 = "提供连接该数据库所需的密码.">
    参数 驱动程序 <类型 = 文本型
            注释 = "提供连接Oracle所需的驱动程序名称,例如\"Oracle in OraClient11g_home1\",使用前请确保系统中已安装该驱动,否则无法进行连接."
            @默认值 = "Oracle in OraClient11g_home1">
    参数 最大连接数 <类型 = 整数 注释 = "连接池中所能创建的最大连接数量." @默认值 = 50>
    参数 初始连接数 <类型 = 整数 注释 = "初始化时所欲创建的可用连接数." @默认值 = 10>
    {
        返回 (初始化 (取格式文本 ("DRIVER=%s; SERVER=%s", 驱动程序, 连接地址), 用户名称, 用户密码, 最大连接数, 初始连接数))
    }

    方法 初始化Access <公开 类型 = 整数 注释 = "连接到指定Access数据库." 返回值注释 = "返回连接数量">
    参数 文件路径 <类型 = 文本型 注释 = "提供数据库文件完整路径.">
    参数 用户密码 <类型 = 文本型 注释 = "提供连接该数据库所需的用户密码." @默认值 = "">
    参数 是否新版 <类型 = 逻辑型 注释 = "本参数指定Access版本,为假则使用2003以下连接方式,为真则使用2007版本连接方式." @默认值 = 假>
    参数 最大连接数 <类型 = 整数 注释 = "连接池中所能创建的最大连接数量." @默认值 = 50>
    参数 初始连接数 <类型 = 整数 注释 = "初始化时所欲创建的可用连接数." @默认值 = 10>
    {
        如果 (是否新版)
        {
            返回 (初始化 (取格式文本 ("rovider=Microsoft.ACE.OLEDB.12.0; Data Source=%s; Jet OLEDBatabase Password=%s", 文件路径, 用户密码), , , 最大连接数, 初始连接数))
        }
        否则
        {
            返回 (初始化 (取格式文本 ("rovider=Microsoft.Jet.OLEDB.4.0; Data Source=%s; Jet OLEDBatabase Password=%s", 文件路径, 用户密码), , , 最大连接数, 初始连接数))
        }
    }

    方法 初始化Mssql <公开 类型 = 整数 注释 = "开始连接到指定的远程Mssql数据库." 返回值注释 = "返回连接数量">
    参数 连接地址 <类型 = 文本型 注释 = "提供数据库连接地址.">
    参数 数据库名称 <类型 = 文本型 注释 = "提供所欲打开的数据库名称.">
    参数 用户名称 <类型 = 文本型 注释 = "提供连接该数据库所需的用户名.">
    参数 用户密码 <类型 = 文本型 注释 = "提供连接该数据库所需的密码.">
    参数 最大连接数 <类型 = 整数 注释 = "连接池中所能创建的最大连接数量." @默认值 = 50>
    参数 初始连接数 <类型 = 整数 注释 = "初始化时所欲创建的可用连接数." @默认值 = 10>
    {
        返回 (初始化 (取格式文本 ("rovider=SqlOleDB; SERVER=%s; DATABASE=%s;", 连接地址, 数据库名称), 用户名称, 用户密码, 最大连接数, 初始连接数))
    }

    方法 初始化Postgresql <公开 类型 = 整数 注释 = "开始连接到指定的远程PostgreSQL数据库." 返回值注释 = "返回连接数量">
    参数 连接地址 <类型 = 文本型 注释 = "提供数据库连接地址.">
    参数 数据库名称 <类型 = 文本型 注释 = "提供所欲打开的数据库名称.">
    参数 用户名称 <类型 = 文本型 注释 = "提供连接该数据库所需的用户名.">
    参数 用户密码 <类型 = 文本型 注释 = "提供连接该数据库所需的密码.">
    参数 连接端口 <类型 = 整数 注释 = "通过该数据库的连接端口." @默认值 = 5432>
    参数 驱动程序 <类型 = 文本型
            注释 = "指定是否使用ODBC驱动方式连接(例如ostgreSQL UNICODE),提供空文本将会使用OLEDB方式连接,如果使用驱动方式连接,务必保证系统中已安装该驱动." @默认值 = "">
    参数 最大连接数 <类型 = 整数 注释 = "连接池中所能创建的最大连接数量." @默认值 = 50>
    参数 初始连接数 <类型 = 整数 注释 = "初始化时所欲创建的可用连接数." @默认值 = 10>
    {
        如果 (文本是否为空 (驱动程序))
        {
            返回 (初始化 (取格式文本 ("rovider=PostgreSQL OLE DB; Data Source=%s; location=%s;", 连接地址, 数据库名称), 用户名称, 用户密码, 最大连接数, 初始连接数))
        }
        否则
        {
            返回 (初始化 (取格式文本 ("rovider=MSDASQL; DRIVER=%s; SERVER=%s; PORT=%d; DATABASE=%s;", 驱动程序, 连接地址, 连接端口, 数据库名称), 用户名称, 用户密码, 最大连接数, 初始连接数))
        }
    }

    方法 取连接 <公开 类型 = 逻辑型>
    参数 数据库对象 <类型 = 数据库类 "">
    参数 连接超时 <类型 = 整数 注释 = "单位秒" @默认值 = 10>
    {
        成员_互斥锁.加锁 ()
        如果 (成员_未使用连接.取成员数 () == 0)
        {
            如果真 (成员_最大连接数 > 成员_未使用连接.取成员数 () + 成员_已使用连接.取成员数 ())
            {
                变量 局部_开始时间 <类型 = 整数>
                局部_开始时间 = 取时间戳 (取现行时间 ())
                判断循环 (真)
                {
                    如果真 (数据库对象.连接 (成员_连接文本, 成员_用户名称, 成员_用户密码, 真, 假))
                    {
                        数据库对象.标记值 = 成员_未使用连接.取成员数 () + 成员_已使用连接.取成员数 () - 1
                        成员_已使用连接.插入 ((整数)数据库对象.标记值, 数据库对象)
                        成员_互斥锁.解锁 ()
                        空闲连接数 (取空闲连接数 ())
                        返回 (真)
                    }
                    如果真 (取时间戳 (取现行时间 ()) - 局部_开始时间 >= 连接超时)
                    {
                        成员_互斥锁.解锁 ()
                        空闲连接数 (取空闲连接数 ())
                        返回 (假)
                    }
                }
            }
        }
        否则
        {
            成员_未使用连接.枚举循环 ()
            {
                数据库对象 = (数据库类)成员_未使用连接.取枚举值 ()
                成员_已使用连接.插入 ((整数)((数据库类)成员_未使用连接.取枚举值 ()).标记值, (数据库类)成员_未使用连接.取枚举值 ())
                成员_未使用连接.删除 ((整数)((数据库类)成员_未使用连接.取枚举值 ()).标记值)
                跳出循环
            }
            成员_互斥锁.解锁 ()
            空闲连接数 (取空闲连接数 ())
            返回 (真)
        }
        返回 (假)
    }

    方法 释放连接 <公开>
    参数 数据库对象 <类型 = 数据库类>
    {
        变量 局部_数据库错误集合 <类型 = 数据库错误集合类>
        变量 局部_数据库错误信息 <类型 = 数据库错误信息类>
        成员_互斥锁.加锁 ()
        局部_数据库错误集合 = 数据库对象.取错误信息 ()
        计次循环 (局部_数据库错误集合.成员数)  // 服务器断开了刷新一下连接?
        {
            局部_数据库错误信息 = 局部_数据库错误集合.取成员 (取循环索引 ())
            如果真 (局部_数据库错误信息.错误代码 == 0)  // 断网了?
            {
                成员_未使用连接.枚举循环 ()
                {
                    ((数据库类)成员_未使用连接.取枚举值 ()).关闭 ()
                    ((数据库类)成员_未使用连接.取枚举值 ()).连接 (成员_连接文本, 成员_用户名称, 成员_用户密码, 真, 假)
                }

                成员_已使用连接.枚举循环 ()
                {
                    ((数据库类)成员_已使用连接.取枚举值 ()).关闭 ()
                    ((数据库类)成员_已使用连接.取枚举值 ()).连接 (成员_连接文本, 成员_用户名称, 成员_用户密码, 真, 假)
                }
                跳出循环

            }

        }

        成员_未使用连接.插入 ((整数)数据库对象.标记值, 成员_已使用连接.取值 ((整数)数据库对象.标记值))
        成员_已使用连接.删除 ((整数)数据库对象.标记值)
        成员_互斥锁.解锁 ()
        空闲连接数 (取空闲连接数 ())
    }

    方法 释放所有连接 <公开>
    {
        成员_互斥锁.加锁 ()
        成员_已使用连接.枚举循环 ()
        {
            成员_未使用连接.插入 ((整数)成员_已使用连接.取枚举值 ().标记值, 成员_已使用连接.取枚举值 ())
        }
        成员_已使用连接.清空 ()
        成员_互斥锁.解锁 ()
        空闲连接数 (取空闲连接数 ())
    }

    方法 取空闲连接数 <公开 类型 = 整数>
    {
        返回 (成员_未使用连接.取成员数 ())
    }

    方法 空闲连接数 <公开 定义事件 类型 = 整数>
    参数 可用连接数 <类型 = 整数>
}

作者: 阳光甜橙    时间: 2024-4-23 19:07
zqiz 发表于 2024-4-23 17:15
@阳光甜橙 能否把火山“斗地主”例程改为“掼蛋”?

掼蛋是啥?
作者: ゞ情非得已Sky    时间: 2024-4-24 06:59
阳光甜橙 发表于 2024-4-23 19:07
掼蛋是啥?

扯dan........
作者: 阳光甜橙    时间: 2024-4-24 13:08
glbosom 发表于 2024-4-23 18:21
类 ADO连接池类
{
    变量 成员_未使用连接

谢谢




欢迎光临 递归火山软件开发平台 (https://bbs.voldp.com/) Powered by Discuz! X3.4