【KDB】后端部署使用Kingbase数据库(人大金仓/电科金仓)

KDB数据库配置

驱动配置

Maven配置

点击查看官方驱动说明

PS:官方驱动说明中的9.0.0版本目前并未推送至公共仓库,因此使用8.6.0版本替代。

<kdb.version>8.6.0</kdb.version>

<dependency>
    <groupId>cn.com.kingbase</groupId>
    <artifactId>kingbase8</artifactId>
    <version>${kdb.version}</version>
</dependency>

离线驱动下载

kingbase8-8.6.0.jar

JDBC连接配置

pamirs:
  datasource:
    base:
      type: com.alibaba.druid.pool.DruidDataSource
      driverClassName: com.kingbase8.Driver
      url: jdbc:kingbase8://127.0.0.1:4321/pamirs?currentSchema=base&autosave=always&cleanupSavepoints=true
      username: xxxxxx
      password: xxxxxx
      initialSize: 5
      maxActive: 200
      minIdle: 5
      maxWait: 60000
      timeBetweenEvictionRunsMillis: 60000
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      asyncInit: true
      validConnectionCheckerClassName: com.alibaba.druid.pool.vendor.PGValidConnectionChecker

PS:validConnectionCheckerClassName配置非常重要,连接存活检查是连接池可以保持连接的重要配置。Druid连接池可以自动识别大多数的数据库类型,由于jdbc:kingbase8协议属于非内置识别的类型,因此需要手动配置。

连接url配置

点击查看官方JDBC连接配置说明

url格式
jdbc:kingbase8://${host}:${port}/${database}?currentSchema=${schema}&autosave=always&cleanupSavepoints=true

在jdbc连接配置时,${database}和${schema}必须配置,不可缺省。autosave=always、cleanupSavepoints=true属于必须配置的事务参数,否则事务回滚行为与其他数据库不一致,会导致部分操作失败。

其他连接参数如需配置,可自行查阅相关资料进行调优。

方言配置

pamirs方言配置
pamirs:
  dialect:
    ds:
      base:
        type: KDB
        version: 9
        major-version: V009R001C001B0030
      pamirs:
        type: KDB
        version: 9
        major-version: V009R001C001B0030
数据库版本 type version majorVersion
V009R001C001B0030 KDB 9 V009R001C001B0030
V008R006C008B0020 KDB 9 V009R001C001B0030

PS:由于方言开发环境为V009R001C001B0030版本,其他类似版本原则上不会出现太大差异,如出现其他版本无法正常支持的,可在文档下方留言。

schedule方言配置
pamirs:
  event:
    enabled: true
    schedule:
      enabled: true
      dialect:
        type: PostgreSQL
        version: 14
        major-version: 14.3
type version majorVersion
PostgreSQL 14 14.3

PS:由于schedule的方言与PostgreSQL数据库并无明显差异,Kingbase数据库可以直接使用PostgreSQL数据库方言。

其他配置

逻辑删除的值配置
pamirs:
  mapper:
    global:
      table-info:
        logic-delete-value: (EXTRACT(epoch FROM CURRENT_TIMESTAMP) * 1000000 + EXTRACT(MICROSECONDS FROM CURRENT_TIMESTAMP))::bigint

KDB数据库关键参数检查

PS:以下参数为Oinone平台接入KDB时使用的数据库参数,参数不一致时可尝试启动。

数据库模式

推荐配置:DB_MODE=oracle

数据库安装/初始化时配置

是否大小写敏感

推荐配置:enable_ci=off

是否启用语句级回滚

推荐配置:ora_statement_level_rollback = off

show ora_statement_level_rollback;

set ora_statement_level_rollback=off;

此参数在Oinone平台接入时使用的版本中未体现出应有的效果。从官方提供的文档来看,此参数与数据库连接串上的autosave=always&cleanupSavepoints=true配置结果应该是一致的,由于此参数配置无效,因此在数据库连接串上必须指定这两个参数。

