翼度科技»论坛 编程开发 PHP 查看内容

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

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
参考了很多前人的文章,最后只支持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。
  1. /**
  2. * Kingbase数据库驱动
  3. */
  4. class Kingbase extends PDOConnection
复制代码
找到 protected function parseDsn(array $config): string 方法,修改该方法下代码:
  1. $dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname'];
  2. //修改为:
  3. $dsn = 'kdb:host=' . $config['hostname'] . ';dbname=' . $config['database'];
复制代码
3.新增金仓数据库的builder类
进到ThinkPHP项目目录下的vendor\topthink\think-orm\src\db\builder\下,复制Pgsql.php为Kingbase.php,同样修改文件中的类名为Kingbase。
  1. /**
  2. * Kingbase数据库驱动
  3. */
  4. class Kingbase extends Builder
复制代码
其他代码不需要修改。
 
4.ThinkPHP配置文件
三处mysql都修改为kingbase:
  1. return [
  2.     // 默认使用的数据库连接配置
  3.     'default'         => env('database.driver', 'kingbase'),
  4. ……
  5. // 数据库连接配置信息
  6.     'connections'     => [
  7.         'kingbase' => [
  8.             // 数据库类型
  9.             'type'            => env('database.type', 'kingbase'),
  10.             // 服务器地址
  11.             'hostname'        => env('database.hostname', 'localhost'),
  12.             // 数据库名
  13.             'database'        => env('database.database', 'TEST'),
  14.             // 用户名
  15.             'username'        => env('database.username', 'SYSTEM'),
  16.             // 密码
  17.             'password'        => env('database.password', '123456'),
  18.             // 端口
  19.             'hostport'        => env('database.hostport', '54321'),
  20.             // 数据库连接参数
  21.             'params'          => [],
  22.             // 数据库编码默认采用utf8
  23.             'charset'         => env('database.charset', 'utf8'),
  24.             // 数据库表前缀
  25.             'prefix'          => env('database.prefix', ''),
  26. ……
  27.         // 更多的数据库配置信息
  28.     ],
  29. ];
复制代码
到此处,和其他文章介绍的方案都一样,现在介绍重点,重点就在这个执行的sql语句上,这个语句执行了很多次都不成功,不是提示table_msg函数不存在,就是其他的一些错误,后来在KStudio中单独创建各个函数,依次排除问题解决。
现在分享3个函数的创建语句,需要到对应的模式下,新建查询进行导入:
  1. CREATE OR REPLACE FUNCTION public .pgsql_type(a_type   varchar )   RETURNS varchar AS
  2. DECLARE
  3. v_type   varchar ;
  4. BEGIN
  5.      IF a_type=  'int8' THEN
  6.           v_type:=  'bigint' ;
  7.      ELSIF a_type=  'int4' THEN
  8.           v_type:=  'integer' ;
  9.      ELSIF a_type=  'int2' THEN
  10.           v_type:=  'smallint' ;
  11.      ELSIF a_type=  'bpchar' THEN
  12.           v_type:=  'char' ;
  13. ELSE
  14.           v_type:=a_type;
  15. END IF;
  16. RETURN v_type;
  17. END
复制代码
 
  1. CREATE OR REPLACE FUNCTION public .table_msg(a_schema_name   varchar , a_table_name   varchar )   RETURNS SETOF tablestruct   AS
  2. DECLARE
  3. v_ret   public .tablestruct;
  4. v_oid oid;
  5. v_sql text;
  6. v_rec RECORD;
  7. v_key   varchar ;
  8. BEGIN
  9.     SELECT
  10.     pg_class.oid   INTO v_oid
  11.     FROM
  12.     pg_class
  13. INNER JOIN pg_namespace   ON
  14.     (
  15.         pg_class.relnamespace = pg_namespace.oid
  16.             AND lower (pg_namespace.nspname) = a_schema_name
  17.     )
  18.     WHERE
  19.     pg_class.relname = a_table_name;
  20. IF   NOT FOUND   THEN
  21.          RETURN ;
  22. END IF;
  23. v_sql =   '
  24.      SELECT
  25.            sys_attribute.attname AS fields_name,
  26.            sys_attribute.attnum AS fields_index,
  27.            pgsql_type(sys_type.typname::varchar) AS fields_type,
  28.            sys_attribute.atttypmod-4 as fields_length,
  29.            CASE WHEN sys_attribute.attnotnull THEN ' 'not null' '
  30.            ELSE ' '' '
  31.            END AS fields_not_null,
  32.            sys_attrdef.adbin AS fields_default,
  33.            sys_description.description AS fields_comment
  34.      FROM
  35.            sys_attribute
  36.            INNER JOIN sys_class ON sys_attribute.attrelid = sys_class.oid
  37.            INNER JOIN sys_type ON sys_attribute.atttypid = sys_type.oid
  38.            LEFT OUTER JOIN sys_attrdef ON sys_attrdef.adrelid = sys_class.oid AND sys_attrdef.adnum = sys_attribute.attnum
  39.            LEFT OUTER JOIN sys_description ON sys_description.objoid = sys_class.oid AND sys_description.objsubid = sys_attribute.attnum
  40.      WHERE
  41.            sys_attribute.attnum > 0
  42.            AND attisdropped <> ATTISLOCAL
  43. ORDER BY sys_attribute.attnum' ;
  44. FOR v_rec   IN EXECUTE v_sql LOOP
  45.          v_ret.fields_name = v_rec.fields_name;
  46. v_ret.fields_type = v_rec.fields_type;
  47. IF v_rec.fields_length > 0   THEN
  48.             v_ret.fields_length := v_rec.fields_length;
  49. ELSE
  50.             v_ret.fields_length :=   NULL ;
  51. END IF;
  52. v_ret.fields_not_null = v_rec.fields_not_null;
  53. v_ret.fields_default = v_rec.fields_default;
  54. v_ret.fields_comment = v_rec.fields_comment;
  55. SELECT
  56.     constraint_name   INTO v_key
  57. FROM
  58.     information_schema.key_column_usage
  59. WHERE
  60.     table_schema = a_schema_name
  61.     AND table_name = a_table_name
  62.     AND column_name = v_rec.fields_name;
  63. IF FOUND   THEN
  64.             v_ret.fields_key_name = v_key;
  65. ELSE
  66.             v_ret.fields_key_name =   '' ;
  67. END IF;
  68. RETURN NEXT v_ret;
  69. END LOOP;
  70. RETURN ;
  71. END
复制代码
  
  1. CREATE OR REPLACE FUNCTION public .table_msg(a_table_name   varchar )   RETURNS SETOF tablestruct   AS
  2. DECLARE
  3. v_ret tablestruct;
  4. BEGIN
  5. FOR v_ret   IN SELECT *   FROM table_msg(  'public' ,a_table_name) LOOP
  6.     RETURN NEXT v_ret;
  7. END LOOP;
  8.     RETURN ;
  9. END
复制代码
 
成功导入3个函数后,在函数项下会出现3个函数,如图:

 
在数据类型功能下,增加一个数据类型,数据类型配置如下:


 
 
完成此步骤后:可以在Controller控制器中执行如下代码测试:
 
  1. try {
  2.             $data =\app\home\model\User::select();
  3.             dump(  $data );
  4.         }  catch (\Exception   $e ) {
  5.             dump(  $e ->getMessage());
  6.         }
  7.         \app\home\model\User::create([  "user_name" =>  "123456" ,
  8.             "user_pwd" =>  "123456" ,
  9.             "mobile" =>  "abc" ,
  10.             "full_name" =>  "abc" ,
  11.         ]);
复制代码
  

  1.  
复制代码
来源:https://www.cnblogs.com/lanfengye/p/18337128
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具