优秀的编程知识分享平台

网站首页 > 技术文章 正文

信创改造-ruoyi项目从mysql升级到kingbase数据库改造详解

nanyue 2024-10-20 07:42:56 技术文章 5 ℃

一、驱动下载及配置

  1. 驱动从官网下载,并放到项目下的libs文件下




  1. 在项目的pom文件中,注释掉mysql的驱动,增加kingbase的驱动
         <!-- Mysql驱动包 -->
<!--        <dependency>-->
<!--            <groupId>mysql</groupId>-->
<!--            <artifactId>mysql-connector-java</artifactId>-->
<!--        </dependency>-->

        <!-- kingbase驱动包 -->
        <dependency>
            <groupId>com.kingbase8.jdbc</groupId>
            <artifactId>kingbase8</artifactId>
            <version>8.6.0</version>
            <scope>system</scope>
            <systemPath>${pom.basedir}/libs/kingbase8-8.6.0.jar</systemPath>
        </dependency>

二、修改application-dev.yml配置文件

  1. 注释掉mysql的相关配置
# 数据源配置
spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
#        driverClassName: com.mysql.cj.jdbc.Driver
#        druid:
#            # 主库数据源
#            master:
#                url: jdbc:mysql://yourhost:3306/yourdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
#                username: root
#                password: yourpassword
#            # 从库数据源
#            slave:
#                # 从数据源开关/默认关闭
#                enabled: true
#                url: jdbc:mysql://yourhost:3306/yourdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
#                username: root
#                password: yourpassword
  1. 替换成kingbase的相关配置
# 数据源配置
spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.kingbase8.Driver
        druid:
          # 主库数据源
          master:
            url: jdbc:kingbase8://yourhost:54321/yourdb?currentSchema=disability_assistance,SYS_CATALOG
            username: yhk
            password: yourpassword
           # 从库数据源
          slave:
            # 从数据源开关/默认关闭
            enabled: false
            url: jdbc:kingbase8://yourhost:54321/yourdb?currentSchema=disability_assistance,SYS_CATALOG
            username: yhk
            password: yourpassword

三、如果配置正确的话,就可以开始启动应用进行调试,有可能遇到以下问题:

问题:Cause: com.kingbase8.util.KSQLException: 错误: 此查询块中所需的 CONNECT BY 子句

### The error may exist in com/yhk/base/mapper/AreaAddressMapper.java (best guess)

### The error may involve defaultParameterMap

### The error occurred while setting parameters

### SQL: SELECT id,level,parent_code,area_code,zip_code,city_code,name,short_name,detail_name,pinyin,longitude,latitude,irs_code FROM area_address

### Cause: com.kingbase8.util.KSQLException: 错误: 此查询块中所需的 CONNECT BY 子句

解决方案:原因是因为level是kingbase的关键字不能直接用

1.打开AreaAddress.java文件,修改如下:

    @NotNull(message="[层级]不能为空")
    @ApiModelProperty("层级")
    @TableField("`level`")
    private Integer level;

2.打开AreaAddressMapper.xml文件并把所有level,加上双引号"level",举例如下:

 <!--查询单个-->
    <select id="queryById" resultMap="AreaAddressMap">
        select
          id, "level", parent_code, area_code, zip_code, city_code, name, short_name, detail_name, pinyin, longitude, latitude, irs_code
        from area_address
        where id = #{id}
    </select>

如果没有问题的话,就可以正常启动成功了。


四、测试应用,并修改遇到的bug,可能遇到以下问题:

  • 问题1:函数 sysdate() 不存在
### Error updating database.  Cause: com.kingbase8.util.KSQLException: 错误: 函数 sysdate() 不存在
  Hint: 没有匹配指定名称和参数类型的函数. 您也许需要增加明确的类型转换.
  Position: 140 At Line: 2, Line Position: 39
### The error may involve com.hhh.system.mapper.SysLogininforMapper.insertLogininfor-Inline
### The error occurred while setting parameters
### SQL: insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time)   values (?, ?, ?, ?, ?, ?, ?, sysdate())
### Cause: com.kingbase8.util.KSQLException: 错误: 函数 sysdate() 不存在

解决方案: 把所有函数 sysdate() 都替换为kingbase的函数sysdate,以SysLogininforMapper.xml为例

	<insert id="insertLogininfor" parameterType="SysLogininfor">
		insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time)
		values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, sysdate())
	</insert>

