暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

应用程序适配磐维数据库实践

IT那活儿 2023-07-18
2135

点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!

磐维数据库(cmdb)是中国移动基于openGauss内核的面向ICT基础设施的自研数据库产品。我们现场有套平台是基于Hibernate ORM框架技术开发,运行在mysql 数据库上,需要对平台进行改造适配cmdb 数据库,本文介绍改造过程所碰到的问题及其对应的解决办法。




问题vs办法



1. ojdbc 依赖问题

1.1 程序报错信息
org.postgresql.util.PSQLException: 不支援 10 验证类型。请核对您已经组态 pg_hba.conf 文件包含客户端的IP位址或网路区段,以及驱动程序所支援的验证架构模式已被支援。
1.2 解决方案
cmdb是基于postgresql 9.2  版本进行封装实现的,程序通过ojdbc 方式操作cmdb数据库,不能使用postgresql 官方自带的ojdbc 包进行连接,需要改用cmdb 自带ojdbc驱动进行连接使用。
2. 框架兼容性问题-HQL Update 失败,查询出多条数据,Hibernate 在每次修改实体对象的参数时,都会执行更新操作
2.1 程序报错信息
Batch update returned unexpected row count from update [0]; actual row count: 13; expected: 1
2.2 解决方案
  • 方案一:使用 JDBC 操作数据库。
  • 方案二:不修改实体类,直接编写 SQL,通过 Hibernate 的 executeSql() 方法进行更新。
3. 不支持函数-unix_timestamp
3.1 程序报错信息
ERROR: function unix_timestamp(timestamp without time zone) does not exist
对应 SQL:
SELECT
  sysuserlog0_.id AS id1_108_,
  sysuserlog0_.description AS descript2_108_,
  sysuserlog0_.ip AS ip3_108_,
  sysuserlog0_.operator AS operator4_108_,
  sysuserlog0_.parameter AS paramete5_108_,
  sysuserlog0_.time AS time6_108_,
  sysuserlog0_.type AS type7_108_,
  sysuserlog0_.url AS url8_108_
FROM
  sys_userlog sysuserlog0_
ORDER BY
  unix_timestamp(sysuserlog0_.time) DESC
LIMIT ?

3.2 解决方案
order by unix_timestamp(time) desc
-- 修改为
order by time desc

4. 不支持函数-date_format
4.1 程序报错信息
ERROR: function date_format(timestamp without time zone, unkown) does not exist
对应 SQL:
SELECT
  DATE_FORMAT(dbc.flchecktime,
  '%Y-%m-%d')
FROM
  dmm_basejob_checkrecords dbc

4.2 解决方案
date_format(column, '%Y-%m-%d')
-- 修改为
to_char(column, 'YYYY-MM-DD')
-- 或者修改为
to_date(left(column::text,10),'YYYY-MM-DD')

5. 不支持函数-ifnull
5.1 程序报错信息
ERROR: function ifnull(numeric, integer) does not exist
对应 SQL:
SELECT
  IFNULL(SUM(dtc.table_rows),
  0)
FROM
  dmm_node_table_result dntr,
  dmm_table_capacity dtc
WHERE
  dntr.attachmentid = dtc.flattachmentid
  AND dntr.table_name = dtc.fltablename
  AND dntr.flowchart_id = '-1'

5.2 解决方案
ifnull
--修改为
coalesce

注意:当使用函数 coalesce 时,第一个参数为 timestamp 时,在 PostgreSQL 中第二个参数不能为 ''。

6. 不支持函数-any_value
6.1 程序报错信息
ERROR: function any_value(character varying) does not exist
对应 SQL:
select
  b.id,
  b. NAME,
  COUNT(distinct c.dbid) db_cnt,
  COUNT( distinct c.dbid, c. OWNER, c.table_name ) tb_cnt,
  b.flowchart_id flowchart_id,
  MAX(ck.flchecktime) flchecktime,
  b.system_id,
  any_value(dpm.flname)
