🏛🏛🏛 以下内容记录一次 Springboot 项目整和人大金仓数据库的过程 🏛🏛🏛
文章目录
- KingBaseES8
- SpringBoot整合KES8(pgsql)
- 修改pom文件
- 配置多数据源
- 配置文件
- 配置类
- 代码生成器配置
- JsonTypeHandler
- 修改配置文件
- -----------------------------------------------
KingBaseES8
人大金仓数据库管理系统 KingbaseES(KES) 是面向全行业、全客户关键应用的企业级大型通用数据库管理系统,适用于联机事务处理、查询密集型数据仓库、要求苛刻的互联网应用等场景,提供全部应用开发及系统管理功能,提供性能增强特性,可支持主备集群、读写分离集群、多活共享存储集群等全集群架构,具有高性能、高安全、高可用、易使用、易管理、易维护的特点,支持所有国内外主流CPU、操作系统与云平台部署。
KES 可以兼容oracle和pgsql,在安装时可以选择兼容模式。
人大金仓社区地址
个人感觉目前KES的建设还未有其他国外成熟DB系统完善,因此如果在官网查询不到的问题解决方案的时候,可以尝试向KES兼容的数据库方向上做类似考虑。
SpringBoot整合KES8(pgsql)
以下KingBase兼容pgsql
修改pom文件
添加KES 8、Mybatis、MyBatis plus、Mybatis generator 等依赖
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- 其他依赖-->
...
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!-- pgsql-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.1</version>
</dependency>
<!-- kingbase-->
<dependency>
<groupId>cn.com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>8.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
<!-- 设置数据源驱动-->
<dependency>
<groupId>cn.com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>8.6.0</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerVersion>${java.version}</compilerVersion>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
配置多数据源
这里的多数据源配置是静态多数据源
配置文件
application.properties
################# KINGBASE CONFIG #################
spring.datasource.db1.jdbc-url=jdbc:kingbase8://ip:port/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true
spring.datasource.db1.driver-class-name=com.kingbase8.Driver
spring.datasource.db1.username=test
spring.datasource.db1.password=1q2w3e4rmb
spring.datasource.db2.jdbc-url=jdbc:kingbase8://ip2:port2/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true
spring.datasource.db2.driver-class-name=com.kingbase8.Driver
spring.datasource.db2.username=test
spring.datasource.db2.password=1q2w3e4rmb
配置类
db1配置文件,为不同业务的包设置不同的数据源
其中如果在DataSource类型的Bean上设置了@Primary属性,则表示该数据源为默认数据源
@Configuration
@MapperScan(basePackages = "com.xxx.xxx.mapper", sqlSessionFactoryRef = "db1SqlSessionFactory")
public class MybatisDB1Config {
@Bean(name = "db1DataSource")
// 表示这个数据源是默认数据源
@Primary
@ConfigurationProperties(prefix = "spring.datasource.db1")
public DataSource getDateSourceDB1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db1SqlSessionFactory")
@Primary
// @Qualifier表示查找Spring容器中名字为test1DataSource的对象
public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
//解决mapper 返回类型为Map 类型时,如果数据数据为空,则不显示列名的问题。
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
configuration.setCallSettersOnNulls(true);
bean.setConfiguration(configuration);
return bean.getObject();
}
@Bean("db1SqlSessionTemplate")
@Primary
public SqlSessionTemplate db1SqlSessionTemplate(
@Qualifier("db1SqlSessionFactory") SqlSessionFactory sessionFactory) {
return new SqlSessionTemplate(sessionFactory);
}
//写事务时使用,使用事务时必须指定数据源
@Bean(name = "db1TransactionManager")
public DataSourceTransactionManager db1TransactionManager(@Qualifier("db1DataSource") DataSource datasource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(datasource);
return dataSourceTransactionManager;
}
}
@Bean(name = “db1TransactionManager”)用来使用事务时指定数据源,否则编译器会报错
使用时如下@Transactional(“db1TransactionManager”)
代码生成器配置
在POM文件中我们制定了生成器读取配置的文件位置
我们需要将我们生成的表配置一下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="auth" targetRuntime="MyBatis3">
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"></plugin>
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
<commentGenerator type="com.qdeicc.base.db.MyCommentGenerator">
<!-- <!– 是否去除自动生成的注释 true:是 : false:否 –>-->
<!--<!– <property name="suppressAllComments" value="true" />–>-->
<property name="suppressDate" value="true"/>
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.kingbase8.Driver"
connectionURL="jdbc:kingbase8://ip:port/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true&stringtype=unspecified"
userId="test"
password="1q2w3e4rmb">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.xxx.xxx.db.pojo"
targetProject=".\src\main\java\">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.xxx.xxx.db.mapper"
targetProject=".\src\main\java\">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="ANNOTATEDMAPPER"
targetPackage="com.xxx.xxx.db.mapper"
targetProject=".\src\main\java\">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- 指定数据库表 -->
<table schema="" tableName="tb_sys_dict">
<generatedKey column="id" sqlStatement="JDBC" identity="true"/>
</table>
</context>
</generatorConfiguration>
有些时候我们可能会用到数据库中特殊类型的字段
如jsonb,如果不在代码生成配置中做特殊处理,那么我们生成的代码将无法读取或写入此类字段
所以以jsonb类型字段为例,我们创建一个处理器,并在代码生成配置中使用它
JsonTypeHandler
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kingbase8.util.KBobject;
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 JsonTypeHandler<T extends Object> extends BaseTypeHandler<T> {
private static final ObjectMapper mapper = new ObjectMapper();
static {
mapper.configure(JsonParser.Feature.ALLOW_MISSING_VALUES, false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
private Class<T> clazz;
public JsonTypeHandler(Class<T> clazz) {
if (clazz == null) throw new IllegalArgumentException("Type argument cannot be null");
this.clazz = clazz;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
KBobject jsonbObject = new KBobject();
jsonbObject.setType("jsonb");
try {
jsonbObject.setValue(this.toJson(parameter));
} catch (SQLException throwables) {
throwables.printStackTrace();
}
ps.setObject(i, jsonbObject);
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
return this.toObject(rs.getString(columnName), clazz);
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return this.toObject(rs.getString(columnIndex), clazz);
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return this.toObject(cs.getString(columnIndex), clazz);
}
private String toJson(T object) {
try {
return mapper.writeValueAsString(object);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private T toObject(String content, Class<?> clazz) {
if (content != null && !content.isEmpty()) {
try {
return (T) mapper.readValue(content, clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
return null;
}
}
}
修改配置文件
如下,如果我们的jsonb字段中存储的是一个列表,那么我们可以使用以下设置读取出内容。
<table schema="" tableName="tb_sys_role">
<generatedKey column="id" sqlStatement="JDBC" identity="true"/>
<columnOverride column="flag" jdbcType="VARCHAR"
typeHandler="com.xxx.xxx.xxx.typehandler.JsonTypeHandler"
javaType="java.util.List"></columnOverride>
</table>
如此之后,我们就可以直接读取并写入flag字段
要注意在这里我们读取出来的结构是List<Object> 或者List<Map> 的格式,需要自己转换实体类。
也可以在生成代码时直接指定对应实体类类型,配置方法会复杂一些,后面会在开一篇文章记录一下。
-----------------------------------------------
至此,整合KingbaseES8的步骤就结束了,并可以mybatis-generator生成对应文件