datai/datai-scenes/datai-scene-salesforce/docs/reference-code/datai-salesforce-common模块详细文档.md

32 KiB
Raw Permalink Blame History

datai-salesforce-common 模块详细文档

模块概述

基本信息

  • 模块名称: datai-salesforce-common
  • 模块类型: 通用工具模块
  • 版本: 1.0.0
  • Java 版本: 22
  • 编码: UTF-8

功能描述

datai-salesforce-common 模块是 Salesforce 集成体系的通用工具模块,提供常量定义、工具类、数据转换、异常处理等基础功能。该模块被其他所有 Salesforce 相关模块依赖,是整个体系的基础设施层。

核心特性

  1. 常量管理:统一的 Salesforce 相关常量定义
  2. SOQL 构建:强大的 SOQL 查询构建器
  3. 数据转换Salesforce 数据类型转换工具
  4. 异常处理:完善的异常体系
  5. 参数封装:统一的参数封装类
  6. 工具方法:丰富的工具方法集合

模块架构

整体架构图

┌─────────────────────────────────────────────────────────────────┐
│                    datai-salesforce-common                      │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │              常量层Constants                        │  │
│  │  SalesforceConstants | ConfigConstants | Connection   │  │
│  └─────────────────────────────────────────────────────────┘  │
│                           │                                     │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │              工具层Utils                            │  │
│  │  SoqlBuilder | SoqlUtil | ApiListUtils | FileValidation│  │
│  │  IdUtils | ValidationUtils | BooleanConverter           │  │
│  └─────────────────────────────────────────────────────────┘  │
│                           │                                     │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │              转换层Converters                        │  │
│  │  SalesforceDataTypeConverter                            │  │
│  └─────────────────────────────────────────────────────────┘  │
│                           │                                     │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │              参数层Params                            │  │
│  │  SalesforceParam | SalesforceStockParam                 │  │
│  │  SalesforceIncrementParam                               │  │
│  └─────────────────────────────────────────────────────────┘  │
│                           │                                     │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │              异常层Exceptions                        │  │
│  │  SalesforceAuthException | SalesforceLoginException      │  │
│  │  SalesforceOAuthException | FileUploadException          │  │
│  │  ... (30+ 异常类)                                       │  │
│  └─────────────────────────────────────────────────────────┘  │
│                           │                                     │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │              枚举层Enums                             │  │
│  │  FileObjectType                                         │  │
│  └─────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

分层说明

1. 常量层

负责统一管理 Salesforce 相关常量,包括 API 版本、连接端点、HTTP 方法、日期格式等。

2. 工具层

提供各种工具方法,包括 SOQL 查询构建、文件验证、ID 处理、数据验证等。

3. 转换层

负责数据类型转换,特别是 Salesforce 特有的数据类型转换。

4. 参数层

封装各种业务参数,提供统一的参数传递方式。

5. 异常层

定义完善的异常体系,覆盖各种业务场景。

6. 枚举层

定义业务枚举,提供类型安全的常量定义。

核心组件详解

1. SalesforceConstants常量类

类路径: com.datai.common.constant.SalesforceConstants

功能描述 统一管理 Salesforce 相关常量,按照功能模块分类,便于维护和使用。

主要常量分类

API 版本常量

// REST API 版本
public static final String REST_API_VERSION = "v59.0";

// Bulk API v1 版本
public static final String BULK_V1_API_VERSION = "47.0";

// Bulk API v2 版本
public static final String BULK_V2_API_VERSION = "v59.0";

连接端点常量

// REST API 端点后缀
public static final String REST_ENDPOINT_SUFFIX = "/services/data/";

// Bulk API v1 端点后缀
public static final String BULK_V1_ENDPOINT_SUFFIX = "/services/async/";

// Bulk API v2 端点后缀
public static final String BULK_V2_ENDPOINT_SUFFIX = "/services/data/v59.0/jobs/";

// SOAP API 端点后缀
public static final String SOAP_ENDPOINT_SUFFIX = "/services/Soap/u/59.0/";

连接类型常量

// 连接类型 - SOAP
public static final String CONNECTION_TYPE_SOAP = "SOAP";

// 连接类型 - REST
public static final String CONNECTION_TYPE_REST = "REST";

// 连接类型 - Bulk API v1
public static final String CONNECTION_TYPE_BULK_V1 = "BULK_V1";

