Oinone连接外部数据源方案

场景描述

在实际业务场景中,有是有这样的需求:链接外部数据进行数据的获取;通常的做法:
1、【推荐】通过集成平台的数据连接器,链接外部数据源进行数据操作;
2、项目代码中链接数据源,即通过程序代码操作外部数据源的数据;

本篇文章只介绍通过程序代码操作外部数据源的方式.

整体方案

  • Oinone管理外部数据源,即yml中配置外部数据源;
  • 后端通过Mapper的方式进行数据操作(增/删/查/改);
  • 调用Mapper接口的时候,指定到外部数据源;

详细步骤

1、数据源配置(application.yml), 与正常的数据源配置一样

    out_ds_name(外部数据源别名):
      driverClassName: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      # local环境配置调整
      url: jdbc:mysql://ip(host):端口/数据库Schema?useSSL=false&allowPublicKeyRetrieval=true&useServerPrepStmts=true&cachePrepStmts=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true
      username: 用户名
      password: 命名
      initialSize: 5
      maxActive: 200
      minIdle: 5
      maxWait: 60000
      timeBetweenEvictionRunsMillis: 60000
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      asyncInit: true

2、外部数据源其他配置
外部数据源限制创建表结构的执行,可以通过配置指定【不创建DB,不创建数据表】

      persistence:
        global:
          auto-create-database: true
          auto-create-table: true
        ds:
          out_ds_name(外部数据源别名):
            # 不创建DB
            auto-create-database: false
            # 不创建数据表
            auto-create-table: false

3、后端写Mapper

  • SQL Mapper跟使用原生mybaits/mybaits-plus写法一样,无特殊限制;
  • Mapper和SQL写到一起,或者分开两个文件都可以

4、Mapper被Service或者Action调用
1)启动的Application中@MapperScan需要扫描到对应的包。
2)调用是与普通bean一样(即调用方式跟传统的方式样),唯一的区别就是加上DsHintApi,即指定Mapper所使用的数据源。

@Autowired
private ScheduleItemMapper scheduleItemMapper;

public saveData(Object data) {
    ScheduleQuery scheduleQuery = new ScheduleQuery();
    //scheduleQuery.setActionName();
    try (DsHintApi dsHint = DsHintApi.use(“外部数据源名称”)) {
        List<ScheduleItem> scheduleItems = scheduleItemMapper.selectListForSerial(scheduleQuery);
        // 具体业务逻辑
    }
}

其他参考:
如何自定义sql语句:https://doc.oinone.top/backend/4759.html

Oinone社区 作者:望闲原创文章,如若转载,请注明出处:https://doc.oinone.top/backend/4562.html

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

Like (2)
望闲's avatar望闲数式管理员
Previous 2024年5月17日 pm2:23
Next 2024年5月17日 pm6:40

