Springboot -- Mybatis + Mybatis Generate + KingbaseES8(pgsql) + 静态多数据源

news2024/10/6 22:20:20

🏛🏛🏛 以下内容记录一次 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">
			<!--			&lt;!&ndash; 是否去除自动生成的注释 true:是 : false:否 &ndash;&gt;-->
			<!--&lt;!&ndash;			<property name="suppressAllComments" value="true" />&ndash;&gt;-->
			<property name="suppressDate" value="true"/>
		</commentGenerator>
		<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.kingbase8.Driver"
						connectionURL="jdbc:kingbase8://ip:port/test?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT%2B8&amp;allowMultiQueries=true&amp;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生成对应文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/742770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[HDCTF2019]Maze(初识逆向)

下载附件解压&#xff0c;为了方便&#xff0c;我将文件名改为了maze.exe 一般我们先查壳&#xff0c;确实存在UPX壳 对于刚接触逆向的我&#xff0c;一键脱掉哈哈哈 不过还是要说一下&#xff0c;这种脱壳处理有可能会产生其它损坏或者影响&#xff0c;需要进行一定的修复 可…

Visio使用

1.Visio中字母上下标快捷键&#xff1a; 选中要成为上标的文字,ctrlshift"" 选中要成为下标的文字,ctrl"" 2.导入CAD文件 从 AutoCAD 版本 2007 到 2017 导入 .dwg 或 .dxf 文件。 3.编辑CAD文件 右键图形—CAD绘图对象—转换 选择高级 将默认选项改…

居安思危,测试员被裁了还能干什么?

2019年迎来了一大波大佬级公司裁员&#xff0c;包括了阿里、美团、知乎……。它们是各行业的独角兽公司&#xff0c;既是媒体关注的焦点&#xff0c;也是代表了行业风向的指针。 2019年的互联网&#xff0c;已经过了蓬勃发展期&#xff0c;接下来要迎接的更加平稳、规律的发展…

ECM能耗管理云平台

能源是企业运营中不可或缺的要素之一&#xff0c;直接影响企业的成本和竞争力。能源消耗和碳排放不断增长&#xff0c;对环境和可持续发展造成了严重影响。越来越多的企业开始关注并实施能耗管理云平台系统&#xff0c;以实现更高的能源效率、降低碳排放。 ECM能耗管理云平台系…

数分面试题:魔方涂色

问题&#xff1a;现在有一个正方体&#xff0c;现在有6种颜色&#xff0c;给正方体的每一面涂一种颜色&#xff0c;有多少种涂色方法。 注意&#xff01;正方体是可以旋转的&#xff0c;如果旋转正方体之后&#xff0c;涂色效果和另一种涂色效果相同&#xff0c;那么算是一种涂…

车载开发月薪10k与30k的区别,就是CAN总线技术

CAN&#xff08;Controller Area Network&#xff09;总线是一种实时通信协议&#xff0c;是一种广泛应用于车载电子系统中的网络技术。CAN总线技术最初是由德国Bosch公司开发的&#xff0c;用于汽车电子控制系统&#xff08;ECU&#xff09;之间的通信&#xff0c;它能够在车辆…

Linux的shell脚本

Linux的shell脚本 &#x1f607;博主简介&#xff1a;我是一名正在攻读研究生学位的人工智能专业学生&#xff0c;我可以为计算机、人工智能相关本科生和研究生提供排忧解惑的服务。如果您有任何问题或困惑&#xff0c;欢迎随时来交流哦&#xff01;&#x1f604; ✨座右铭&…

Ai数字人浪潮来袭,超写实数字人系统出世,为企业打造定制化服务

数字人概念首次出现在80年代&#xff0c;最初在音乐领域应用&#xff0c;使用手绘技术进行生成。随着时间的推移&#xff0c;传统手绘被CG和动作捕捉等技术取代&#xff0c;从而使虚拟数字人的制作变得更加简化并降低成本。因此&#xff0c;虚拟数字人产业进入产业化探索阶段。…

SpringBoot快速实践 --Ⅰ

文章目录 启动一个SpringBoot项目如何替换内嵌容器玩转SpringBoot配置全局异常处理过滤器拦截器使用Lombok简洁代码使用IDEA HTTP Client进行接口调试 启动一个SpringBoot项目 如果你觉得使用官网来创建太慢了&#xff0c;那你直接把以前项目的依赖粘过来就行了&#xff1a; …