// 连接类型 - Bulk API v2
public static final String CONNECTION_TYPE_BULK_V2 = "BULK_V2";

HTTP 相关常量

// HTTP 方法
public static final String HTTP_METHOD_GET = "GET";
public static final String HTTP_METHOD_POST = "POST";
public static final String HTTP_METHOD_PUT = "PUT";
public static final String HTTP_METHOD_PATCH = "PATCH";
public static final String HTTP_METHOD_DELETE = "DELETE";

// 内容类型
public static final String CONTENT_TYPE_JSON = "application/json";
public static final String CONTENT_TYPE_CSV = "text/csv";
public static final String CONTENT_TYPE_XML = "application/xml";

// 授权头
public static final String AUTH_HEADER_NAME = "Authorization";
public static final String AUTH_HEADER_PREFIX = "Bearer ";

日期格式常量

// Salesforce 日期时间格式
public static final String SF_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

// Salesforce 日期格式
public static final String SF_DATE_ONLY_FORMAT = "yyyy-MM-dd";

// Salesforce 时间格式
public static final String SF_TIME_FORMAT = "HH:mm:ss.SSS'Z'";

批次处理常量

// 大批次大小(外层批次)
public static final int LARGE_BATCH_SIZE = 10000;

// 小批次大小API 调用批次)
public static final int SMALL_BATCH_SIZE = 200;

// 批次间休眠时间(毫秒)
public static final long BATCH_SLEEP_MS = 1L;

// 日志输出间隔
public static final int LOG_OUTPUT_INTERVAL = 10;

重试相关常量

// 最大重试次数
public static final int MAX_RETRY_COUNT = 3;

// 重试延迟时间(毫秒)
public static final long RETRY_DELAY_MS = 1000L;

2. SoqlBuilderSOQL 查询构建器)

类路径: com.datai.common.utils.SoqlBuilder

功能描述 强大的 SOQL 查询构建器,支持复杂查询条件,采用链式调用方式,提供类型安全的查询构建。

SOQL 语法限制

  1. 不支持 SELECT *,必须明确指定字段或使用 FIELDS()
  2. 不支持 BETWEEN 运算符,请使用 >= 和 <= 组合代替
  3. 不支持 JOIN使用关系查询Relationship Queries如 Account.Name
  4. 不支持 UNION无法合并两个不相关的结果集
  5. 查询最多返回 50000 条记录
  6. OFFSET 上限为 2000且必须与 LIMIT 一起使用
  7. 支持的运算符:=, !=, >, >=, <, <=, LIKE, IN, NOT IN, = NULL, != NULL
  8. 支持的子句WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET

核心方法

SELECT 子句

// 设置 SELECT 子句
public SoqlBuilder select(String... fields)

// 示例
SoqlBuilder builder = new SoqlBuilder()
    .select("Id", "Name", "Account.Name", "CreatedDate");

FROM 子句

// 设置 FROM 子句
public SoqlBuilder from(String object)

// 示例
SoqlBuilder builder = new SoqlBuilder()
    .from("Contact");

WHERE 子句

// 添加 WHERE 子句
public SoqlBuilder where(String clause)

// 添加等于条件
public SoqlBuilder whereEq(String field, Object value)

// 添加不等于条件
public SoqlBuilder whereNe(String field, Object value)

// 添加大于条件
public SoqlBuilder whereGt(String field, Object value)

// 添加大于等于条件
public SoqlBuilder whereGe(String field, Object value)

// 添加小于条件
public SoqlBuilder whereLt(String field, Object value)

// 添加小于等于条件
public SoqlBuilder whereLe(String field, Object value)

// 添加 IN 条件
public SoqlBuilder whereIn(String field, List<Object> values)

// 添加 NOT IN 条件
public SoqlBuilder whereNotIn(String field, List<Object> values)

// 添加 LIKE 条件
public SoqlBuilder whereLike(String field, String value)

// 添加 NOT LIKE 条件
public SoqlBuilder whereNotLike(String field, String value)

// 添加 = NULL 条件
public SoqlBuilder whereIsNull(String field)

// 添加 != NULL 条件
public SoqlBuilder whereIsNotNull(String field)

// 示例
SoqlBuilder builder = new SoqlBuilder()
    .whereEq("Status", "Active")
    .whereGt("Amount", 1000)
    .whereIn("Type", Arrays.asList("Customer", "Partner"))
    .whereLike("Name", "John%");

