人大金仓KingbaseV8适配文档

1 应用及对应版本

MybatisPlus(3.4.2)
kingbaseES 数据库版本(V008R006C007B0024)
kingbase驱动包版本(8.6.0)
mysql 数据库(8.0.31)
mysql 驱动包版本(8.0.20)

2 主要改造点

数据库连接方式;
pom.xml 依赖包修改;
数据库改造点;
mybatis: *Mapper.xml 文件改造;
java 类改造(含实体类、Service和Controller等);

3 改造内容

3.1 数据库连接方式

spring.datasource.type = com.zaxxer.hikari.HikariDataSource
spring.datasource.driverClassName = com.kingbase8.Driver
spring.datasource.url = jdbc:kingbase8://localhost:54321/xxxx?characterEncoding=utf8
spring.datasource.username = xxx
spring.datasource.password = xxx
spring.datasource.initialSize = 10
spring.datasource.minIdle = 10
spring.datasource.maxActive = 345
spring.datasource.maxWait = 60000
spring.datasource.timeBetweenEvictionRunsMillis = 60000
spring.datasource.minEvictableIdleTimeMillis = 300000
spring.datasource.validationQuery = SELECT 1 FROM T_ETC
spring.datasource.testWhileIdle = true
spring.datasource.testOnBorrow = false
spring.datasource.testOnReturn = false
spring.datasource.poolPreparedStatements = true
spring.datasource.maxPoolPreparedStatementPerConnectionSize = 20
spring.datasource.filters = stat,wall,log4j
spring.datasource.connectionProperties = druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.driver-class-name=com.kingbase8.Driver
spring.datasource.hikari.minimum-idle=1
spring.datasource.hikari.connection-test-query=SELECT 1
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=GHHikariCP
spring.datasource.hikari.max-lifetime=120000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.db-type=oracle
#处理数据库中 Boolean 和 实体类中的 Integer 的类型转换,看下面的 3.4
mybatis-plus.type-handlers-package=com.test.tools.model.typehandler
#设置数据库配置的模式
mybatis-plus.global-config.db-config.schema=xxxx

3.2 pom.xml文件修改

<!--mysql 驱动包-->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>

<!--KingBase 驱动包-->
<dependency>
  <groupId>com.xh</groupId>
  <artifactId>kingbase-x86</artifactId>
  <version>8.6.0</version>
</dependency>

3.3 数据库调整点

1、数据库的数据类型与服务对应关系
在这里插入图片描述
注意:如果出现下图问题,则需要把字段设置 timestamp WITHOUT time ZONE ;或出现Java的LocalDateTime 映射 TimeStampZ类型失败的问题,也是需要把字段设置成 timestamp WITHOUT time ZONE。
在这里插入图片描述

2、创建若干函数,例如:date_format、exec 等
(很多 mysql 函数不被人大金仓数据库支持,需要手动创建)

-- 创建 date_format 函数,并支持若干日期格式
-- kingbase 没有这个函数,需要自定义,以下为参考,具体还需要结合业务看是否适配,可自行增减
CREATE OR REPLACE FUNCTION "public"."date_format"("indate" anyelement, "intext" text)
    RETURNS "pg_catalog"."text" AS $BODY$
	BEGIN
		IF upper(inText) = upper('%Y%m%d_%H%i') THEN
		return to_char(inDate,'YYYYMMDD_HH24MI');
		END IF;
		IF upper(inText) = upper('%Y-%m-%d %H:%i:%s') THEN
		return to_char(inDate,'YYYY-MM-DD HH24:MI:SS');
		END IF;
		IF upper(inText) = upper('%Y%m%d%H%i%s') THEN
		return to_char(inDate,'YYYYMMDDHH24MISS');
		END IF;
		IF upper(inText) = upper('%Y-%m-%d %H') THEN
		return to_char(inDate,'YYYY-MM-DD HH24');
		END IF;
		IF upper(inText) = upper('%Y-%m-%d') THEN
		return to_char(inDate,'YYYY-MM-DD');
		END IF;
		IF upper(inText) = upper('%Y-%m') THEN
		return to_char(inDate,'YYYY-MM');
		end if;
		IF upper(inText) = upper('%Y') THEN
		return to_char(inDate,'YYYY');
		end if;
		IF upper(inText) = upper('%m%d') THEN
		return to_char(inDate,'MMDD');
		END IF;
		IF upper(inText) = upper('%k') THEN
		return to_char(inDate,'HH24');
		END IF;
		IF upper(inText) = upper('%c') THEN
		return to_char(inDate,'MM');
		END IF;
		return '';
	END;
	$BODY$
LANGUAGE plpgsql VOLATILE
COST 100