Oinone平台在最初开发时使用的是基于mysql数据库的事务特性,即不支持语句级回滚的事务行为。因此,为了保证Oinone平台功能正常,需要使得事务行为保持一致。

如不一致,则可能出现某些功能无法正常使用的情况。如:流程设计器首次发布定时触发的工作流时会出现报错;导入/导出任务出现异常无法正常更新任务状态等。

是否将空字符串视为NULL

推荐配置:ora_input_emptystr_isnull = off

show ora_input_emptystr_isnull;

set ora_input_emptystr_isnull=off;

KDB数据库用户初始化及授权

-- init root user (user name can be modified by oneself)

CREATE USER root WITH PASSWORD 'password';

-- if using automatic database and schema creation, this is very important.
ALTER USER root CREATEDB;

SELECT * FROM pg_roles;

-- if using kingbase database, this authorization is required.
GRANT CREATE ON DATABASE kingbase TO root;

常用数据库运维脚本

PS:以下脚本在docker容器中可直接执行,其他环境请参考官方部署文档。

# 停止数据库服务
/home/kingbase/install/kingbase/bin/sys_ctl -D /home/kingbase/userdata/data/ stop

# 启动数据服务
/home/kingbase/install/kingbase/bin/sys_ctl -D /home/kingbase/userdata/data/ start

# 修改配置文件后加载配置文件
/home/kingbase/install/kingbase/bin/sys_ctl reload -D  /home/kingbase/userdata/data/

Oinone社区 作者:张博昊原创文章,如若转载,请注明出处:https://doc.oinone.top/install/18659.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (0)
张博昊's avatar张博昊数式管理员
Previous 2024年10月26日 pm2:48
Next 2024年10月29日 pm3:03