ORDER BY 子句

// 添加 ORDER BY 子句
public SoqlBuilder orderBy(String field, SortOrder direction)

// 示例
SoqlBuilder builder = new SoqlBuilder()
    .orderBy("CreatedDate", SortOrder.DESC)
    .orderBy("Name", SortOrder.ASC);

GROUP BY 子句

// 添加 GROUP BY 子句
public SoqlBuilder groupBy(String... fields)

// 示例
SoqlBuilder builder = new SoqlBuilder()
    .groupBy("Account.Name", "Status");

HAVING 子句

// 添加 HAVING 子句
public SoqlBuilder having(String clause)

// 示例
SoqlBuilder builder = new SoqlBuilder()
    .having("COUNT(Id) > 10");

LIMIT 和 OFFSET 子句

// 设置 LIMIT 子句
public SoqlBuilder limit(int limit)

// 设置 OFFSET 子句
public SoqlBuilder offset(int offset)

// 示例
SoqlBuilder builder = new SoqlBuilder()
    .limit(100)
    .offset(50);

构建查询

// 构建 SOQL 查询语句
public String build()

// 构建 COUNT 查询语句
public String buildCountQuery()

// 示例
String soql = new SoqlBuilder()
    .select("Id", "Name", "Account.Name", "CreatedDate")
    .from("Contact")
    .whereEq("Status", "Active")
    .whereGt("Amount", 1000)
    .orderBy("CreatedDate", SortOrder.DESC)
    .limit(100)
    .build();

完整示例

// 简单查询
String soql1 = new SoqlBuilder()
    .select("Id", "Name")
    .from("Account")
    .whereEq("Status", "Active")
    .orderBy("Name", SortOrder.ASC)
    .limit(10)
    .build();
// 生成: SELECT Id, Name FROM Account WHERE Status = 'Active' ORDER BY Name ASC LIMIT 10

// 复杂查询
String soql2 = new SoqlBuilder()
    .select("Id", "Name", "Account.Name", "TotalAmount", "CreatedDate")
    .from("Opportunity")
    .whereEq("StageName", "Closed Won")
    .whereGe("CloseDate", "2024-01-01")
    .whereIn("Type", Arrays.asList("New Customer", "Existing Customer"))
    .orderBy("TotalAmount", SortOrder.DESC)
    .limit(50)
    .build();
// 生成: SELECT Id, Name, Account.Name, TotalAmount, CreatedDate 
//      FROM Opportunity 
//      WHERE StageName = 'Closed Won' 
//      AND CloseDate >= '2024-01-01' 
//      AND Type IN ('New Customer', 'Existing Customer') 
//      ORDER BY TotalAmount DESC 
//      LIMIT 50

// COUNT 查询
String countSoql = new SoqlBuilder()
    .select("Id", "Name")
    .from("Account")
    .whereEq("Status", "Active")
    .buildCountQuery();
// 生成: SELECT count(Id) FROM Account WHERE Status = 'Active'

3. SalesforceDataTypeConverter数据类型转换器

类路径: com.datai.common.converter.SalesforceDataTypeConverter

功能描述 Salesforce 特定数据类型转换工具处理日期时间转换、ID 格式转换等。

核心方法

日期时间转换

// 将 Salesforce 日期时间字符串转换为 Date 对象
public Date convertToDate(String dateTimeString)

// 将 Date 对象转换为 Salesforce 日期时间字符串
public String convertToString(Date date)

// 将 Date 对象转换为 Salesforce 日期字符串
public String convertToDateString(Date date)

// 示例
SalesforceDataTypeConverter converter = new SalesforceDataTypeConverter();

// 转换为 Date
Date date = converter.convertToDate("2024-01-15T10:30:00.000Z");

// 转换为字符串
String dateTimeStr = converter.convertToString(new Date());
String dateStr = converter.convertToDateString(new Date());

ID 格式转换

// 将 Salesforce ID 转换为 15 位格式
public String to15CharId(String salesforceId)

// 将 Salesforce ID 转换为 18 位格式
public String to18CharId(String salesforceId)

// 示例
String id18 = converter.to18CharId("001xx000003DHb2AAG");
String id15 = converter.to15CharId("001xx000003DHb2AAG");

