后续会持续更新,查缺补漏... ...
( Kingbase 是基于 PostGreSQL 开发的一款数据库,所以本篇文章的大部分内容也适用于 PostGreSQL 改造 )
###【改造前的数据库连接配置】
spring:
datasource:
## 涉及敏感内容,需要将 IP、端口、数据库名修改成你自己想要的
url: jdbc:mysql://127.0.0.1:3306/test_db?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
## 涉及敏感内容,将数据库用户名、密码修改成你自己想要的
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 1
connection-test-query: SELECT 1 FROM DUAL
maximum-pool-size: 20
auto-commit: true
idle-timeout: 30000
pool-name: GHHikariCP
max-lifetime: 120000
connection-timeout: 30000
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: false
###【改造后的数据库连接配置】
spring:
datasource:
## 涉及敏感内容,需要将 IP、端口、数据库名修改成你自己想要的
url: jdbc:kingbase8://127.0.0.1:54321/test_db?useUnicode=true&characterEncoding=UTF-8
## 涉及敏感内容,将数据库用户名、密码修改成你自己想要的
username: system
password: system@123
driver-class-name: com.kingbase8.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 1
connection-test-query: SELECT 1
maximum-pool-size: 20
auto-commit: true
idle-timeout: 30000
pool-name: GHHikariCP
max-lifetime: 120000
connection-timeout: 30000
db-type: postgresql
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:
## 这个配置是用来忽略大小写
map-underscore-to-camel-case: true
## 可选配置,自定义处理类,处理数据库中 Boolean 和 实体类中的 Integer 的类型转换,具体见下文 5.4 内容。
type-handlers-package: com.gh.common.handler.common
(注意:kingbase 的驱动包,在阿里仓库是没有的,需要到官网上下载下来放到本地仓库中,我用的是公司仓库)
<!--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>
(很多 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,'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
即带下划线的数据库表字段对应驼峰命名的实体类字段
-- 对已知表查询前五条数据
修改前:limit 1,5
修改后:limit 0 offset 5
mysql 中的很多函数无法在 kingbase / PostGreSQL 数据库中使用
修改前:update t_device t set t.band_flag = #{bandFlag} where t.id = #{id} ;
修改后:update t_device set band_flag = #{bandFlag} where id = #{id} ;
因为 mysql 的语法对字符串和数值类型做了兼容处理,而 kingbase 是严格区分字符串和数值,所以在遇到一些类型不一致的情况,需要类型转换
-- 已知
SELECT * FROM t_alarm_history h
LEFT JOIN t_gis_config c on c.device_id=d.id or c.device_id :: varchar = CONCAT('cam_',d.id);
-- 已知表命名为 t_device 的情况下,以下为错误实例:
1)@TableName("T_DEVICE")
2)@TableName("tDevice")
3)@TableName("T_device")
不要使用 @TableId(type = IdType.NONE) 注解,否则 id 不会自增长
;即带下划线的数据库表字段对应驼峰命名的实体类字段
--修改前的建表语句:
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 会自动将数据库中带下划线的字段转换成驼峰形式)
Wrapper 中使用的字段,必须要和数据库保持一致,否则会报字段找不到的错误
sql 如下:
--【修改前】
SQL语句:select name as deviceName , id as deviceId from t_device
java代码:Map deviceMap = (Map)deviceMap.get("deviceName");
--【修改后】
SQL语句:select name as devicename , id as deviceid from t_device
java代码:Map deviceMap = (Map)deviceMap.get("devicename");
package com.gh.common.handler.common;
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;
public class BooleanTypeHandler extends BaseTypeHandler<Boolean> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Boolean aBoolean, JdbcType jdbcType) throws SQLException {
if (aBoolean){
ps.setInt(i,1);
}else ps.setInt(i,0);
}
@Override
public Boolean getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
int man = resultSet.getInt(columnName);
return man == 1 ? true : false;
}
@Override
public Boolean getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
int man = resultSet.getInt(columnIndex);
return man == 1 ? true : false;
}
@Override
public Boolean getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
int man = callableStatement.getInt(columnIndex);
return man == 1 ? true : false;
}
}