背景
随着企业对数据驱动能力的要求不断提高,开发团队需要以更低的成本、更短的周期将数据库中的数据以安全、可管理的 API 形式暴露出来。基于“通过配置 SQL 快速创建数据增删改 API”的能力,能够在很多场景中显著提升效率、降低错误率并强化治理。
- AI 编程与智能应用
- 快速为智能助手、自动化脚本或微服务暴露结构化数据接口,简化API编程和数据应用中的数据接入工作,减少定制开发成本。
- 在数据标注、人机交互、生成式应用中,通过配置 API 提供可追溯、可限制的数据访问,支持实时或批量数据读取/写回。
- 数据集成与ETL
- 快速构建用于数据迁移、同步或集成的增删改 API,支持不同系统间的数据流转(如将业务库数据推送到数据仓库或第三方系统)。
- 支持参数化查询与批量操作,简化定时任务与数据流水线的开发和维护。
- 可作为数据接入层统一管理对外数据接口,便于做数据权限控制与审计。
- 内部工具与业务中台
- 为后台管理系统、运营工具、BI 报表、移动端应用等快速生成标准化的 CRUD 接口,缩短前后端联调周期。
- 通过配置实现字段映射、输入校验与数据变换,减少重复编码,提高一致性与安全性。
- 低代码/无代码与快速原型
- 让非后端开发人员或业务人员通过配置即可生成数据 API,加速原型验证与业务流程自动化落地。
- 支持自动的API文档、示例请求、返回结构定义,降低使用门槛。
在Dataphin 5.4发布前,Dataphin数据服务仅支持查询类API(List、Get),用户需手动编写代码或自定义API来实现增删改操作,存在以下痛点:
- 开发成本高:非开发用户无法自助创建;
- 维护复杂:API分散管理,缺乏统一治理;
- 安全性差:绕过平台权限控制,存在数据风险。
借助 Dataphin 5.4 的新增删改 API 功能,企业可以更加高效地管理和利用数据资源,加速业务创新与发展,充分释放数据的价值。
功能概览
Datpahin提供了数据增删改API的创建能力。增删改API与查询类API不同,通常来说性能相较于查询会更差,并且需要更细颗粒度的事务控制、数据批次控制和错误处理。以下是Dataphin的增删改API的详细功能:
- 可视化创建:用户可以通过可视化界面轻松创建增删改API,降低开发门槛。
- 参数校验与默认值填充:在执行SQL前对参数进行校验,并自动填充默认值,确保数据的完整性和合法性。
- 批量操作:支持单条和批量接口的配置,多条数据操作,可使用批量操作接口,性能更佳。可设置最大数据条数,保护系统。
- 事务控制:支持单条和批量接口的事务处理模式,包括单事务、无事务和分批独立事务,确保数据的一致性和可靠性。
- 错误处理与返回:提供详细的错误处理机制,支持部分成功和全部成功的选项,返回成功和失败的数据详情,便于问题排查。
- 性能优化:针对不同数据量和并发情况,自动进行优化,比如MySQL的批量操作,自动修改JDBC连接
rewriteBatchedStatements的设置以提升性能。 - 权限管理:支持API级别的权限申请,确保数据安全。暂不支持行级权限。
- 限流与告警:同样地,增删改API也支持限流与告警,保障API的稳定运行。
- 多种数据源支持:本期支持MySQL、Oracle、Microsoft SQL Server和PostgreSQL等多种数据源,满足不同用户的数据库需求。
使用示例
在本示例中,我们将创建单条和批量客户增删改查的数据服务API,并给出详细的调用的示例,以便大家可以将参考进行开发。
在本示例中,我们将使用MySQL数据库用于存储客户的详细信息。需要注意的是,mysql本身不支持returning语法,因此新增客户时无法将customer_id返回,因此在本示例中,使用传入customer_id的方式简化。在实际中,需要增加使用业务代理主键(如手机号)查询新增的customer_id。
前置准备
在数据库中创建dim_customers表,可通过navicat等工具进行创建,也可通过Dataphin的数据库SQL进行创建。
CREATE TABLE dim_customers ( customer_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100), email VARCHAR(255), phone VARCHAR(50), dob DATE, gender ENUM('male','female','other','unknown') NOT NULL DEFAULT 'unknown', address TEXT, city VARCHAR(100), state VARCHAR(100), postal_code VARCHAR(20), country VARCHAR(100), status ENUM('active','inactive','deleted') NOT NULL DEFAULT 'active', created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ;
创建增删改查API
升级到Dataphin 5.4后,可以发现API的操作类型新增了Create、Update和Delete(如未出现,则需要购买及开通数据增强操作模块)。
接下来,我们就可以利用Dataphin数据服务创建增删改查的API了。我们可创建单条和批量接口(如下图所示),但本文档中仅给出Create接口创建示例。
CreateCustomer:新增客户
- 新建API,填写API的名称。 API的名称需与业务逻辑一致,并且遵循企业内部的名称规范。
- 操作类型选择“Create”,即插入新的数据记录。
- 数据量选择“单条”,即单条数据操作
- 选择数据源及数据表的名称。可点击“快捷插入”,系统即可生成参考示例。这里我们修改SQL删除Create_at和Update_at的字段,选择由系统自动生成。
BulkCreateCustomer:批量增客户
同单条创建客户类似,但是我们这里数据量的设置我们选择了“批量”,并且设置事务处理方式为“分批处理”,当然我们也可以不分批,以保持整批数据创建的完整性,要不都成功,要不都失败。
批量操作API的其中一个处理单点是错误处理。Dataphin数据服务也进行了细致的支持。
1)错误处理可选择“允许部分成功”或“全部成功才可成功”
2)在返回参数中,可分别配置操作成功时返回的数据和操作失败时返回的数据。一般来说成功操作时,仅可返回主键或者无需返回,而失败时,则需要返回更完整的信息用于定位。比如在失败结果中,我们可以配置输入的参数,而在成功的结果中也配置customer_id(如数据库为PostgreSQL,也可将returning中的字段配置为成功结果的返回值)。
例如,当遇到主键冲突时,插入失败的数据记录将被返回:
按照以上的方式,配置单条/批量Update和Delete接口,以及客户列表和详情的查询接口,关于客户的增删改查的接口就配置完成了。
调用接口
接下来,就可以通过客户端进行API的调用了。以下以Java代码为例。
前置的准备如下:
- 创建应用或使用已有的应用。此处略过
- 申请应用访问API的权限。此处略过
接下来就可以编写客户端代码,调用API了。您可以下载示例代码完整版(本章最后) 。
- 创建Maven/Gradle项目,并引入必要的依赖。并将示例文件复制到项目下。
- 配置数据服务基本信息,包括数据服务的Host(进入 Dataphin - 数据服务-服务管理-网络配置,查看域名 )、应用的AppKey/Secret、增删改API ID
private static final String HOST = "dataphin-dataservice.hostname.com"; // Todo: replace with right host private static final String APP_KEY = "xxxx"; // Todo: replace with right app key private static final String APP_SECRET = "xxxxxxx"; // Todo: replace with right App SecretKey private static final String create_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String update_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String delete_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String get_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String bulk_create_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String bulk_update_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String bulk_delete_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String bulk_get_customer_api_id = "xxx"; // Todo: replace with right API ID
- 执行
CustomerDemo.java类, - 验证调用结果:
- 实时日志:控制台输出调用状态及响应数据
- 运维日志:可进入 Dataphin - 数据服务 - 应用运维 - 调用日志,查看调用的结果。
示例代码(完整版)
package org.example; import com.alibaba.cloudapi.sdk.constant.SdkConstant; import com.alibaba.cloudapi.sdk.enums.Scheme; import com.alibaba.cloudapi.sdk.model.ApiResponse; import com.alibaba.dt.dataphin.client.ApiClient; import com.alibaba.dt.dataphin.client.ApiClientBuilderParams; import com.alibaba.dt.dataphin.schema.ManipulationParamRequest; import com.alibaba.dt.dataphin.schema.OrderBy; import com.alibaba.dt.dataphin.schema.QueryParamRequest; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import javax.crypto.SecretKey; import java.util.*; /** * 同步API示例 * <p> * 使用方式: * 先配置好 HOST/APP_KEY/APP_SECRET/API_ID, * 再按需设置 getClient() 中的变量以及 packQueryParamRequest() 中的参数值。 * 注意: * getClient() 中的参数可能会因不同的 API 而设置不同的值,可以将 getClient() 改造成带有入参,以适应不同 API 使用不同的参数。 */ public class CustomerDemo { /** * 访问域名或ip,在数据服务的网络配置中获得该值 */ private static final String HOST = "dataphin-dataservice.hostname.com"; // Todo: replace with right host /** * 应用appKey,即你用哪个APP来调用这个API */ private static final String APP_KEY = "xxxx"; // Todo: replace with right app key /** * 应用appSecret,即你用哪个APP来调用这个API */ private static final String APP_SECRET = "xxxxxxx"; / Todo: replace with right App SecretKey /** * 配置调用的API编号 */ // private static final String API_ID = "xxx"; private static final String create_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String update_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String delete_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String get_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String bulk_create_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String bulk_update_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String bulk_delete_customer_api_id = "xxx"; // Todo: replace with right API ID private static final String bulk_get_customer_api_id = "xxx"; // Todo: replace with right API ID public static void main(String[] args) throws Exception { // single api test singleCustomerManipulationTest(); // test bulk apis bulkCustomerManipulationTest(); } private static void bulkCustomerManipulationTest() { // test bulk create customers List<Map<String, Object>> customers = new ArrayList<>(); for (int i = 0; i < 20; i++) { Map<String, Object> customer = new HashMap<>(); customer.put("customer_id", i); customer.put("first_name", "John" + i); customer.put("last_name", "Doe" + i); customer.put("email", "john.doe" + i + "@example.com"); customer.put("phone", "+1234567890"); customer.put("dob", "1990-01-01"); customer.put("gender", "male"); customer.put("address", "123 Main St"); customer.put("city", "New York"); customer.put("state", "NY"); customer.put("postal_code", "10001"); customer.put("country", "USA"); customer.put("status", "active"); customers.add(customer); } List<Integer> success_customer_ids = new ArrayList<>(); List<Map<String, Object>> failed_customer_ids = new ArrayList<>(); bulkCreateCustomer(customers, success_customer_ids, failed_customer_ids); if(success_customer_ids != null && success_customer_ids.size() > 0) { bulkGetCustomer(success_customer_ids); } // test bulk update customers List<Map<String, Object>> newCustomers = new ArrayList<>(); List<Integer> success_customer_ids2 = new ArrayList<>(); List<Map<String, Object>> failed_customer_ids2 = new ArrayList<>(); for (int i = 0; i < success_customer_ids.size(); i++) { int customer_id = success_customer_ids.get(i); Map<String, Object> customer = new HashMap<>(); customer.put("customer_id", customer_id); customer.put("first_name", "John" + customer_id + "_"+ customer_id); customer.put("last_name", "Doe"); customer.put("email", "john.doe" + customer_id + "@example.com"); customer.put("phone", "+1234567890"); customer.put("dob", "1990-01-01"); customer.put("gender", "male"); customer.put("address", "123 Main St"); customer.put("city", "New York"); customer.put("state", "NY"); customer.put("postal_code", "10001"); customer.put("country", "USA"); customer.put("status", "active"); newCustomers.add(customer); } bulkUpdateCustomer(newCustomers, success_customer_ids2, failed_customer_ids2); bulkGetCustomer(success_customer_ids2); // delete customers created List<Map<String, Object>> deleteCustomers = new ArrayList<>(); List<Integer> success_customer_ids3 = new ArrayList<>(); List<Map<String, Object>> failed_customer_ids3 = new ArrayList<>(); for (int i = 0; i < 20; i++) { Map<String, Object> customer = new HashMap<>(); customer.put("customer_id", i); deleteCustomers.add(customer); } bulkDeleteCustomer(deleteCustomers, success_customer_ids3, failed_customer_ids3); bulkGetCustomer(success_customer_ids2); } private static void singleCustomerManipulationTest() { int customer_id = 2; // int customer_id = 2; getCustomer(customer_id); System.out.println("create customer\n"); createCustomer(customer_id, "John", "Doe", "john.doe@example.com", "+1234567890", "1990-01-01", "male", "123 Main St", "New York", "NY", "10001", "USA", "active"); getCustomer(customer_id); System.out.println("update customer\n"); updateCustomer(customer_id, "Linda", "Zhu", "lindazhu@example.com", "+1234567890", "1990-01-01", "female", "123 Main St", "New York", "NY", "10001", "USA", "active"); getCustomer(customer_id); System.out.println("delete customer\n"); deleteCustomer(customer_id); getCustomer(customer_id); } public static void createCustomer(int customer_id, String first_name, String last_name, String email, String phone, String dob, String gender, String address, String city, String state, String postal_code, String country, String status) { // 获取 ApiClient 对象 ApiClient client = getClient(); // 按需修改入参信息 ManipulationParamRequest manipulationParamRequest = new ManipulationParamRequest(); Map<String, Object> conditions = new HashMap<>(); conditions.put("customer_id", customer_id); conditions.put("first_name", first_name); conditions.put("last_name", last_name); conditions.put("email", email); conditions.put("phone", phone); conditions.put("dob", dob); conditions.put("gender", gender); conditions.put("address", address); conditions.put("city", city); conditions.put("state", state); conditions.put("postal_code", postal_code); conditions.put("country", country); conditions.put("status", status); manipulationParamRequest.setConditions(conditions); ApiResponse response = client.createSync(create_customer_api_id, manipulationParamRequest); System.out.println(getResultString(response)); } public static void updateCustomer(int customer_id, String first_name, String last_name, String email, String phone, String dob, String gender, String address, String city, String state, String postal_code, String country, String status) { // 获取 ApiClient 对象 ApiClient client = getClient(); // 按需修改入参信息 ManipulationParamRequest manipulationParamRequest = new ManipulationParamRequest(); Map<String, Object> conditions = new HashMap<>(); conditions.put("customer_id", customer_id); conditions.put("first_name", first_name); conditions.put("last_name", last_name); conditions.put("email", email); conditions.put("phone", phone); conditions.put("dob", dob); conditions.put("gender", gender); conditions.put("address", address); conditions.put("city", city); conditions.put("state", state); conditions.put("postal_code", postal_code); conditions.put("country", country); conditions.put("status", status); manipulationParamRequest.setConditions(conditions); ApiResponse response = client.updateSync(update_customer_api_id, manipulationParamRequest); System.out.println(getResultString(response)); } public static void getCustomer(int customer_id) { // 获取 ApiClient 对象 ApiClient client = getClient(); // 需要按需修改里面的返回字段、查询条件等 QueryParamRequest queryParamRequest = new QueryParamRequest(); Map<String, Object> conditions = new HashMap<>(); conditions.put("customer_id", customer_id); queryParamRequest.setConditions(conditions); queryParamRequest.setReturnFields(Arrays.asList( "customer_id", "first_name", "last_name", "email", "phone", "dob", "gender", "address", "city", "state", "postal_code", "country", "status", "created_at", "updated_at" )); List<OrderBy> orderList = new ArrayList<>(); queryParamRequest.setOrderBys(orderList); queryParamRequest.setUseModelCache(false); queryParamRequest.setUseResultCache(false); queryParamRequest.setKeepColumnCase(true); ApiResponse response = client.getSync(get_customer_api_id, queryParamRequest); System.out.println(getResultString(response)); } public static void deleteCustomer(int customer_id) { ApiClient client = getClient(); // 按需修改入参信息 ManipulationParamRequest manipulationParamRequest = new ManipulationParamRequest(); Map<String, Object> conditions = new HashMap<>(); conditions.put("customer_id", customer_id); manipulationParamRequest.setConditions(conditions); ApiResponse response = client.deleteSync(delete_customer_api_id, manipulationParamRequest); System.out.println(getResultString(response)); } public static void bulkCreateCustomer(List<Map<String, Object>> customers, List<Integer> success_customer_ids, List<Map<String, Object>> failed_customer_ids) { ApiClient client = getClient(); // 按需修改入参信息 ManipulationParamRequest manipulationParamRequest = new ManipulationParamRequest(); manipulationParamRequest.setBatchConditions(customers); ApiResponse response = client.createSync(bulk_create_customer_api_id, manipulationParamRequest); // System.out.println(getResultString(response)); // retrieve success ids and failed ids if (response.getCode() == 200) { String resultStr = new String(response.getBody(), SdkConstant.CLOUDAPI_ENCODING); JSONObject jsonObject = JSON.parseObject(resultStr ); if(jsonObject.getString("code").equals("DPN-OLTP-COMMON-000")) { // get successfully created customer list JSONArray successResult = jsonObject.getJSONObject("result").getJSONArray("success"); for (int i = 0; i < successResult.size(); i++) { success_customer_ids.add(successResult.getJSONObject(i).getJSONArray("input").getJSONObject(0).getInteger("customer_id")); } } // get customer list failed to creat JSONArray failedResult = jsonObject.getJSONObject("result").getJSONArray("failed"); for(int i = 0; failedResult!=null && i< failedResult.size();i++) { HashMap<String, Object> failedCustomer = new HashMap<>(); failedCustomer.put("code",failedResult.getJSONObject(i).getString("code")); failedCustomer.put("message",failedResult.getJSONObject(i).getString("message")); failedCustomer.put("first_name",failedResult.getJSONObject(i).getJSONObject("input").getString("first_name")); failed_customer_ids.add(failedCustomer); } } } public static void bulkUpdateCustomer(List<Map<String, Object>> customers, List<Integer> success_customer_ids, List<Map<String, Object>> failed_customer_ids) { ApiClient client = getClient(); // 按需修改入参信息 ManipulationParamRequest manipulationParamRequest = new ManipulationParamRequest(); manipulationParamRequest.setBatchConditions(customers); ApiResponse response = client.updateSync(bulk_update_customer_api_id, manipulationParamRequest); System.out.println(getResultString(response)); JSONObject jsonObject = JSON.parseObject(new String(response.getBody(), SdkConstant.CLOUDAPI_ENCODING)); // retrieve success ids and failed ids if (response.getCode() == 200 && jsonObject.getString("code").equals("DPN-OLTP-COMMON-000")){ JSONArray successResult = jsonObject.getJSONObject("result").getJSONArray("success"); for (int i = 0; i < successResult.size(); i++) { success_customer_ids.add(successResult.getJSONObject(i).getJSONObject("input").getInteger("customer_id")); } } JSONArray failedResult = jsonObject.getJSONObject("result")==null ? null : jsonObject.getJSONObject("result").getJSONArray("failed"); for(int i = 0; failedResult!=null && i< failedResult.size();i++) { HashMap<String, Object> failedCustomer = new HashMap<>(); failedCustomer.put("code",failedResult.getJSONObject(i).getString("code")); failedCustomer.put("message",failedResult.getJSONObject(i).getString("message")); failedCustomer.put("first_name",failedResult.getJSONObject(i).getJSONObject("input").getString("first_name")); failed_customer_ids.add(failedCustomer); } } public static void bulkDeleteCustomer(List<Map<String, Object>> customers, List<Integer> success_customer_ids, List<Map<String, Object>> failed_customer_ids){ ApiClient client = getClient(); // 按需修改入参信息 ManipulationParamRequest manipulationParamRequest = new ManipulationParamRequest(); manipulationParamRequest.setBatchConditions(customers); ApiResponse response = client.deleteSync(bulk_delete_customer_api_id, manipulationParamRequest); System.out.println(getResultString(response)); // retrieve success ids and failed ids if (response.getCode() == 200) { JSONObject jsonObject = JSON.parseObject(new String(response.getBody(), SdkConstant.CLOUDAPI_ENCODING)); if (jsonObject.getString("code").equals("DPN-OLTP-COMMON-000")){ JSONArray successResult = jsonObject.getJSONObject("result").getJSONArray("success"); for (int i = 0; i < successResult.size(); i++) { success_customer_ids.add(successResult.getJSONObject(i).getJSONObject("input").getInteger("customer_id")); } System.out.println("success_customer_ids:"+success_customer_ids); } } } public static void bulkGetCustomer(List<Integer> customer_ids){ ApiClient client = getClient(); QueryParamRequest queryParamRequest = new QueryParamRequest(); Map<String, Object> conditions = new HashMap<>(); conditions.put("customer_ids", customer_ids); // conditions.put("age", Arrays.asList(10, 20, 30)); queryParamRequest.setConditions(conditions); queryParamRequest.setPageSize(10); queryParamRequest.setReturnTotalNum( true); // get 1st batch queryParamRequest.setPageStart(0); queryParamRequest.setReturnFields(Arrays.asList("customer_id","first_name", "last_name", "email", "phone", "dob", "gender", "address", "city", "state", "postal_code", "country", "status")); ApiResponse response = client.listSync(bulk_get_customer_api_id, queryParamRequest); int totalNum = -1; int firstbatchNum = -1; if (response.getCode() == 200) { JSONObject jsonObject = JSON.parseObject(response.getBodyStr()); String resultStr = new String(response.getBody(), SdkConstant.CLOUDAPI_ENCODING); JSONObject resultJson = JSON.parseObject(resultStr ); if(resultJson.getString("code").equals("DPN-OLTP-COMMON-000")) { totalNum = resultJson.getInteger("totalNum"); JSONArray result = resultJson.getJSONArray("results"); if(result!=null && !result.isEmpty()) { firstbatchNum = result.size(); for (int i = 0; i < result.size(); i++) { JSONObject customerJson = result.getJSONObject(i); System.out.println(customerJson.toString()); } } } } for(int i = firstbatchNum; i<totalNum; i+=10){ queryParamRequest.setPageStart(i); ApiResponse tempResponse = client.listSync(bulk_get_customer_api_id, queryParamRequest); System.out.println(getResultString(tempResponse)); } } private static ApiClient getClient() { ApiClientBuilderParams params = new ApiClientBuilderParams(); // 应用appKey params.setAppKey(APP_KEY); // 应用appSecret params.setAppSecret(APP_SECRET); // 访问域名或ip params.setHost(HOST); // 默认为http协议, 可根据API设置https协议 // 注意:Dataphin内置网关不支持https,阿里云网关支持https params.setScheme(Scheme.HTTP); // 访问API的数据环境,生产环境:RELEASE,开发环境:PRE params.setStage("RELEASE"); // 如果使用二级域名或未指定环境的独立域名,需要设置env // 有 PROD 和 PRE 两种值(如果是basic模式,传PROD; 如果是Dev-Prod模式,PROD表示查生产环境数据库,PRE表示查开发环境数据库) // 如果已经指定了访问环境的独立域名,则env参数不会起作用 params.setEnv("PROD"); ApiClient apiClient = new ApiClient(params); // 设置impala数据库类型的超时时间以及轮询间隔(可选,默认超时时间300s,轮询间隔800毫秒) // 参数只对impala有作用,调用非impala的API也要设置,保持默认即可 apiClient.setImpalaTimeoutAndInterval(300, 800); return apiClient; } private static String getResultString(ApiResponse response) { /* * step 1: 获取HttpResponse中头部的详细信息方式 * response.getHeaders().get(key) * 说明:key取值有"date\server\transfer-encoding\keep-alive\vary\connection\content-type\x-ca-request-id\x-ca-error-message\x-ca-error-code" * 如果API调用失败,Headers会有x-ca-error-message(错误信息描述)和x-ca-error-code(网关错误状态码),如果成功则不会存在该信息, * 但是x-ca-request-id(每次请求的唯一标识)始终会有。 * 推荐:如果返回code不是200,可打印出x-ca-error-message\x-ca-error-code以便排查问题 * 强制:使用中需要打印出x-ca-request-id,便于查看日志 * * step 2:下面已经打印出response的详细信息,实际开发中可以根据step1中描述,选择输出相关信息 */ System.out.println("返回结果详细信息: "+ SdkConstant.CLOUDAPI_LF + JSON.toJSONString(response) + SdkConstant.CLOUDAPI_LF); StringBuilder result = new StringBuilder(); result.append("Response from backend server").append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF); result.append("ResultCode:").append(SdkConstant.CLOUDAPI_LF).append(response.getCode()).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF); result.append("RequestId:").append(SdkConstant.CLOUDAPI_LF).append(response.getHeaders().get("x-ca-request-id")).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF); if (200 != response.getCode()) { result.append("ErrorCode:").append(SdkConstant.CLOUDAPI_LF).append(response.getHeaders().get("x-ca-error-code")).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF); result.append("ErrorMessage:").append(SdkConstant.CLOUDAPI_LF).append(response.getHeaders().get("x-ca-error-message")).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF); } result.append("ResultBody:").append(SdkConstant.CLOUDAPI_LF).append(new String(response.getBody(), SdkConstant.CLOUDAPI_ENCODING)); /* * 查看结果 如果状态码不是200,可查看x-ca-error-message报错信息排查问题 * 建议用户保存x-ca-request-id参数,如有异常请提供该参数以便我们排查问题 */ return result.toString(); } }
FAQ
- Q:如何返回自增ID?
A:对于MySQL,需通过业务键(如手机号)查询新记录;对于PostgreSQL,可使用RETURNING语句,并在成功操作的返回结果中增加ID,在调用侧即可获取。 - Q:批量操作失败如何重试?
A:建议在客户端记录失败条目,通过API重试或使用Dataphin的失败重试功能。 - Q:高级SQL模式的性能较差,如何优化?
A:高级SQL由于SQL无法进行预编译,因此性能较差。可根据业务的情况,创建多个简单SQL模式的API,以提升性能。 - Q:该功能支持哪些数据库?
A:支持的数据源包括:MySQL、Oracle、Microsoft SQL Server、PostgreSQL。目前仅开放上述数据库的增删改操作接口,其他数据库将在后续版本中逐步支持。 - Q:批量操作失败如何重试?
A:建议在客户端记录失败条目,重新调用API进行重试。