时区支持

// 使用默认时区UTC
SalesforceDataTypeConverter converter1 = new SalesforceDataTypeConverter();

// 使用自定义时区
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
SalesforceDataTypeConverter converter2 = new SalesforceDataTypeConverter(zoneId);

4. SalesforceParam参数封装类

类路径: com.datai.common.param.SalesforceParam

功能描述 封装 Salesforce 查询参数,提供统一的参数传递方式。

主要字段

字段名 类型 说明
api String 查询对象 API 名称
select String 查询字段
beginDate Date 开始日期
endDate Date 结束日期
beginCreateDate Date 开始创建日期
endCreateDate Date 结束创建日期
beginModifyDate Date 开始修改日期
endModifyDate Date 结束修改日期
maxId String 最大 ID
idField String ID 字段名(默认为 "Id"
dateField String 日期字段名(默认为 "CreatedDate"
sql String 自定义 SQL
batchId Integer 批次 ID
isDeleted Boolean 是否逻辑删除
limit Integer 查询限制数量
isSingleThread Boolean 是否单线程(默认为 false

使用示例

SalesforceParam param = new SalesforceParam();
param.setApi("Account");
param.setSelect("Id, Name, CreatedDate");
param.setBeginCreateDate(startDate);
param.setEndCreateDate(endDate);
param.setLimit(100);

5. FileObjectType文件对象类型枚举

类路径: com.datai.common.enums.FileObjectType

功能描述 定义 Salesforce 文件对象类型,提供文件上传相关的元数据。

枚举值

枚举值 API 名称 描述 最大大小 推荐 上传方法 必需字段
ATTACHMENT Attachment 传统附件对象(已弃用) 50 MB 仅兼容旧系统 REST API (JSON + Base64) ParentId, Name, Body
CONTENT_DOCUMENT ContentDocument 现代文件对象 2048 MB 强烈推荐 REST API (Multipart/form-data) Title, PathOnClient, VersionData
DOCUMENT Document 文档对象 25 MB 仅用于特定遗留功能 Partner API (SOAP) FolderId, Name, Body

使用示例

// 获取枚举
FileObjectType type = FileObjectType.fromApiName("ContentDocument");

// 获取属性
String apiName = type.getApiName();           // "ContentDocument"
int maxSizeMB = type.getMaxSizeMB();           // 2048
long maxSizeBytes = type.getMaxSizeBytes();   // 2147483648
String recommendation = type.getRecommendation(); // "强烈推荐"

6. 异常体系

异常层次结构

SalesforceAuthException认证异常基类
├── SalesforceLoginException登录异常
├── SalesforceLegacyCredentialLoginException传统凭证登录异常
├── SalesforceOAuthExceptionOAuth 异常)
├── SalesforceSessionIdLoginExceptionSession ID 登录异常)
└── SalesforceCliLoginExceptionCLI 登录异常)

SalesforceLoginException登录异常
├── PasswordExpiredException密码过期异常
└── NotLoggedInException未登录异常

FileUploadException文件上传异常
├── FileSizeExceededException文件大小超出限制异常
├── FileTypeNotSupportedException文件类型不支持异常
├── FileObjectNotFoundException文件对象未找到异常
└── FileValidationException文件验证异常

SalesforceOperationException操作异常
├── ExtractException提取异常
├── LoadException加载异常
└── ...

DataAccessException数据访问异常
├── DataAccessObjectException数据访问对象异常
├── DataAccessRowException数据访问行异常
└── ...

ConfigException配置异常
├── ConfigInitializationException配置初始化异常
├── OrgConfigNotFoundException组织配置未找到异常
└── ...

主要异常类

SalesforceAuthException

// Salesforce 认证异常基类
public class SalesforceAuthException extends RuntimeException {
    private String errorCode;
    
    public SalesforceAuthException(String errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
    }
    
    public String getErrorCode() {
        return errorCode;
    }
}

SalesforceLoginException

// Salesforce 登录异常
public class SalesforceLoginException extends SalesforceAuthException {
    public SalesforceLoginException(String message) {
        super(message);
    }
    
    public SalesforceLoginException(String errorCode, String message) {
        super(errorCode, message);
    }
}

FileUploadException

// 文件上传异常
public class FileUploadException extends RuntimeException {
    private FileErrorCode errorCode;
    