from
  dmm_business b,
  dmm_business_flowchart_node a,
  dmm_node_table_result c,
  dmm_basejob_checkrecords ck,
  dmm_pdm_modelsystem dpm
where
  b.flowchart_defined = 1
  and a.flowchart_id = b.flowchart_id
  and c.node_id = a.node_id
  and b.flowchart_id = c.flowchart_id
  and ck.flid = c.checkrecordid
  and b.system_id = dpm.flid
  and c.checkrecordid in(10, 7, 4, 8, 24)
  and b.flowchart_defined = 1
group by
  b.id
order by
  flchecktime desc
limit ?

6.2 解决方案
说明:any_value() 会选择被分到同一组的数据里第一条数据的指定列值作为返回数据,主要作用是抑制 ONLY_FULL_GROUP_BY 值被拒绝,获取的值在代码中没有实际意义。
any_value(dpm.flname)
-- 修改为
max(dpm.flname) flname

7. 不支持函数-group_concat
7.1 程序报错信息
ERROR: function group_concat(text) does not exist
对应 SQL:
SELECT
  count(*)
FROM
  (
  SELECT
    dct.tablecode,
    GROUP_CONCAT( CONCAT( dct.flstatus,
    '(',
    dct.fltableid,
    ')' )) tableIds
  FROM
    dmm_pdm_attachment dpa
  INNER JOIN dmm_pdm_table dpt ON
    dpa.flid = dpt.flattachmentid
  LEFT JOIN dmm_collect_tables dct ON
    dct.tablecode = dpt.flcode
    AND dct.fldbid = dpa.fldbid
  WHERE
    dpa.flid IN (
    SELECT
      dbc1.flattachmentid flid
    FROM
      dmm_basejob_checkrecords dbc1,
      (
      SELECT
        dbc2.fldbid,
        max(dbc2.flid) flcheckrecordid
      FROM
        dmm_basejob_checkrecords dbc2
      WHERE
        dbc2.is_success = 1
      GROUP BY
        dbc2.fldbid ) tmp
    WHERE
      dbc1.fldbid = tmp.fldbid
      AND dbc1.flid = tmp.flcheckrecordid )
    AND dct.flstatus != 1
    AND dpa.flsystypeid =:dmmSystemId
  GROUP BY
    dct.tablecode) aa

7.2 解决方案
GROUP_CONCAT(CONCAT( dct.flstatus,'(',dct.fltableid,')' )) tableIds
-- 修改为
string_agg(CONCAT( dct.flstatus, '(', dct.fltableid, ')' ),',') tableIds

8. 不支持函数-any_value
8.1 程序报错信息
ERROR: function any_value(character varying) does not exist
对应 SQL:
select
  b.id,
  b. NAME,
  COUNT(distinct c.dbid) db_cnt,
  COUNT( distinct c.dbid, c. OWNER, c.table_name ) tb_cnt,
  b.flowchart_id flowchart_id,
  MAX(ck.flchecktime) flchecktime,
  b.system_id,
  any_value(dpm.flname)
from
  dmm_business b,
  dmm_business_flowchart_node a,
  dmm_node_table_result c,
  dmm_basejob_checkrecords ck,
  dmm_pdm_modelsystem dpm
where
  b.flowchart_defined = 1
  and a.flowchart_id = b.flowchart_id
  and c.node_id = a.node_id
  and b.flowchart_id = c.flowchart_id
  and ck.flid = c.checkrecordid
  and b.system_id = dpm.flid
  and c.checkrecordid in(10, 7, 4, 8, 24)
  and b.flowchart_defined = 1
group by
  b.id
order by
  flchecktime desc
limit ?

8.2 解决方案
说明:any_value() 会选择被分到同一组的数据里第一条数据的指定列值作为返回数据,主要作用是抑制 ONLY_FULL_GROUP_BY 值被拒绝,获取的值在代码中没有实际意义。
any_value(dpm.flname)
-- 修改为
max(dpm.flname) flname


END


本文作者:长研架构小组(上海新炬中北团队)

本文来源:“IT那活儿”公众号

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论