首页 > 数据库 >ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题

ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题

时间:2024-08-01 17:40:45浏览次数:10  
标签:金仓 name database fields Kingbase ThinkPHP6 sys ret type

参考了很多前人的文章,最后只支持Db::query原生查询,不支持thinkphp数据模型方法,这在实际项目中是很难接受的,特分享出解决方案。

先按照流程配置如下:

1.准备工作

首先确认PHP支持金仓数据库的扩展,可以去金仓官网下载,安装配置(详细配置略过……)。

使用 php -m 命令检查,显示有 pdo_kdb即可。 这里注意一下libpq.dll的版本要>=10,否则会报错误。

2,新增金仓数据库的connenter类

进到ThinkPHP项目目录下的vendor\topthink\think-orm\src\db\connector\下,复制Pgsql.php为Kingbase.php(基于pgsql修改),修改文件中的类名为Kingbase。

/**
 * Kingbase数据库驱动
 */
class Kingbase extends PDOConnection

找到 protected function parseDsn(array $config): string 方法,修改该方法下代码:

$dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname'];
//修改为:
$dsn = 'kdb:host=' . $config['hostname'] . ';dbname=' . $config['database'];

3.新增金仓数据库的builder类

进到ThinkPHP项目目录下的vendor\topthink\think-orm\src\db\builder\下,复制Pgsql.php为Kingbase.php,同样修改文件中的类名为Kingbase。

/**
 * Kingbase数据库驱动
 */
class Kingbase extends Builder

其他代码不需要修改。

 

4.ThinkPHP配置文件

三处mysql都修改为kingbase:

