- 人工智能
- AI 技能
- 文档
- 开发工具
【免费下载链接】DocAgent
本文是 DocAgent 仓库中仓颉标准库std.database.sql包的技术解读,聚焦可空变长二进制字符串类型SqlNullableVarBinary:它对应 SQL 的VARBINARY类型与仓颉Array<Byte>类型,并显式支持数据库Null值。读完本文,你将掌握该类型的构造与取值方式、其在SqlNullableDbType类型体系中的位置、在预编译语句中读写可空二进制列的完整用法,以及面向未来版本的迁移建议。
一、类定位:SqlNullableVarBinary 是什么
在 database_sql 包总览 的 SQL 数据类型与仓颉类型映射表中,VARBINARY对应仓颉Array<Byte>,映射类型为SqlVarBinary;而本文主角SqlNullableVarBinary则是其可空版本,定义于 database_sql 包 API 类文档:
public class SqlNullableVarBinary <: SqlNullableDbType { public init(v: ?Array<Byte>) }核心定位可归纳为三点:
- 变长二进制字符串:对应 SQL 标准中的
VARBINARY列,字节长度随实际数据变化,不强制补齐到固定长度(与定长的BINARY/SqlNullableBinary相区别); - 底层仓颉类型为
Array<Byte>:其中 Byte 是内置类型UInt8的别名,即无符号 8 位整数序列; - 可为数据库
Null值:构造函数入参与value属性均声明为可空类型?Array<Byte>,用于承载数据库中该列的NULL语义。
同时在 readme.md 的 SQL 数据类型清单中,该类被明确标注为(deprecated),说明当前版本仍可使用,但未来版本即将废弃,需要逐步迁移到仓颉原生类型方案。
二、类型体系与 Null 语义设计
SqlNullableVarBinary的父类型是 SqlNullableDbType 接口,而SqlNullableDbType又继承自 SqlDbType 接口。从源码接口定义看,这构成了仓颉 SQL 数据类型的双层抽象:
| 接口 | 职责 | 关键约束 |
|---|---|---|
SqlDbType | 所有 sql 数据类型的父类,仅声明prop name: String | 所有实现类型都必须具有公共value属性 |
SqlNullableDbType | 允许null值的 sql 数据类型父类 | null值时,value属性值为Option.None |
SqlDbType接口对实现类的形式约束(见 database_sql_package_interfaces.md 中的说明)可以总结为三条规则:
- 只有一个参数、参数类型为
T的构造函数(T为仓颉语言支持的类型); - 具有
public修饰的value属性,其类型与构造函数参数类型一致,值为对应仓颉类型的值; - 若数据类型允许
null值,则继承SqlNullableDbType,null时value字段的值为Option<T>.None。
SqlNullableVarBinary完全符合这套约定:构造函数为init(v: ?Array<Byte>),value属性类型为?Array<Byte>(即可空Array<Byte>,对应Option<Array<Byte>>语义),null值场景下取值为None。
设计要点:可空类型统一放在独立的
SqlNullableDbType分支下,而不是在每个具体类型内部自行处理,保证了全包范围内"可空 = 继承SqlNullableDbType"这一约定的一致性,也让查询结果读取(见下文getOrNull)能够依托Option类型安全地表达NULL。
三、API 详解:构造函数与成员属性
关联文档 SqlNullableVarBinary_class.md 完整列出了该类的全部对外 API,共一个构造函数与两个成员属性,这里逐一展开:
3.1 构造函数init
| 名称 | 原型 | 说明 |
|---|---|---|
init | (v: ?Array<Byte>) | 根据传入参数 v 构造一个SqlNullableVarBinary实例 |
- 入参
v为可空字节数组:传入Array<Byte>表示非空二进制数据,传入None(或null字面量)表示数据库NULL; - 该构造函数的完整声明与参数说明见 database_sql_package_classes.md。
3.2 成员属性name
| 名称 | 原型 | 说明 |
|---|---|---|
name | public prop name: String | 类型名称,即SqlNullableVarBinary |
该属性继承自SqlDbType接口的约定,用于标识当前 SQL 数据类型的具体类型名,可配合ColumnInfo.typeName等元数据做运行时类型判断。
3.3 成员属性value
| 名称 | 原型 | 说明 |
|---|---|---|
value | public mut prop value: ?Array<Byte> | 该数据的值 |
- 可读可写(
mut prop),类型为?Array<Byte>; - 构造后可随时修改所承载的二进制内容;
- 当值为
None时即代表数据库NULL。
四、在数据库读写中的实战用法
SqlNullableVarBinary不会单独使用,而是嵌入std.database.sql的"驱动 → 数据源 → 连接 → 预编译语句"调用链中。下面结合包内示例(获取连接示例、数据库操作示例)与 Statement 接口、QueryResult 接口 的源码定义,给出读写可空VARBINARY列的两种思路。
4.1 写入:基于原生类型与setNull的新接口方式
从Statement接口定义看,set<T>(index: Int, value: T)的功能是"将仓颉的数据类型转成数据库的数据类型",而setNull(index: Int)的功能是"将指定位置处的语句参数设置为 SQL NULL"。因此可以直接用仓颉原生Array<Byte>写入二进制数据、用setNull表达 NULL,无需显式构造包装类型(该类已标注 deprecated 也印证了这一趋势):
import std.database.sql.* main() { let drv = DriverManager.getDriver("opengauss") ?? return let ds = drv.open("opengauss://testuser:testpwd@localhost:5432/testdb", []) let conn = ds.connect() var stmt = conn.prepareStatement("INSERT INTO files(name, payload) VALUES(?, ?)") stmt.set<String>(0, "logo.png") // 二进制内容以原生 Array<Byte> 传入,驱动自动完成类型转换 stmt.set<Array<Byte>>(1, [0x89, 0x50, 0x4E, 0x47]) var ur = stmt.update() println("Update Result: ${ur.rowCount} ${ur.lastInsertId}") stmt.close() }当该列允许为空、需要写入NULL时,则使用setNull:
stmt.set<String>(0, "empty.bin") stmt.setNull(1) // 将第 1 个参数设置为 SQL NULL stmt.update()4.2 读取:getOrNull安全处理 NULL
QueryResult接口提供了两种取值方式:get<T>(index: Int)与getOrNull<T>(index: Int)。从接口定义可知,getOrNull在列值为SQL NULL时返回None,而索引越界或行数据未就绪时抛出SqlException。因此读取可空二进制列应优先使用getOrNull,配合模式匹配区分空值:
let qr = stmt.query() while (qr.next()) { let payload = qr.getOrNull<Array<Byte>>(1) // NULL 时返回 None match (payload) { case Some(bytes) => println("payload size = ${bytes.size}") case None => println("payload is NULL") } } stmt.close()4.3 旧式参数绑定方式(理解历史代码)
接口中还存在带<sup>(deprecated)</sup>标注的query(params: Array<SqlDbType>)与update(params: Array<SqlDbType>)重载,它们以Array<SqlDbType>列表替换 SQL 语句中的?占位符。在旧代码中,可空二进制参数正是通过SqlNullableVarBinary这样的包装类型传入;遇到此类历史代码时,可将SqlNullableVarBinary(None)与SqlNullableVarBinary(bytes)分别映射NULL与非空数据。官方已明确建议改用query()/update()无参版本配合set/setNull的新方式。
五、废弃说明与迁移建议
SqlNullableVarBinary与SqlVarBinary均在文档中标注为"未来版本即将废弃不再使用,使用仓颉原生类型替代"。结合前文接口定义,迁移路径是清晰的:
- 写入侧:用
Statement.set<T>直接传Array<Byte>,用Statement.setNull传NULL,替代构造SqlNullableVarBinary包装对象; - 读取侧:用
QueryResult.getOrNull<Array<Byte>>(index)读取,替代依赖SqlDbType旧式next(values)的取值流程; - 类型判断侧:列是否可空可直接查看
ColumnInfo.nullable属性(见 ColumnInfo 接口),无需再依赖包装类型名。
迁移期间若仍需与旧代码共存,构造SqlNullableVarBinary时注意value为None即表示NULL这一语义即可平滑过渡。
六、参考文档索引
- SqlNullableVarBinary 类索引文档(本文主体)
- SqlVarBinary 类索引文档(非空版本对照)
- database_sql 包 API 类文档(完整类声明与全部 SQL 数据类型)
- database_sql 包 API 接口文档(
SqlDbType/SqlNullableDbType/Statement/QueryResult接口) - database_sql 包总览(SQL 与仓颉类型映射表)
- database_sql readme(包内 API 索引与分类导航)
- 获取数据库连接示例、数据库操作示例(驱动注册、数据源打开、语句执行全流程)
- 人工智能
- AI 技能
- 文档
- 开发工具
【免费下载链接】DocAgent
相关推荐
DocAgent 仓颉标准库参考:SqlNullableTime 可空时间类型深度解析
DocAgent 仓颉标准库参考:SqlNullableTime 可空时间类型深度解析 SqlNullableTime 是仓颉标准库 std.database.
人工智能AI 技能文档开发工具仓颉数据库访问:SqlNullableVarchar 可空变长字符串类型详解(std.database.sql)
仓颉数据库访问:SqlNullableVarchar 可空变长字符串类型详解(std.database.sql) 导读 SqlNullableVarchar 是
人工智能AI 技能文档开发工具仓颉数据库包 SqlVarBinary 类详解:VARBINARY 变长二进制数据的建模与迁移
仓颉数据库包 SqlVarBinary 类详解:VARBINARY 变长二进制数据的建模与迁移 SqlVarBinary 是仓颉标准库 std.database
人工智能AI 技能文档开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考