相关推荐

  • 低无一体使用 (后端)

    低无一体使用 (后端) 低无一体应用 打开低无一体应用。 选择应用模块 在选择模块选择框中,下拉选择需要使用低无一体的应用模块。 生成SDK 点击生成SDK, 生成当前选择应用模块的低无一体SDK。 点击之后的系统消息 提示"生成SDK成功",表示操作完成。 生成扩展工程 点击下载扩展工程模板, 生成当前选择应用模块的低无一体SDK。 点击之后的系统消息 提示"下载扩展工程模板成功",表示操作完成。 之后刷新页面 下载扩展工程 使用系统消息中的链接或者详情页中的下载地址下载扩展工程 扩展工程结构概览 自定义Action示例 import org.springframework.stereotype.Component; import pro.shushi.oinone.stand.testExt.model.Model0000000001; import pro.shushi.pamirs.meta.annotation.Action; import pro.shushi.pamirs.meta.annotation.Function; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.api.dto.condition.Pagination; import pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper; import pro.shushi.pamirs.meta.constant.FunctionConstants; import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum; import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum; /** * Model0000000001Action * * @author yakir on 2025/01/20 14:59. */ @Component @Model.model(Model0000000001.MODEL_MODEL) public class Model0000000001Action { @Function.Advanced(type = FunctionTypeEnum.QUERY) @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.API}) public Pagination<Model0000000001> queryPage(Pagination<Model0000000001> page, IWrapper<Model0000000001> queryWrapper) { return new Model0000000001().queryPage(page, queryWrapper); } @Action(displayName = "sayHello") @Action.Advanced(type = FunctionTypeEnum.QUERY) public Model0000000001 sayHello(Model0000000001 query) { query.setName(query.getName() + System.currentTimeMillis()); return query; } } 注意事项 ⚠️⚠️⚠️ Oinone底层依赖版本与设计器和业务应用一致 (参考 版本更新日志 ) 扩展工程如需独立启动, 手动修改application.yml中安装模块和pom.xml中模块jar的依赖配置

    2025年2月17日
    1.4K00
  • 元数据表介绍

    模型 模型元数据的讲解 https://doc.oinone.top/oio4/9281.html base_model 模型表 字段名 备注 示例 system_source BASE是系统创建, MANUAL是人工创建 MANUAL pk 主键 id module 模块编码 demo_core model 模型编码 demo.PetType name api名称 petType lname 模型代码名称 pro.shushi.pamirs.demo.api.model.PetType table 逻辑数据表名称 demo_core_pet_type ds_key 逻辑数据源名 pamirs type 模型类型 store display_name 显示名称 品种 data_manager 是否允许系统根据模型变化自动创建表和更新表 1 ordering 排序 createDate DESC, id DESC super_models 父模型 demo.AbstractDemoIdModel uniques 唯一索引 indexes 索引 name,createDate 模块 模块元数据的讲解 https://doc.oinone.top/oio4/9279.html base_module 模块表 字段名 备注 示例 display_name 显示名称 OinoneDemo name api名称 DemoCore module 模块编码 demo_core module_dependencies 依赖模块编码列表 base,common,file,trigger module_exclusions 互斥模块编码列表 module_upstreams 上游模块编码列表 system_source BASE是系统创建, MANUAL是人工创建 MANUAL web web应用 1 default_home_page_model 默认主页模型编码 函数 函数元数据的讲解 https://doc.oinone.top/oio4/9282.html base_function 函数表 字段名 备注 示例 display_name 显示名称 根据条件分页查询记录列表和总数 clazz 函数位置 pro.shushi.pamirs.framework.orm.DefaultReadApi module 模块 demo_core method 函数方法 queryPage namespace 函数命名空间 demo.PetType argument_list 函数参数 [{"ltype":"pro.shushi.pamirs.meta.api.dto.condition.Pagination","model":"base.Pagination","modelGeneric":false,"multi":false,"name":"page","ttype":"m2o"},{"ltype":"pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper","ltypeT":"java.lang.Object","model":"base.Condition","modelGeneric":true,"multi":false,"name":"queryWrapper","ttype":"m2o"}] fun 函数编码 queryPage return_type 返回值类型 {"ltype":"pro.shushi.pamirs.meta.api.dto.condition.Pagination","model":"base.Pagination","modelGeneric":false,"multi":false,"ttype":"m2o"} sys 由系统产生的元数据 1 type 函数类型 1: CREATE, 2: DELETE, 4: UPDATE, 8: QUERY 8 data_manager 数据管理器函数 1 codes 代码内容 open_level 开放级别 2: LOCAL, 4: REMOTE, 8: API, 6: LOCAL+REMOTE, 10: LOCAL+API, 12: REMOTE+API, 14:LOCAL+REMOTE+API 14 模型字段 字段讲解 https://doc.oinone.top/oio4/9239.html base_field 字段表 字段名 备注 示例 system_source BASE是系统创建, MANUAL是人工创建 MANUAL name api名称 name field 字段编码 name ttype 关系类型, 类型:m2o/o2m/m2m/enum/string/integer/map/datetime/related/money/html string model 模型编码…

    2024年8月23日
    1.3K00
  • 重写QueryPage时,增加额外的条件

    在需要对QueryPage增加额外的查询条件,比如DemoItem增加只展示创建人为当前用户的数据 @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "查询列表") @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API}) public Pagination<DemoItem> queryPage(Pagination<DemoItem> page, IWrapper<DemoItem> queryWrapper) { LambdaQueryWrapper<DemoItem> qw = ((QueryWrapper<DemoItem>) queryWrapper).lambda(); qw.eq(DemoItem::getCreateUid, PamirsSession.getUserId()); return demoItemService.queryPage(page, qw); }

    2023年11月1日
    1.1K00
  • 自定义RSQL占位符(placeholder)及在权限中使用

    1 自定义RSQL占位符常用场景 统一的数据权限配置 查询表达式的上下文变量扩展 2 自定义RSQL的模板 /** * 演示Placeholder占位符基本定义 * * @author Adamancy Zhang at 13:53 on 2024-03-24 */ @Component public class DemoPlaceHolder extends AbstractPlaceHolderParser { private static final String PLACEHOLDER_KEY = "${thisPlaceholder}"; /** * 占位符 * * @return placeholder */ @Override public String namespace() { return PLACEHOLDER_KEY; } /** * 占位符替换值 * * @return the placeholder replace to the value */ @Override protected String value() { return PamirsSession.getUserId().toString(); } /** * 优先级 * * @return execution order of placeholders, ascending order. */ @Override public Integer priority() { return 0; } /** * 是否激活 * * @return the placeholder is activated */ @Override public Boolean active() { return true; } } 注意事项 在一些旧版本中,priority和active可能不起作用,为保证升级时不受影响,请保证该属性配置正确。 PLACEHOLDER_KEY变量表示自定义占位符使用的关键字,需按照所需业务场景的具体功能并根据上下文语义正确定义。 为保证占位符可以被正确替换并执行,所有占位符都不应该出现重复,尤其是不能与系统内置的重复。 3 占位符使用时的优先级问题 多个占位符在进行替换时,会根据优先级按升序顺序执行,如需要指定替换顺序,可使用Spring的Order注解对其进行排序。 import org.springframework.core.annotation.Order; @Order(0) 4 Oinone平台内置的占位符 占位符 数据类型 含义 备注 ${currentUser} String 当前用户ID 未登录时无法使用 ${currentRoles} Set<String> 当前用户的角色ID集合 未登录时无法使用 5 如何覆盖平台内置的占位符? 通过指定占位符的优先级,并定义相同的namespace可优先替换。 6 如何定义会话级别的上下文变量? 在上述模板中,我们使用的是Oinone平台内置的上下文变量进行演示,通常情况下,我们需要根据实际业务场景增加上下文变量,以此来实现所需功能。 下面,我们将根据当前用户获取当前员工ID定义该上下文变量进行演示。 /** * 员工Session * * @author Adamancy Zhang at 14:33 on 2024-03-24 */ @Component public class EmployeeSession implements HookBefore { private static final String SESSION_KEY = "CUSTOM_EMPLOYEE_ID"; @Autowired private DemoEmployeeService demoEmployeeService; public static String getEmployeeId() { return PamirsSession.getTransmittableExtend().get(SESSION_KEY);…

    2024年3月24日
    2.0K00
  • 如何扩展自有的文件存储系统

    介绍 数式Oinone默认提供了阿里云、腾讯云、华为云、又拍云、Minio和本地文件存储这几种文件存储系统,如果我们有其他的文件存储系统需要对接,或者是扩展现有的文件系统,可以通过SPI继承AbstractFileClient注册新的文件存储系统。 代码示例 这里以扩展自有的本地文件系统为例 继承了内置的本地文件存储LocalFileClient,将其中上传文件的方法重写 package pro.shushi.pamirs.demo.core.file; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; import pro.shushi.pamirs.framework.connectors.cdn.client.LocalFileClient; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; import pro.shushi.pamirs.meta.common.spi.SPI; import javax.servlet.http.HttpServletRequest; @Slf4j @Component // 注册新的文件存储系统类型 @SPI.Service(DemoLocalFileClient.TYPE) @RestController @RequestMapping("/demo_file") public class DemoLocalFileClient extends LocalFileClient { public static final String TYPE = "DEMO_LOCAL"; @Override public CdnFileForm getFormData(String fileName) { CdnConfig cdnConfig = getCdnConfig(); CdnFileForm fileForm = new CdnFileForm(); String uniqueFileName = Spider.getDefaultExtension(CdnFileNameApi.class).getNewFilename(fileName); String fileKey = getFileKey(cdnConfig.getMainDir(), uniqueFileName); //前端获取uploadUrl,上传文件到该地址 fileForm.setUploadUrl(cdnConfig.getUploadUrl() + "/demo_file/upload"); //上传后,前端将downloadUrl返回给后端 fileForm.setDownloadUrl(getDownloadUrl(fileKey)); fileForm.setFileName(uniqueFileName); Map<String, Object> formDataJson = new HashMap<>(); formDataJson.put("uniqueFileName", uniqueFileName); formDataJson.put("key", fileKey); fileForm.setFormDataJson(JSON.toJSONString(formDataJson)); return fileForm; } @ResponseBody @RequestMapping(value = "/upload", produces = "multipart/form-data;charset=UTF-8",method = RequestMethod.POST) public String uploadFileToLocal(HttpServletRequest request) { MultipartFile file = ((StandardMultipartHttpServletRequest) request).getFile("file"); // 例如可以根据file文件类型判断哪些文件是否可以上传 return super.uploadFileToLocal(request); } } 在application.yml内配置 cdn: oss: name: 本地文件系统 # 这里的type与代码中定义的文件存储系统类型对应 type: DEMO_LOCAL bucket: pamirs uploadUrl: http://127.0.0.1:8190 downloadUrl: http://127.0.0.1:6800 validTime: 3600000 timeout: 600000 active: true referer: localFolderUrl: /Users/demo/workspace/static

    2024年10月24日
    1.0K00

Leave a Reply

Please Login to Comment