    public FileUploadException(FileErrorCode errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
    }
    
    public FileErrorCode getErrorCode() {
        return errorCode;
    }
}

使用示例

// 抛出登录异常
throw new SalesforceLoginException("LOGIN_FAILED", "登录失败,请检查用户名和密码");

// 抛出文件上传异常
throw new FileUploadException(FileErrorCode.FILE_SIZE_EXCEEDED, "文件大小超出限制");

// 捕获异常
try {
    // 执行登录
} catch (SalesforceLoginException e) {
    String errorCode = e.getErrorCode();
    String message = e.getMessage();
    // 处理异常
}

依赖关系

Maven 依赖

<dependencies>
    <!-- datai-common通用工具模块 -->
    <dependency>
        <groupId>com.datai</groupId>
        <artifactId>datai-common</artifactId>
    </dependency>

    <!-- commons-beanutilsBean 工具 -->
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.9.4</version>
    </dependency>

    <!-- force-wscForce Web Service Connector -->
    <dependency>
        <groupId>com.force.api</groupId>
        <artifactId>force-wsc</artifactId>
        <version>61.0.0</version>
    </dependency>

    <!-- hutool-allHutool 工具包 -->
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.22</version>
    </dependency>

    <!-- fastjson2JSON 处理 -->
    <dependency>
        <groupId>com.alibaba.fastjson2</groupId>
        <artifactId>fastjson2</artifactId>
        <version>2.0.60</version>
    </dependency>
</dependencies>

模块依赖

被依赖的模块

  • datai-salesforce-auth使用常量、异常、工具类
  • datai-salesforce-partner使用常量、参数、工具类
  • datai-salesforce-apex使用常量、参数、工具类
  • datai-salesforce-metadata使用常量、参数、工具类
  • datai-salesforce-tooling使用常量、参数、工具类

依赖的模块

  • datai-common通用工具模块

使用示例

示例 1使用 SoqlBuilder 构建查询

// 简单查询
String soql1 = new SoqlBuilder()
    .select("Id", "Name", "CreatedDate")
    .from("Account")
    .whereEq("Status", "Active")
    .orderBy("CreatedDate", SortOrder.DESC)
    .limit(10)
    .build();

// 复杂查询
String soql2 = new SoqlBuilder()
    .select("Id", "Name", "Account.Name", "TotalAmount", "StageName")
    .from("Opportunity")
    .whereEq("StageName", "Closed Won")
    .whereGe("CloseDate", "2024-01-01")
    .whereIn("Type", Arrays.asList("New Customer", "Existing Customer"))
    .whereLike("Name", "Project%")
    .orderBy("TotalAmount", SortOrder.DESC)
    .limit(50)
    .build();

// COUNT 查询
String countSoql = new SoqlBuilder()
    .select("Id")
    .from("Account")
    .whereEq("Status", "Active")
    .buildCountQuery();

示例 2使用 SalesforceDataTypeConverter

// 创建转换器(使用默认时区)
SalesforceDataTypeConverter converter = new SalesforceDataTypeConverter();

// 日期时间转换
Date date = converter.convertToDate("2024-01-15T10:30:00.000Z");
String dateTimeStr = converter.convertToString(date);
String dateStr = converter.convertToDateString(date);

// ID 格式转换
String id18 = converter.to18CharId("001xx000003DHb2AAG");
String id15 = converter.to15CharId("001xx000003DHb2AAG");

// 使用自定义时区
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
SalesforceDataTypeConverter converter2 = new SalesforceDataTypeConverter(zoneId);

示例 3使用 SalesforceParam

// 创建参数对象
SalesforceParam param = new SalesforceParam();
param.setApi("Account");
param.setSelect("Id, Name, CreatedDate, LastModifiedDate");
param.setBeginCreateDate(startDate);
param.setEndCreateDate(endDate);
param.setLimit(100);
param.setIsDeleted(false);

// 使用参数构建查询
String soql = new SoqlBuilder()
    .select(param.getSelect().split(",\\s*"))
    .from(param.getApi())
    .whereGe(param.getDateField(), param.getBeginCreateDate())
    .whereLe(param.getDateField(), param.getEndCreateDate())
    .whereEq("IsDeleted", param.getIsDeleted())
    .limit(param.getLimit())
    .build();

示例 4使用 FileObjectType