相关推荐

  • 如何自定义SQL(Mapper)语句

    场景描述 在实际业务场景中,存在复杂SQL的情况,具体表现为: 单表单SQL满足不了的情况下 有复杂的Join关系或者子查询 复杂SQL的逻辑通过程序逻辑难以实现或实现代价较大 在此情况下,通过原生的mybatis/mybatis-plus, 自定义Mapper的方式实现业务功能 1、编写所需的Mapper SQL Mapper写法无限制,与使用原生的mybaits/mybaits-plus用法一样; Mapper(DAO)和SQL可以写在一个文件中,也分开写在两个文件中。 package pro.shushi.pamirs.demo.core.map; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.util.List; import java.util.Map; @Mapper public interface DemoItemMapper { @Select("<script>select sum(item_price) as itemPrice,sum(inventory_quantity) as inventoryQuantity,categoryId from ${demoItemTable} as core_demo_item ${where} group by category_id</script>") List<Map<String, Object>> groupByCategoryId(@Param("demoItemTable") String pamirsUserTable, @Param("where") String where); } 2.调用mapper 调用Mapper代码示例 package pro.shushi.pamirs.demo.core.map; import com.google.api.client.util.Lists; import org.springframework.stereotype.Component; import pro.shushi.pamirs.demo.api.model.DemoItem; import pro.shushi.pamirs.framework.connectors.data.api.datasource.DsHintApi; import pro.shushi.pamirs.meta.api.core.orm.convert.DataConverter; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.common.spring.BeanDefinitionUtils; import java.util.List; import java.util.Map; @Component public class DemoItemDAO { public List<DemoItem> customSqlDemoItem(){ try (DsHintApi dsHint = DsHintApi.model(DemoItem.MODEL_MODEL)) { String demoItemTable = PamirsSession.getContext().getModelCache().get(DemoItem.MODEL_MODEL).getTable(); DemoItemMapper demoItemMapper = BeanDefinitionUtils.getBean(DemoItemMapper.class); String where = " where status = 'ACTIVE'"; List<Map<String, Object>> dataList = demoItemMapper.groupByCategoryId(demoItemTable,where); DataConverter persistenceDataConverter = BeanDefinitionUtils.getBean(DataConverter.class); return persistenceDataConverter.out(DemoItem.MODEL_MODEL, dataList); } return Lists.newArrayList(); } } 调用Mapper一些说明 启动类需要配置扫描包MapperScan @MapperScan(value = "pro.shushi", annotationClass = Mapper.class) @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, FreeMarkerAutoConfiguration.class}) public class DemoApplication { 调用Mapper接口的时候,需要指定数据源;即上述示例代码中的 DsHintApi dsHint = DsHintApi.model(DemoItem.MODEL_MODEL), 实际代码中使用 try-with-resources语法。 从Mapper返回的结果中获取数据 如果SQL Mapper中已定义了resultMap,调用Mapper(DAO)返回的就是Java对象 如果Mapper返回的是Map<String, Object>,则通过 DataConverter.out进行转化,参考上面的示例 其他参考:Oinone连接外部数据源方案:https://doc.oinone.top/backend/4562.html

    2023年11月27日
    2.3K00
  • 如何选择适合的模型类型?

    介绍 通过Oinone 7天从入门到精通的模型的类型章节我们可以知道模型有抽象模型、存储模型、代理模型、传输模型这四种。但是在在定义模型的时候我们可能不知道该如何选择类型,下面结合业务场景为大家讲解几种模型的典型使用场景。 抽象模型 抽象模型往往是提供公共能力和字段的模型,它本身不会直接用于构建协议和基础设施(如表结构等)。 场景:猫、鸟都继承自动物这个抽象模型 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.annotation.sys.Base; import pro.shushi.pamirs.meta.base.IdModel; import pro.shushi.pamirs.meta.enmu.ModelTypeEnum; @Base @Model.model(AbstractAnimal.MODEL_MODEL) @Model.Advanced(type = ModelTypeEnum.ABSTRACT) @Model(displayName = "动物") public abstract class AbstractAnimal extends IdModel { public static final String MODEL_MODEL = "demo.AbstractAnimal"; @Field.String @Field(displayName = "名称") private String name; @Field.String @Field(displayName = "颜色") private String color; } package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; @Model.model(Cat.MODEL_MODEL) @Model(displayName = "猫") public class Cat extends AbstractAnimal { private static final long serialVersionUID = -5104390780952634397L; public static final String MODEL_MODEL = "demo.Cat"; @Field.Integer @Field(displayName = "尾巴长度") private Integer tailLength; } package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; @Model.model(Bird.MODEL_MODEL) @Model(displayName = "鸟") public class Bird extends AbstractAnimal { private static final long serialVersionUID = -5144390780952634397L; public static final String MODEL_MODEL = "demo.Bird"; @Field.Integer @Field(displayName = "翼展宽度") private Integer wingSpanWidth; } 存储模型 存储模型用于定义数据表结构和数据的增删改查(数据管理器)功能,是直接与连接器进行交互的数据容器。 场景:存储模型对应传统开发模式中的数据表,上面例子中的Cat和Birdd都属于传输模型,由于模型定义的注解@Model.Advanced(type = ModelTypeEnum.STORE)默认值就是存储模型,所以一般不用手动指定 代理模型 代理模型是用于代理存储模型的数据管理器能力,同时又可以扩展出非存储数据信息的交互功能的模型。 场景一:隔离数据权限 场景二:增强列表的搜索项 场景三:导入导出的时候增加其他特殊信息 场景四:重写下拉组件的查询逻辑做数据过滤 传输模型 传输模型不会在数据库生成的表,只是作为数据的传输使用,跟传统开发模式中的DTO有一点相似。 场景一:批量处理数据 场景二:处理一些跟数据表无关的操作,如:清理指定业务的缓存、查看一些系统监控信息,可以根据业务信息建立对应的传输模型,在传输模型上创建action动作 场景三:通过传输模型完成复杂页面数据传输

    2024年4月7日
    1.9K00
  • 如何重写获取首页的方法

    介绍 用户登录成功后或者访问网页不带任何路由参数的时候前端会请求全局的首页的视图动作viewAction配置,然后跳转到该视图动作viewAction 方案 我们可以通过在该方法的后置hook自定义获取首页的逻辑,下面以按角色跳转不同首页的需求示例 package pro.shushi.pamirs.demo.core.hook; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Component; import pro.shushi.pamirs.auth.api.model.AuthRole; import pro.shushi.pamirs.boot.base.enmu.BaseExpEnumerate; import pro.shushi.pamirs.boot.base.model.ViewAction; import pro.shushi.pamirs.boot.web.loader.PageLoadAction; import pro.shushi.pamirs.demo.api.model.DemoItemCategory; import pro.shushi.pamirs.demo.api.model.DemoItemLabel; import pro.shushi.pamirs.meta.annotation.Hook; import pro.shushi.pamirs.meta.api.CommonApiFactory; import pro.shushi.pamirs.meta.api.core.faas.HookAfter; import pro.shushi.pamirs.meta.api.dto.fun.Function; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.common.exception.PamirsException; import pro.shushi.pamirs.user.api.model.PamirsUser; import java.util.List; import java.util.stream.Collectors; @Component public class DemoHomepageHook implements HookAfter { private static final String TEST_ROLE_CODE_01 = "ROLE_1211"; private static final String TEST_ROLE_CODE_02 = "ROLE_1211_1"; @Override @Hook(module = {"base"}, model = {ViewAction.MODEL_MODEL}, fun = {"homepage"}) public Object run(Function function, Object ret) { if (ret == null) { return null; } ViewAction viewAction = getViewActionByCurrentRole(); if (viewAction != null) { ViewAction retNew = CommonApiFactory.getApi(PageLoadAction.class).load(viewAction); ViewAction viewActionRet = (ViewAction) ((Object[]) ret)[0]; viewActionRet.set_d(retNew.get_d()); } return ret; } protected ViewAction getViewActionByCurrentRole() { try { PamirsUser user = new PamirsUser(); user.setId(PamirsSession.getUserId()); user.fieldQuery(PamirsUser::getRoles); List<AuthRole> roles = user.getRoles(); if (CollectionUtils.isNotEmpty(roles)) { List<String> roleCodes = roles.stream().map(AuthRole::getCode).collect(Collectors.toList()); if (roleCodes.contains(TEST_ROLE_CODE_01)) { return new ViewAction().setModel(DemoItemCategory.MODEL_MODEL).setName("DemoMenus_ItemPMenu_DemoItemAndCateMenu_DemoItemCategoryMenu").queryOne(); } else if (roleCodes.contains(TEST_ROLE_CODE_02)) { return new ViewAction().setModel(DemoItemLabel.MODEL_MODEL).setName("DemoMenus_ItemPMenu_DemoItemAndCateMenu_DemoItemLabelMenu").queryOne(); } } } catch (PamirsException exception) { if (PamirsSession.getUserId() == null) { throw PamirsException.construct(BaseExpEnumerate.BASE_USER_NOT_LOGIN_ERROR, exception.getCause()).errThrow(); } else { throw exception; } } return null; } }

    2024年7月6日
    3.2K00
  • 如何排查启动依赖错误的问题

    场景 启动的时候可能会出现以下错误提示 启动模块中包含jar包或者数据库中不存在的模块 启动模块中包含不存在的模块 启动模块互斥模块中包含已安装模块 排查项 确保启动工程的application.yml中的启动模块pamirs.boot.modules配置项内的模块在pom.xml内依赖了对应模块的jar包 确保出问题的模块的定义文件内的包扫描前缀packagePrefix方法内的路径定义正确,该路径可以是多个,但是一定要包含模块下所有子工程的路径,包括但不限于api子工程、core工程等,另外该路径也不能和其他模块的配置有重复、交集、包含关系(例如:a模块是 aa.bb.cc, b模块是aa.bb,这样b模块的路径就包含了a模块的) 启动类里spring自带的@ComponentScan.basePackages注解项需要包含所有依赖模块的路径 无代码应用创建的时候,配置了依赖模块。但这个依赖没有被本地安装,该模块就会出问题,要么删除该依赖,要么在代码里添加该依赖。

    2024年7月18日
    2.3K00

Leave a Reply

Please Login to Comment