替换后:

	<insert id="insertLogininfor" parameterType="SysLogininfor">
		insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time)
		values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, sysdate)
	</insert>
  • 问题:字段 "UNSIGNED" 不存在
springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: com.kingbase8.util.KSQLException: 错误: 字段 "UNSIGNED" 不存在
  Position: 118 At Line: 1, Line Position: 118

解决方案:

convert(t2.service_period,UNSIGNED) 改为  t2.service_period
  • 问题:在查询列表中必须出现SELECT DISTINCT, ORDER BY表达式
### SQL: SELECT   distinct `flow_no`   FROM disability_flow_process   WHERE  deleted=0  AND (actor_role_id <> ? AND service_type = ? AND status = ?) ORDER BY status ASC,id DESC LIMIT ?
### Cause: com.kingbase8.util.KSQLException: 错误: 在查询列表中必须出现SELECT DISTINCT, ORDER BY表达式
  Position: 153 At Line: 6, Line Position: 74
; bad SQL grammar []; nested exception is com.kingbase8.util.KSQLException: 错误: 在查询列表中必须出现SELECT DISTINCT, ORDER BY表达式

原因:order 的字段需要全部加到DISTINCT中去。

解决方案:distinct `flow_no` 改为 "distinct `flow_no`,`status`,`id`"

  • 问题:操作符不存在: bit = integer

Caused by: com.kingbase8.util.KSQLException: 错误: 操作符不存在: bit = integer

Hint: 没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.

需要全部把以下
eq(DisabilityFamilyMember::getIsDeleted,0));
改为
eq(DisabilityFamilyMember::getIsDeleted,Boolean.FALSE));
  • 问题:mem.is_deleted为bit类型,不能直接 = 0

### SQL: SELECT count(0) FROM (SELECT mem.family_group_id, dbi.id, dbi.name, dbi.mobile, dbi.disability_certificate_number, dbi.id_card_number, dbi.disability_type, dbi.disability_level, dbi.gender, dbi.birthday, dbi.age, dbi.present_community, dbi.present_street FROM disability_family_member mem LEFT JOIN disability_base_info dbi ON mem.disability_id = dbi.id WHERE mem.is_deleted = 0 GROUP BY mem.family_group_id) table_count

### Cause: com.kingbase8.util.KSQLException: 错误: 操作符不存在: bit = integer

Hint: 没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.

Position: 376 At Line: 1, Line Position: 376

; bad SQL grammar []; nested exception is com.kingbase8.util.KSQLException: 错误: 操作符不存在: bit = integer

Hint: 没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.

解决方案:

mem.is_deleted = 0

改为

mem.is_deleted = '0'


问题:GROUP BY 少了字段 "dbi.id"

### SQL: SELECT count(0) FROM (SELECT mem.family_group_id, dbi.id, dbi.name, dbi.mobile, dbi.disability_certificate_number, dbi.id_card_number, dbi.disability_type, dbi.disability_level, dbi.gender, dbi.birthday, dbi.age, dbi.present_community, dbi.present_street FROM disability_family_member mem LEFT JOIN disability_base_info dbi ON mem.disability_id = dbi.id WHERE mem.is_deleted = '0' GROUP BY mem.family_group_id) table_count

### Cause: com.kingbase8.util.KSQLException: 错误: 字段 "dbi.id" 必须出现在 GROUP BY 子句中或者在聚合函数中使用

Position: 51 At Line: 1, Line Position: 51

; bad SQL grammar []; nested exception is com.kingbase8.util.KSQLException: 错误: 字段 "dbi.id" 必须出现在 GROUP BY 子句中或者在聚合函数中使用

解决方案:

GROUP BY mem.family_group_id 后面dbi.id


  • 问题:需要对Kingbase的相应日期函数和语法进行调整

SQL: SELECT * FROM disability_activity_user WHERE DATE(activity_start_time) = DATE(NOW() - INTERVAL 1 DAY) AND status = 1;

### Cause: com.kingbase8.util.KSQLException: 错误: 语法错误 在 "(" 或附近的

解决方法:

SELECT *
FROM disability_activity_user
WHERE activity_start_time::date = CURRENT_DATE - 1
AND status = 1;
  • 问题:重复键违反唯一约束

sed by: com.kingbase8.util.KSQLException: 错误: 重复键违反唯一约束"PRIMARY_C154670D"

Detail: 键值"(id)=(389)" 已经存在

解决方法:在kstudio管理工具中,把键值调大1个数字


最近发表
标签列表