-- 创建 exec 函数
CREATE OR REPLACE FUNCTION "public"."exec"("sqlstring" varchar)
  RETURNS "pg_catalog"."varchar" AS $BODY$
    declare
        res varchar(50);
    BEGIN
        EXECUTE sqlstring;
        RETURN 'ok';
    END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100

3、检查各表、表字段名,统一修改为小写
4、检查各字段名是否存在驼峰式命名,统一修改为下划线的形式,并与对应的实体类一一对应——>即带下划线的数据库表字段对应驼峰命名的实体类字段

3.4 Boolean转Integer 转换器

package  com.test.tools.model.typehandler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * kingbase不支持boolean值,需要转换成int
 *
 * @author 
 * @date 2024/3/4 18:00
 */
public class BooleanHandler extends BaseTypeHandler<Boolean> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Boolean aBoolean, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, aBoolean ? 1 : 0);
    }

    @Override
    public Boolean getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
        int man = resultSet.getInt(columnName);
        return man == 1;
    }

    @Override
    public Boolean getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
        int man = resultSet.getInt(columnIndex);
        return man == 1;
    }

    @Override
    public Boolean getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
        int man = callableStatement.getInt(columnIndex);
        return man == 1;
    }
}

3.5 mybatis: *Mapper.xml 文件改造;

1、 凡是碰到 limit 关键字,需按照 postgre 语法重新更改
– 对已知表查询前五条数据
修改前:limit 1,5
修改后:limit 0 offset 5

2、逐个检查 java 中 Mapper.xml 文件中的 update 语句,update 条件不能使用别名操作
修改前:update t_device t set t.band_flag = #{bandFlag} where t.id = #{id} ;
修改后:update t_device set band_flag = #{bandFlag} where id = #{id} ;
3、 关联表字段存在类型不一致的情况,需要用 :: varchar 做类型转换,因为 mysql 的语法对字符串和数值类型做了兼容处理,而 kingbase 是严格区分字符串和数值,所以在遇到一些类型不一致的情况,需要类型转换
– device_id 字段是int4类型,后面concat函数转换后的是字符串类型,得使用 :: 先将device_id临时转化成字符串

SELECT * FROM t_alarm h 
LEFT JOIN t_config c on c.device_id=d.id or c.device_id :: varchar = CONCAT('cam_',d.id);

4、sql查询过程中自定义的别名不要出现数据库关键字。例:select 字段名 as year (多见于统计年份)
5、kingbase数据库char存储是按照定长存储,不够的自动填充空字符,sql查询出来之后会带上缺少的空字符,比对的时候会出问题,变长字符串没有这个问题
6、 kingbase 分组查询不能将上级查询结果放到子查询中作为条件
7、 若该方法的返回类型为 resultMap ,则需要看情况修改该 resultMap 映射的 column 中的字段名;
8、 需要注意的一点在mysql中排序的时候null默认是最小的,在kingbase里面null默认是排序最大值;
9、 sql中包含 ` 符号需要替换掉,kingbase不支持这种写法,全部替换为空,或者替换成英文的 ’ 。(重点)

3.6 java 类改造(含实体类、Service和Controller等)

1、 修改 @TableName 注解,将注解内的表名统一修改为小写,若表名是按照驼峰命名规则,建议改为带下划线形式
– 已知表命名为 t_device 的情况下,以下为错误实例:
1)@TableName(“T_DEVICE”)
2)@TableName(“tDevice”)
3)@TableName(“T_device”)

2、 对于表自增的 id,应当加上注解:@TableId(type = IdType.AUTO) ,不要使用@TableId(type = IdType.NONE) 注解,否则 id 不会自增长;
3、 检查实体类中的字段是否有非驼峰命名,驼峰命名不需要任何修改,最主要的是需要跟数据库中的字段保持对应,即带下划线的数据库表字段对应驼峰命名的实体类字段。

--修改前的建表语句:
CREATE TABLE "public"."t_device" (
	"manualPath" varchar(64) COLLATE "pg_catalog"."default"
);
-- 修改前对应的实体类字段申明:
private String manualPath ;

-- 修改后的建表语句:
CREATE TABLE "public"."t_device" (
	"manual_path" varchar(64) COLLATE "pg_catalog"."default"
);

原理:(MybatisPlus 会自动将数据库中带下划线的字段转换成驼峰形式)

4、 检索工程中使用 Wrapper 形式写 sql 语句或者字段的部分,必须将条件中的字段名称与表字段保持相同。Wrapper 中使用的字段,必须要和数据库保持一致,否则会报字段找不到的错误。
5、 若实体类中 username 字段没有按驼峰命名,需要在该字段上加上注解@TableField(“user_name”) 其他字段类似,最好保持一致,使用 userName 驼峰式命名规则。

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值