// 获取文件对象类型
FileObjectType type = FileObjectType.fromApiName("ContentDocument");

// 获取文件对象属性
String apiName = type.getApiName();                    // "ContentDocument"
String description = type.getDescription();            // "现代文件对象"
int maxSizeMB = type.getMaxSizeMB();                    // 2048
long maxSizeBytes = type.getMaxSizeBytes();            // 2147483648
String recommendation = type.getRecommendation();       // "强烈推荐"
String uploadMethod = type.getUploadMethod();          // "REST API (Multipart/form-data)"
String requiredFields = type.getRequiredFields();      // "Title, PathOnClient, VersionData"

// 验证文件大小
long fileSize = 1024 * 1024 * 500; // 500 MB
if (fileSize > type.getMaxSizeBytes()) {
    throw new FileUploadException(FileErrorCode.FILE_SIZE_EXCEEDED, 
        "文件大小超出限制,最大允许 " + type.getMaxSizeMB() + " MB");
}

示例 5使用异常类

// 抛出登录异常
try {
    // 执行登录
    if (loginResult == null || !loginResult.isSuccess()) {
        throw new SalesforceLoginException("LOGIN_FAILED", "登录失败,请检查用户名和密码");
    }
} catch (SalesforceLoginException e) {
    String errorCode = e.getErrorCode();
    String message = e.getMessage();
    // 处理异常
    logger.error("登录失败: errorCode={}, message={}", errorCode, message);
}

// 抛出文件上传异常
try {
    // 上传文件
    if (fileSize > maxSize) {
        throw new FileUploadException(FileErrorCode.FILE_SIZE_EXCEEDED, 
            "文件大小超出限制,最大允许 " + maxSize + " MB");
    }
} catch (FileUploadException e) {
    FileErrorCode errorCode = e.getErrorCode();
    String message = e.getMessage();
    // 处理异常
    logger.error("文件上传失败: errorCode={}, message={}", errorCode, message);
}

// 抛出操作异常
try {
    // 执行操作
    if (operationResult == null) {
        throw new SalesforceOperationException("OPERATION_FAILED", "操作失败");
    }
} catch (SalesforceOperationException e) {
    String errorCode = e.getErrorCode();
    String message = e.getMessage();
    // 处理异常
    logger.error("操作失败: errorCode={}, message={}", errorCode, message);
}

示例 6使用常量

// 使用 API 版本常量
String restApiVersion = SalesforceConstants.REST_API_VERSION;           // "v59.0"
String bulkV1ApiVersion = SalesforceConstants.BULK_V1_API_VERSION;         // "47.0"
String bulkV2ApiVersion = SalesforceConstants.BULK_V2_API_VERSION;         // "v59.0"

// 使用端点常量
String restEndpointSuffix = SalesforceConstants.REST_ENDPOINT_SUFFIX;     // "/services/data/"
String bulkV1EndpointSuffix = SalesforceConstants.BULK_V1_ENDPOINT_SUFFIX; // "/services/async/"
String bulkV2EndpointSuffix = SalesforceConstants.BULK_V2_ENDPOINT_SUFFIX; // "/services/data/v59.0/jobs/"

// 使用连接类型常量
String soapConnectionType = SalesforceConstants.CONNECTION_TYPE_SOAP;     // "SOAP"
String restConnectionType = SalesforceConstants.CONNECTION_TYPE_REST;     // "REST"
String bulkV1ConnectionType = SalesforceConstants.CONNECTION_TYPE_BULK_V1; // "BULK_V1"
String bulkV2ConnectionType = SalesforceConstants.CONNECTION_TYPE_BULK_V2; // "BULK_V2"

// 使用 HTTP 方法常量
String httpGet = SalesforceConstants.HTTP_METHOD_GET;                     // "GET"
String httpPost = SalesforceConstants.HTTP_METHOD_POST;                   // "POST"

// 使用内容类型常量
String contentTypeJson = SalesforceConstants.CONTENT_TYPE_JSON;           // "application/json"
String contentTypeCsv = SalesforceConstants.CONTENT_TYPE_CSV;             // "text/csv"

// 使用日期格式常量
String sfDateFormat = SalesforceConstants.SF_DATE_FORMAT;                 // "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
String sfDateOnlyFormat = SalesforceConstants.SF_DATE_ONLY_FORMAT;         // "yyyy-MM-dd"