pytorch LBFGS

LBFGS pytorch的LBFGS也是一个优化器 但是与一般的优化器不同 平常我们的顺序是 losscriterion(predict, gt) optim.zero_grad() loss.backward() optim.step()而LBFGS是 def closure():optim.zero_grad()loss criterion(predict, gt)loss.backward()return lossoptim.step…

5.EFLK(ELK+filebeat)+filter过滤

文章目录 EFLK&#xff08;ELKfilebeat&#xff09;部署filebeat修改配置文件logstash配置 logstash的filter过滤grok(正则捕获插件)内置正则表达式调用自定义表达式 mutate(数据修改插件)重命名字段添加字段删除字段转换数据类型替换字段内容以"|"为分割符拆分数据成…

系统升级丨让VR全景制作简单再简单

最高端的VR全景 往往只需要最朴素的制作方式 酷雷曼3D VR数字化升级平台4.0版本 闪耀上线 全新的后台界面 丝滑的编辑工具 无需代码 不用建模 简单拖拉拽移 依然有手就行 轻松搭建VR元宇宙空间 1、界面升级&#xff0c;让VR创作更加可视 全新视觉设计 酷雷曼3D VR…

【必读】未来八大最具潜力行业!看懂就赚了

1 网络安全行业 现在保护“网络安全”已经成为世界各国的重要共识。有专家表示&#xff0c;未来网络安全行业有望超越金融、地产业成最赚钱行业。 2 动漫行业 我国的动漫产业才刚刚起步&#xff0c;现在全国各地如北京、上海、杭州、大连、深圳、广州等城市均建立起动漫产业…

2023年中总结:未到年末,立的Flag就已实现

前言 去年年末&#xff0c;搞了一篇年终总结&#xff0c;立了一个小小的Flag&#xff0c;2023年实现全网粉丝量突破1.5万&#xff0c;可以很负责任的告诉大家&#xff0c;截至到当前&#xff0c;不仅已经实现&#xff0c;而且超额完成&#xff0c;虽然这个量&#xff0c;很低&a…

【目标检测】基于yolov5的道路坑洼检测(附代码和数据集)

写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 路虽远,行则将至;事虽难,做则必成。只要有愚公移山的志气、滴水穿石的毅力,脚踏实地,埋头苦干,积跬步以至千里,就…

《TCP/IP网络编程》第3,4章学习记录

基础知识&#xff1a; struct sockaddr_in {sa_family_t sin_family; //地址族&#xff08;Address Family)uint16_t sin_port; //16位TCP/UDP端口号struct in_addr sin_addr; //32位IP地址char sin_zero[8]; //不使用 }sa_family_t包括&#xff1a; (1)AF_INET,IPv4网络协议…

【Linux】分布式监控 Zabbix

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Zabbix 介绍zabbix 概述Zabbix 监控原理Zabbix 6.0 新特性Zabbix 6.0 功能组件 Zabbix 6.0 部署Zabbix 添加客户端主机Zabbix 自定义监控内容Zabbix 自动发现与自动…

2.1、修改Gitea上传附件大小限制

目录 1. 修改Gitea配置2. 重启服务3. 使用 之前在Gitea上传附件时&#xff0c;显示大小超过3MB&#xff0c;不能符合我的使用场景。记录一下修改这个限制的配置。 1. 修改Gitea配置 默认在安装路径的custom/conf/app.ini文件中&#xff1a; 添加参数 [repository.upload] ; 是…

linux下cuda的安装

linux下cuda的安装 安装cuda11.1和pytorch1.8安装显卡驱动第一个报错第二个报错第三个错误屏幕不显示问题解决方案 安装cuda11.1 安装cuda11.1和pytorch1.8 通过上表可以发现&#xff0c;如果要使用CUDA11.1&#xff0c;那么需要将显卡的驱动更新至455.23或以上&#xff08;Lin…

SpringBoot2+Vue2实战(十六)vue集成视频播放组件

修改文件上传大小限制 servlet:multipart:max-file-size: 100MBmax-request-size: 100MB Video.vue <template><div style"padding: 10px"><el-card><div v-for"item in videos" :key"item.id"style"margin: 10px 0…