return [
    // 默认使用的数据库连接配置
    'default'         => env('database.driver', 'kingbase'),

……

// 数据库连接配置信息
    'connections'     => [
        'kingbase' => [
            // 数据库类型
            'type'            => env('database.type', 'kingbase'),
            // 服务器地址
            'hostname'        => env('database.hostname', 'localhost'),
            // 数据库名
            'database'        => env('database.database', 'TEST'),
            // 用户名
            'username'        => env('database.username', 'SYSTEM'),
            // 密码
            'password'        => env('database.password', '123456'),
            // 端口
            'hostport'        => env('database.hostport', '54321'),
            // 数据库连接参数
            'params'          => [],
            // 数据库编码默认采用utf8
            'charset'         => env('database.charset', 'utf8'),
            // 数据库表前缀
            'prefix'          => env('database.prefix', ''),

……

        // 更多的数据库配置信息
    ],
];

到此处,和其他文章介绍的方案都一样,现在介绍重点,重点就在这个执行的sql语句上,这个语句执行了很多次都不成功,不是提示table_msg函数不存在,就是其他的一些错误,后来在KStudio中单独创建各个函数,依次排除问题解决。
现在分享3个函数的创建语句,需要到对应的模式下,新建查询进行导入:

CREATE OR REPLACE FUNCTION public .pgsql_type(a_type  varchar )  RETURNS varchar AS
DECLARE
v_type  varchar ;
BEGIN
     IF a_type= 'int8' THEN
          v_type:= 'bigint' ;
     ELSIF a_type= 'int4' THEN
          v_type:= 'integer' ;
     ELSIF a_type= 'int2' THEN
          v_type:= 'smallint' ;
     ELSIF a_type= 'bpchar' THEN
          v_type:= 'char' ;
ELSE
          v_type:=a_type;
END IF;
RETURN v_type;
END

 

CREATE OR REPLACE FUNCTION public .table_msg(a_schema_name  varchar , a_table_name  varchar )  RETURNS SETOF tablestruct  AS
DECLARE
v_ret  public .tablestruct;

v_oid oid;

v_sql text;

v_rec RECORD;

v_key  varchar ;

BEGIN
    SELECT
    pg_class.oid  INTO v_oid
    FROM
    pg_class
INNER JOIN pg_namespace  ON
    (
        pg_class.relnamespace = pg_namespace.oid
            AND lower (pg_namespace.nspname) = a_schema_name
    )
    WHERE
    pg_class.relname = a_table_name;

IF  NOT FOUND  THEN
         RETURN ;
END IF;

v_sql =  '
     SELECT
           sys_attribute.attname AS fields_name,
           sys_attribute.attnum AS fields_index,
           pgsql_type(sys_type.typname::varchar) AS fields_type,
           sys_attribute.atttypmod-4 as fields_length,
           CASE WHEN sys_attribute.attnotnull THEN ' 'not null' '
           ELSE ' '' '
           END AS fields_not_null,
           sys_attrdef.adbin AS fields_default,
           sys_description.description AS fields_comment 
     FROM
           sys_attribute 
           INNER JOIN sys_class ON sys_attribute.attrelid = sys_class.oid 
           INNER JOIN sys_type ON sys_attribute.atttypid = sys_type.oid 
           LEFT OUTER JOIN sys_attrdef ON sys_attrdef.adrelid = sys_class.oid AND sys_attrdef.adnum = sys_attribute.attnum 
           LEFT OUTER JOIN sys_description ON sys_description.objoid = sys_class.oid AND sys_description.objsubid = sys_attribute.attnum
     WHERE
           sys_attribute.attnum > 0 
           AND attisdropped <> ATTISLOCAL 
ORDER BY sys_attribute.attnum' ;

FOR v_rec  IN EXECUTE v_sql LOOP
         v_ret.fields_name = v_rec.fields_name;

v_ret.fields_type = v_rec.fields_type;

IF v_rec.fields_length > 0  THEN
            v_ret.fields_length := v_rec.fields_length;
ELSE
            v_ret.fields_length :=  NULL ;
END IF;

v_ret.fields_not_null = v_rec.fields_not_null;

v_ret.fields_default = v_rec.fields_default;

v_ret.fields_comment = v_rec.fields_comment;

SELECT
    constraint_name  INTO v_key
FROM
    information_schema.key_column_usage
WHERE
    table_schema = a_schema_name
    AND table_name = a_table_name
    AND column_name = v_rec.fields_name;

IF FOUND  THEN
            v_ret.fields_key_name = v_key;
ELSE
            v_ret.fields_key_name =  '' ;
END IF;

RETURN NEXT v_ret;
END LOOP;

RETURN ;
END

  

CREATE OR REPLACE FUNCTION public .table_msg(a_table_name  varchar )  RETURNS SETOF tablestruct  AS
DECLARE
v_ret tablestruct;
BEGIN
FOR v_ret  IN SELECT *  FROM table_msg( 'public' ,a_table_name) LOOP
    RETURN NEXT v_ret;
END LOOP;
    RETURN ;
END

 

成功导入3个函数后,在函数项下会出现3个函数,如图:

完成此步骤后:可以在Controller控制器中执行如下代码测试:

 

try {
            $data =\app\home\model\User::select();
            dump( $data );
        } catch (\Exception  $e ) {
            dump( $e ->getMessage());
        }


        \app\home\model\User::create([ "user_name" => "123456" ,
            "user_pwd" => "123456" ,
            "mobile" => "abc" ,
            "full_name" => "abc" ,
        ]);

  

 

标签:金仓,name,database,fields,Kingbase,ThinkPHP6,sys,ret,type
From: https://www.cnblogs.com/lanfengye/p/18337128

相关文章

  • ThinkPHP6之Excel解析
    PhpSpreadsheet解析Excel文件安装PhpSpreadsheet通过Composer安装了PhpSpreadsheet:composerrequirephpoffice/phpspreadsheet控制器ExcelController<?phpnamespaceapp\controller;usethink\facade\Db;usethink\facade\Request;usethink\facade\View;use......
  • 人大金仓踩坑指南
    现在越来越多的项目要求-切换国产数据库系统,或达梦(性能高),或人大金仓(扩展性高,更稳定),跨平台如果上来就干,坑还是不少的,本人有幸踩个遍. 1.软件有效期,人大金仓可不便宜,不少政府采购网上都是标价10万+,测试时候用专业版玩一玩就好到期后,可以直接下载其他版本的授权文件进行替换,......
  • KingbaseES数据库禁止某用户连接到数据库
    一、权限介绍KingbaseES数据库中的权限控制主要分为两个层次:实例级别和数据库级别。实例级别的权限由sys_hba.conf文件控制,而数据库级别的权限则由数据库内部的权限系统控制。对于数据库以及实例的权限控制,这两者权限控制可以理解为粗粒度,细粒度。实例级别权限:这主要通过sys_hba......
  • KingbaseES 等待事件之DataFileRead
    等待事件含义IO:DataFileRead等待事件发生在会话连接等待后端进程从存储中读取所需页面,原因是该页面在共享内存中不可用或无法找到。所有查询和数据操作(DML)操作都访问缓冲池中的页面,语句包括SELECT、UPDATE和DELETE等。例如,UPDATE可以从表或索引中读取页面。如果请求或更新的页......
  • KingbaseES 数据库WAL日志暴增问题处理
    故障现象:kingbase数据库容量不足100G,业务繁忙程度小,但是每天产生112283个WAL日志,每个日志16M,生成约1.7T的归档日志分析过程:思路一:从数据库日志入手,分析过程如下:sys_log日志:2024-06-0223:54:05.497CST3130361b580b0.7a47182242021-12-1212......
  • KingbaseES V8R6等待事件之 lwlock: CSNLogControlLock
    一、原理CSN日志是数据库中用于记录事务提交顺序和事务状态的重要日志,为了解决高并发场景下获取快照时的性能瓶颈,引入CSN机制。CSN机制通过为每个非只读事务分配一个XID(事务号),并在事务提交时推进CSN,同时保存CSN与XID的映射关系在CSNLog中。CSNLogControlLock等待事件通常表示某......
  • KingbaseES V8R6等待事件之 lock: transactionid
    等待事件含义Lock:在数据库管理系统中,锁是用来确保数据完整性和一致性的重要机制。当一个事务需要修改数据时,它会请求一个锁来防止其他事务同时修改相同的数据,从而导致数据不一致。transactionid:这通常是一个唯一标识符,用于区分和跟踪数据库中的不同事务。每个事务都有一个唯一的......
  • KingbaseES 更改 WAL 日志文件大小
    一、引言WAL日志的目的:WAL(Write-AheadLogging)是KingbaseES数据库中的一个关键特性,用于确保在数据库崩溃或故障后能够恢复数据。WAL日志记录了数据库的所有更改,这样即使数据库突然宕机,也可以从WAL文件中恢复数据到一致性状态。命令的功能:sys_resetwal命令用于重置WAL日志,它可以......
  • KingbaseES 数据库无响应问题分析
    一、背景及理论阐述某项目数据库系统是集群环境,主库业务卡顿,应用反馈部分业务无法正常进行。在操作系统中,物理内存(RAM)是有限的资源,当内存需求超过物理内存的容量时,操作系统会使用页面调度机制来管理内存资源。页面调度涉及将不常用的内存页面(Page)移到磁盘上的交换空间(SwapSpace......
  • KingbaseES 对象状态规则总结
    KingbaseES的PLSQL对象包括函数、存储过程、触发器、包、包体、对象类型、对象类型体和匿名块,其中匿名块即用即销,不具有状态属性,SQL中存在依赖的常见对象是表,视图,索引,自定义类型,自定义操作符等等。在使用编码过程会存在相互引用和被引用,就会导致对象的增删改无法“顺利”进行,本文......