// 使用批次处理常量
int largeBatchSize = SalesforceConstants.LARGE_BATCH_SIZE;                 // 10000
int smallBatchSize = SalesforceConstants.SMALL_BATCH_SIZE;                 // 200
long batchSleepMs = SalesforceConstants.BATCH_SLEEP_MS;                   // 1L

// 使用重试常量
int maxRetryCount = SalesforceConstants.MAX_RETRY_COUNT;                  // 3
long retryDelayMs = SalesforceConstants.RETRY_DELAY_MS;                    // 1000L

最佳实践

1. 使用 SoqlBuilder 构建查询

  • 始终使用 SoqlBuilder 构建 SOQL 查询,不要手动拼接字符串
  • 利用链式调用提高代码可读性
  • 使用类型安全的方法(如 whereEq、whereGt而不是手动拼接条件
  • 注意 SOQL 的限制(如最多返回 50000 条记录OFFSET 上限为 2000

2. 使用 SalesforceDataTypeConverter 进行数据转换

  • 始终使用 SalesforceDataTypeConverter 进行日期时间转换
  • 注意时区问题,根据需要设置正确的时区
  • 使用 to18CharId 和 to15CharId 进行 ID 格式转换

3. 使用 SalesforceParam 封装参数

  • 使用 SalesforceParam 封装查询参数,提高代码可维护性
  • 设置合理的默认值(如 idField、dateField
  • 注意参数验证,防止无效参数

4. 使用 FileObjectType 处理文件上传

  • 优先使用 ContentDocument现代文件对象
  • 注意文件大小限制,上传前验证文件大小
  • 使用枚举获取文件对象的元数据

5. 使用异常类处理错误

  • 使用合适的异常类,不要使用通用的 RuntimeException
  • 提供清晰的错误码和错误消息
  • 在合适的层级捕获和处理异常

6. 使用常量避免魔法值

  • 使用 SalesforceConstants 中的常量,不要硬编码字符串
  • 保持常量的可读性和可维护性
  • 按功能模块分类组织常量

常见问题

Q1SoqlBuilder 支持 SELECT * 吗?

A不支持。SOQL 不支持 SELECT *,必须明确指定查询字段或使用 FIELDS()。

Q2SoqlBuilder 支持 BETWEEN 运算符吗?

A不支持。请使用 >= 和 <= 组合代替 BETWEEN。

Q3SoqlBuilder 支持 JOIN 吗?

A不支持。请使用关系查询Relationship Queries如 Account.Name。

Q4SoqlBuilder 支持 UNION 吗?

A不支持。SOQL 无法合并两个不相关的结果集。

Q5SoqlBuilder 查询最多返回多少条记录?

A最多返回 50000 条记录。

Q6SoqlBuilder 的 OFFSET 上限是多少?

AOFFSET 上限为 2000且必须与 LIMIT 一起使用。

Q7SalesforceDataTypeConverter 支持哪些时区?

A支持所有 Java 时区。默认使用 UTC 时区,可以通过构造函数指定自定义时区。

Q8Salesforce ID 的 15 位和 18 位有什么区别?

A15 位 ID 是不区分大小写的18 位 ID 包含校验位,可以区分大小写。建议使用 18 位 ID。

Q9FileObjectType 推荐使用哪种文件对象?

A强烈推荐使用 ContentDocument现代文件对象它支持更大的文件大小2048 MB和更好的功能。

Q10如何选择合适的异常类

A根据业务场景选择合适的异常类。例如登录失败使用 SalesforceLoginException文件上传失败使用 FileUploadException操作失败使用 SalesforceOperationException。

总结

datai-salesforce-common 模块是整个 Salesforce 集成体系的基础设施层,提供了丰富的工具类、常量定义、数据转换和异常处理功能。该模块被其他所有 Salesforce 相关模块依赖,是整个体系的基础。

核心优势

  1. 统一的常量管理
  2. 强大的 SOQL 查询构建器
  3. 完善的数据类型转换
  4. 丰富的异常体系
  5. 统一的参数封装
  6. 类型安全的枚举定义

适用场景

  • 所有与 Salesforce 集成的应用
  • 需要 SOQL 查询构建的场景
  • 需要数据类型转换的场景
  • 需要统一异常处理的场景
  • 需要参数封装的场景
  • 需要文件上传的场景