ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题
参考了很多前人的文章,最后只支持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" ,
]);

ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题的更多相关文章
- 通过ODBC接口访问人大金仓数据库
国产化软件和国产化芯片的窘境一样,一方面市场已经存在性能优越的同类软件,成本很低,但小众的国产化软件不仅需要高价买入版权,并且软件开发维护成本高:另一方面,国产软件目前普遍难用,性能不稳定,Bug ...
- QT 之 ODBC连接人大金仓数据库
QT 之 使用 ODBC 驱动连接人大金仓数据库 获取数据库驱动和依赖动态库 此操作可在人大金仓官网下载与系统匹配的接口动态库,或者从架构数据库的源码中获取驱动和依赖动态库 分别为: 驱动动态库:kd ...
- 通过jmeter连接人大金仓数据库
某项目用的人大金仓数据库,做性能测试,需要用jmeter来连接数据库处理一批数据.jmeter连接人大金仓,做个记录. 1. 概要 在"配置元件"中添加"JDBC Con ...
- linux安装国产数据库(金仓数据库,达梦数据库,南大通用数据库)
今天在公司做的任务是,在Linux的环境下安装三种数据库,结果一种数据库也没有安装好,首先遇到的问题是安装南大通用数据库遇到安装的第五步,就出现问题了,问题是Gbase SDK没有安装成功,以及Gba ...
- 润乾配置连接kingbase(金仓)数据库
问题背景 客户根据项目的不同,使用润乾连接的数据库类型各种各样,此文针对前几日使用润乾设计器连接kingbase金仓数据库做一个说明. kingbase金仓数据库是一款国产数据库,操作方式和配置 ...
- Rocky4.2下安装金仓v7数据库(KingbaseES)
1.准备操作系统 1.1 系统登录界面 1.2 操作系统版本信息 jdbh:~ # uname -ra Linux jdbh -x86_64 # SMP Fri Dec :: CST x86_64 G ...
- 金仓Kingbase数据库网页数据维护分析工具
金仓Kingbase是优秀的国产数据库产品,在能源,政务,国防等领域广泛使用, 现在TreeSoft数据库管理系统已支持Kingbase了,直接在浏览器中就可以操作查看Kingbase数据了,十分方便 ...
- DBeaver连接达梦|虚谷|人大金仓等国产数据库
前言 工作中有些项目可能会接触到「达梦.虚谷.人大金仓」等国产数据库,但通常这些数据库自带的连接工具使用并不方便,所以这篇文章记录一下 DBeaver 连接国产数据库的通用模版,下文以达梦为例(其他国 ...
- 教你10分钟对接人大金仓EF Core 6.x
前言 目前.NET Core中据我了解到除了官方的EF Core外,还用的比较多的ORM框架(恕我孤陋寡闻哈,可能还有别的)有FreeSql.SqlSugar(排名不分先后).FreeSql和SqlS ...
- 不支持关键字“metadata”问题的解决方法
不支持关键字“metadata”问题的解决方法 原来的语句: metadata=res://*/Models.CallCenterEntities2.0.csdl|res://*/Models.Cal ...
随机推荐
- docker ——网络配置和管理
docker网络基础 了解docker网络 两种docker网络 单主机与多主机的docker网络 网络驱动 网络驱动 介绍 bridge 桥接网络,这是默认的网络驱动程序 host 主机网络 ove ...
- 从零开始写 Docker(十七)---容器网络实现(中):为容器插上”网线“
本文为从零开始写 Docker 系列第十七篇,利用 linux 下的 Veth.Bridge.iptables 等等相关技术,构建容器网络模型,为容器插上"网线". 完整代码见:h ...
- Python实现字符串模糊匹配
在一个字符串中,有时需对其中某些内容进行模糊匹配以实现条件的判定,如在"你好,hello,world"中判断是否含有"llo".Python中通过re.se ...
- Lru在Rust中的实现, 源码解析
LRU(Least Recently Used)是一种常用的页面置换算法,其核心思想是选择最近最久未使用的页面予以淘汰. LRU算法原理 基本思想:LRU算法基于一个假设,即如果一个数据在最近一段时间 ...
- kettle从入门到精通 第三十六课 kettle carte 集群
1.carte服务可以单体运行也可以集群方式运行,今天我们一起来学习下carte的集群模式部署和使用.本次示例用一个master和两个slave从节点演示. carte-config-master-8 ...
- C#.NET根据不同业务类别类型写入不同文件中,动态创建log4net实例验证
C#.NET根据不同业务类别类型写入不同文件中,动态创建log4net实例验证 参考了:https://www.cnblogs.com/-dawn/p/8598566.html GetLog4netI ...
- categraf托管与自升级
categraf支持多种方式进行部署.托管,社区里部署和管理categraf也是五花八门,大家自己使用方便即可. 之前我们觉得大家通过ansible之类的工具批量下发/更新就能很简单地完成任务,最近很 ...
- 使用shell脚本在Linux中管理Java应用程序
目录 前言 一.目录结构 二.脚本实现 1. 脚本内容 2. 使用说明 2.1 配置脚本 2.2 脚本部署 2.3 操作你的Java应用 总结 前言 在日常开发和运维工作中,管理基于Java的应用程序 ...
- 阿里云安全扫描漏洞修复fastjson,jackson,xstream,redis, 微信支付xml转对象 ForbiddenClassException
阿里云安全扫描漏洞修复fastjson,jackson,xstream,redis 1.fastjson漏洞fastjson爆发新的反序列化远程代码执行漏洞,黑客利用漏洞,可绕过autoType限制, ...
- Unity中使用ProtocolBuffer
Unity中使用ProtocolBuffer unityProtocolBufferUnity ProtocolBuggerC# ProtocolBuffer Unity中使用ProtocolBuff ...