关于 matlab-map-database-objects
此 MATLAB 技能介绍 Database Toolbox 的 ORM 层,用于将 MATLAB 类映射到关系数据库表,并以对象读写和更新数据。适合需要对象身份、类型约束或业务逻辑的数据库工作流;要求 MATLAB R2023b 或更高版本。
主要功能
- 01将 Mappable 类映射到数据库表
- 02使用 ormread 读取对象
- 03使用 ormwrite 写入对象
- 04使用 ormupdate 更新记录
- 05通过 orm2sql 检查建表语句
适用场景
- 01将 MATLAB 类映射为关系表
- 02把数据库行读取为 MATLAB 对象
- 03修改对象后更新数据库记录
- 04从类定义核对 SQL 表结构
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-map-database-objects安装后在 Claude Code 中输入/matlab-map-database-objects确认已加载。
附带文件manifest.yaml
详细介绍
MATLAB 对象关系映射
使用 Database Toolbox 中的对象关系映射(ORM)层,将 MATLAB 类映射到关系数据库表。定义带有属性到列映射的 Mappable 类,并使用 ormread、ormwrite 和 ormupdate 对对象执行 CRUD 操作。自 R2023b 起可用。
何时使用此技能
- 将 MATLAB 类映射到数据库表
- 将数据库行读取为 MATLAB 对象
- 将 MATLAB 对象写入数据库表
- 根据修改后的对象更新数据库行
- 根据类定义生成 SQL CREATE TABLE 语句
- 面向对象的数据库工作流
- 用户提及以下关键词:ORM、对象关系映射、Mappable、ormread、ormwrite、ormupdate、orm2sql、类映射、属性映射、对象数据库
何时不使用
- 临时查询或数据探索——改用
sqlread/fetch和RowFilter - 数千行数据的批量导入/导出——批量操作中 ORM 比
sqlwrite/sqlread慢 - MongoDB、Cassandra 或 Neo4j——ORM 仅适用于关系数据库(JDBC、ODBC、原生 MySQL/PostgreSQL/SQLite)
- R2023b 之前的 MATLAB 版本——不支持 ORM
关键规则
ORM 要求
- 始终继承
database.orm.mixin.Mappable——这是使用 ORM 功能的必要条件。 - 始终至少定义一个
PrimaryKey属性——ORM 需要它来标识对象。 - 始终使用类级属性
TableName指定数据库表名。 - 始终包含一个可处理
nargin == 0的构造函数(允许 ORM 预分配)。 - ORM 要求使用 R2023b 或更高版本。
支持的连接
- ORM 支持:JDBC、ODBC、PostgreSQL 原生连接、MySQL 原生连接、SQLite 原生连接、DuckDB 原生连接。
- ORM 不支持:MongoDB(mongoc)、Cassandra(apacheCassandra)或 Neo4j。
决策框架
| 场景 | 使用 ORM | 使用 sqlread/sqlwrite |
|---|---|---|
| 需要对象标识和业务逻辑 | 是 | 否 |
| 需要基于类的类型安全 | 是 | 否 |
| 读写时需要进行领域验证 | 是 | 否 |
| 临时查询或探索 | 否 | 是 |
| 批量操作(数千行) | 否 | 是(更快) |
| 不需要对象映射 | 否 | 是 |
核心概念
定义 Mappable 类
Mappable 类将 MATLAB 属性映射到数据库列:
classdef (TableName = "employees") Employee < database.orm.mixin.Mappable
properties (PrimaryKey, ColumnName = "EmployeeID")
ID int32
end
properties
Name string
Department string
Salary double
end
properties (ColumnName = "HireDate", ColumnType = "date")
StartDate datetime
end
methods
function obj = Employee(id, name, dept, salary, startDate)
if nargin ~= 0
obj.ID = id;
obj.Name = name;
obj.Department = dept;
obj.Salary = salary;
obj.StartDate = startDate;
end
end
function obj = promote(obj, raise)
obj.Salary = obj.Salary + raise;
end
end
end
属性特性参考
| 特性 | 用途 | 示例 |
|---|---|---|
PrimaryKey | 将属性标记为主键(必需) | properties (PrimaryKey) |
ColumnName | 将属性映射到名称不同的列 | properties (ColumnName = "EmpID") |
ColumnType | 指定数据库列类型 | properties (ColumnType = "date") |
TableName | 用于指定目标表名的类级属性 | classdef (TableName = "employees") |
常见错误
% INCORRECT — class without PrimaryKey (ormwrite will error)
classdef (TableName = "employees") Employee < database.orm.mixin.Mappable
properties
Name string
Dept string
end
end
% ormwrite(conn, emp) → Error: No PrimaryKey defined
% CORRECT — PrimaryKey is required for ORM operations
classdef (TableName = "employees") Employee < database.orm.mixin.Mappable
properties(PrimaryKey)
EmployeeID int32
end
properties
Name string
Dept string
end
end
% INCORRECT — class not inheriting Mappable
classdef Employee
properties(PrimaryKey)
EmployeeID int32
end
end
% ormread(conn, "Employee") → Error! Not a Mappable class.
% CORRECT — must inherit from database.orm.mixin.Mappable
classdef Employee < database.orm.mixin.Mappable
properties(PrimaryKey)
EmployeeID int32
end
end
% INCORRECT — constructor without nargin==0 guard
classdef (TableName = "emp") Employee < database.orm.mixin.Mappable
methods
function obj = Employee(id, name)
obj.EmployeeID = id;
obj.Name = name;
end
end
end
% ormread will fail because ORM needs to construct empty objects
% CORRECT — nargin==0 guard allows ORM to construct empty objects
classdef (TableName = "emp") Employee < database.orm.mixin.Mappable
methods
function obj = Employee(id, name)
if nargin == 0
return;
end
obj.EmployeeID = id;
obj.Name = name;
end
end
end
使用 ormwrite 写入对象
% Create and insert a single object
emp = Employee(1, "Alice", "Engineering", 95000, datetime(2023,3,15));
ormwrite(conn, emp);
% Create and insert an array of objects
emps = [Employee(2, "Bob", "Sales", 72000, datetime(2023,6,1)), ...
Employee(3, "Carol", "Engineering", 105000, datetime(2022,1,10))];
ormwrite(conn, emps);
使用 ormread 读取对象
% Read all objects
allEmployees = ormread(conn, "Employee");
% Read with a row filter
rf = rowfilter("Salary");
highEarners = ormread(conn, "Employee", RowFilter=rf.Salary > 90000);
% Refresh an existing object from database
emp = ormread(conn, emp);
使用 ormupdate 更新对象
% Modify object in MATLAB
emp = promote(emp, 5000);
% Push changes to database
ormupdate(conn, emp);
删除记录
ORM 不提供 ormdelete 函数。使用 execute 执行删除:
execute(conn, "DELETE FROM employees WHERE EmployeeID = 42");
错误处理
try
ormwrite(conn, employeeObj);
catch ME
if contains(ME.message, "UNIQUE") || contains(ME.message, "primary key")
warning("Duplicate primary key. Use ormupdate instead.");
ormupdate(conn, employeeObj);
else
rethrow(ME);
end
end
根据类定义生成 SQL
% View the CREATE TABLE SQL that corresponds to the class
sql = orm2sql(conn, "Employee");
disp(sql);
% Output: "CREATE TABLE employees (EmployeeID integer, Name text, ...)"
完整示例
示例 1:完整的 ORM 工作流——定义、写入、读取、更新
步骤 1:定义类(保存为 Product.m):
classdef (TableName = "products") Product < database.orm.mixin.Mappable
properties (PrimaryKey, ColumnName = "ProductNumber")
ID int32
end
properties
Name string
Description string
Quantity int32
end
properties (ColumnName = "UnitCost")
CostPerItem double
end
properties (ColumnType = "date")
InventoryDate datetime
end
methods
function obj = Product(id, name, desc, cost, qty, invDate)
if nargin ~= 0
obj.ID = id;
obj.Name = name;
obj.Description = desc;
obj.CostPerItem = cost;
obj.Quantity = qty;
obj.InventoryDate = invDate;
end
end
function obj = restock(obj, amount)
obj.Quantity = obj.Quantity + amount;
obj.InventoryDate = datetime("today");
end
end
end
步骤 2:使用 ORM 操作(保存为 ormWorkflow.m):
(使用上文定义的 Product 类。)
% Connect to SQLite (no driver needed)
conn = sqlite("inventory.db", "create");
% Create and insert products
p1 = Product(1, "Widget", "Small widget", 9.99, 100, datetime(2024,1,1));
p2 = Product(2, "Gadget", "Large gadget", 29.99, 50, datetime(2024,1,1));
ormwrite(conn, [p1, p2]);
% Read all products back as objects
allProducts = ormread(conn, "Product");
disp(allProducts(1));
% Filter: find products under $15
rf = rowfilter("CostPerItem");
cheapProducts = ormread(conn, "Product", RowFilter=rf.CostPerItem < 15);
% Update: restock a product
cheapProducts(1) = restock(cheapProducts(1), 200);
ormupdate(conn, cheapProducts(1));
% Verify
refreshed = ormread(conn, cheapProducts(1));
disp(refreshed.Quantity); % Should be 300
close(conn);
最佳实践
- 始终将 Mappable 类定义在单独的
.m文件中——每个文件一个类(MATLAB 要求)。 - 始终包含一个能够处理
nargin == 0的构造函数(支持预分配)。 - 始终只将一个属性块标记为
PrimaryKey。 - 当 MATLAB 属性名与数据库列名不同时,使用
ColumnName。 - 对于需要显式映射的类型,使用
ColumnType(例如,datetime 类型使用"date")。 - 使用带有
RowFilter的ormread仅导入所需对象——筛选条件会下推到数据库。 - 写入前使用
orm2sql验证类映射是否与预期的数据库架构匹配。 - 在 MATLAB 中使用类方法修改对象,然后使用
ormupdate推送更改。
常见模式
模式 1:定义-写入-读取-更新
% Define class → Product.m
p = Product(1, "Item", "Desc", 9.99, 10, datetime("today"));
ormwrite(conn, p);
p = ormread(conn, p); % Refresh from DB
p = restock(p, 50); % Modify in MATLAB
ormupdate(conn, p); % Push to DB
模式 2:使用业务逻辑进行筛选读取
rf = rowfilter("Quantity");
lowStock = ormread(conn, "Product", RowFilter=rf.Quantity < 10);
for i = 1:numel(lowStock)
lowStock(i) = restock(lowStock(i), 100);
ormupdate(conn, lowStock(i));
end
模式 3:架构验证
sql = orm2sql(conn, "MyClass");
disp(sql); % Verify CREATE TABLE matches expectations
检查清单
完成前,请确认:
- Mappable 类继承自
database.orm.mixin.Mappable - 类的
classdef上具有TableName属性 - 至少一个属性块具有
PrimaryKey属性 - 构造函数能够处理用于预分配的
nargin == 0 - 类保存在单独的
.m文件中 - 已建立并验证连接(
isopen(conn)) - 连接类型受支持(JDBC、ODBC、MySQL/PostgreSQL/SQLite/DuckDB 原生连接)
- 使用 R2023b 或更高版本(较早版本不支持 ORM)
故障排除
问题:ormwrite 失败并提示“class is not Mappable”
- 解决方案:确保该类继承自
database.orm.mixin.Mappable。类定义必须包含< database.orm.mixin.Mappable。
问题:ormread 返回空数组
- 解决方案:使用
sqlfind(conn, tableName)确认数据库中存在该表。确认类的TableName属性与实际表名一致。
问题:ormupdate 未更改数据库值
- 解决方案:
ormupdate根据主键匹配行。确认对象的主键属性值存在于数据库中。使用ormread刷新并检查。
问题:属性到列的映射不正确
- 解决方案:使用
orm2sql(conn, "ClassName")检查生成的 SQL。确认ColumnName和ColumnType属性与数据库架构匹配。
问题:找不到 ORM 函数(“Undefined function”)
- 解决方案:ORM 需要 R2023b 或更高版本。使用
ver('database')检查版本。对于较早版本,请改用sqlread/sqlwrite。
版权所有 2026 The MathWorks, Inc.
评论
支持 Markdown