Read and Write Objects to Relational Database Using ORM Workflow
This example shows the basic operations for reading and writing objects to a relational database using Object Relational Mapping (ORM). This example depends on the Product
class that maps to a database table. This class contains several properties that map to the database, as well as some methods that alter those properties.
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(ColumnName = "Manufacturer") Supplier string end properties(ColumnType = "date") InventoryDate datetime end methods function obj = Product(id,name,description,supplier,cost,quantity,inventoryDate) if nargin ~= 0 inputElements = numel(id); if numel(name) ~= inputElements || ... numel(description) ~= inputElements || ... numel(supplier) ~= inputElements || ... numel(cost) ~= inputElements || ... numel(quantity) ~= inputElements || ... numel(inventoryDate) ~= inputElements error('All inputs must have the same number of elements') end % Preallocate by creating the last object first obj(inputElements).ID = id(inputElements); obj(inputElements).Name = name(inputElements); obj(inputElements).Description = description(inputElements); obj(inputElements).Supplier = supplier(inputElements); obj(inputElements).CostPerItem = cost(inputElements); obj(inputElements).Quantity = quantity(inputElements); obj(inputElements).InventoryDate = inventoryDate(inputElements); for n = 1:inputElements-1 % Fill in the rest of the objects obj(n).ID = id(n); obj(n).Name = name(n); obj(n).Description = description(n); obj(n).Supplier = supplier(n); obj(n).CostPerItem = cost(n); obj(n).Quantity = quantity(n); obj(n).InventoryDate = inventoryDate(n); end end end function obj = adjustPrice(obj,amount) arguments obj (1,1) Product amount (1,1) {mustBeNumeric} end obj.CostPerItem = obj.CostPerItem + amount; end function obj = shipProduct(obj,amount) arguments obj (1,1) Product amount (1,1) {mustBePositive,mustBeInteger} end obj.Quantity = obj.Quantity - amount; end function obj = recieveProduct(obj,amount) arguments obj (1,1) Product amount (1,1) {mustBePositive,mustBeInteger} end obj.Quantity = obj.Quantity + amount; obj.InventoryDate = datetime('today'); end end end
Create a Database Connection
To read and write to a database using ORM, create a sqlite
database file that does not require a connection to a live database.
filename = "orm_demo.db"; if exist(filename,"file") conn = sqlite(filename); else conn = sqlite(filename,"create"); end % Remove it to maintain consistency execute(conn,"DROP TABLE IF EXISTS products");
Populate Database Table with Objects
The orm2sql
function shows how a mapped MATLAB® class is respresented as a database table. Display the database column information based on the class defined in Product.m.
orm2sql(conn,"Product")
ans = "CREATE TABLE products (ProductNumber double, Name text, Description text, Quantity double, UnitCost double, Manufacturer text, InventoryDate date, PRIMARY KEY (ProductNumber))"
Use the sqlfind
function to verify that the products
table does not exist.
sqlfind(conn,"products")
ans = 0×5 empty table Catalog Schema Table Columns Type _______ ______ _____ _______ ____
Insert a Scalar Object
Create a Product
object and use it to create and populate a table.
toy = Product(1,"Toy1","Descr1","CompanyA",24.99,0,datetime(2023,1,1))
toy = Product with properties: ID: 1 Name: "Toy1" Description: "Descr1" Quantity: 0 CostPerItem: 24.9900 Supplier: "CompanyA" InventoryDate: 01-Jan-2023
Use the ormwrite
function to populate the database with the data from toy
, and use the sqlread
function to read the table and verify the results.
ormwrite(conn,toy);
sqlread(conn,"products")
ans=1×7 table
ProductNumber Name Description Quantity UnitCost Manufacturer InventoryDate
_____________ ______ ___________ ________ ________ ____________ ____________________________
1 "Toy1" "Descr1" 0 24.99 "CompanyA" "2023-01-01 00:00:00.000000"
Insert an Array of Objects
Instantiate a Product
class with an array of objects.
productArray = Product(2:10,... ["Toy2","Toy3","Toy4","Toy5","Toy6","Toy7","Toy8",... "Toy9","Toy10"],... ["Descr2","Descr3","Descr4","Descr5","Descr6","Descr7",... "Descr8","Descr9","Descr10"],... ["CompanyB","CompanyA","CompanyC","CompanyB","CompanyA","CompanyD","CompanyE","CompanyF","CompanyG"],... [5.99,4.99,14.99,12.99,17.99,4.99,149.99,10.99,5.99],... [1000,350,225,25,600,300,50,100,1250],... repmat(datetime(2023,1,1),1,9)) % View the last object productArray(end)
ans = Product with properties: ID: 10 Name: "Toy10" Description: "Descr10" Quantity: 1250 CostPerItem: 5.9900 Supplier: "CompanyG" InventoryDate: 01-Jan-2023
Use ormwrite
to insert multiple objects at the same time.
% Insert the object array into the database and view the results ormwrite(conn,productArray); sqlread(conn,"products")
ans=10×7 table
ProductNumber Name Description Quantity UnitCost Manufacturer InventoryDate
_____________ _______ ___________ ________ ________ ____________ ____________________________
1 "Toy1" "Descr1" 0 24.99 "CompanyA" "2023-01-01 00:00:00.000000"
2 "Toy2" "Descr2" 1000 5.99 "CompanyB" "2023-01-01 00:00:00.000000"
3 "Toy3" "Descr3" 350 4.99 "CompanyA" "2023-01-01 00:00:00.000000"
4 "Toy4" "Descr4" 225 14.99 "CompanyC" "2023-01-01 00:00:00.000000"
5 "Toy5" "Descr5" 25 12.99 "CompanyB" "2023-01-01 00:00:00.000000"
6 "Toy6" "Descr6" 600 17.99 "CompanyA" "2023-01-01 00:00:00.000000"
7 "Toy7" "Descr7" 300 4.99 "CompanyD" "2023-01-01 00:00:00.000000"
8 "Toy8" "Descr8" 50 149.99 "CompanyE" "2023-01-01 00:00:00.000000"
9 "Toy9" "Descr9" 100 10.99 "CompanyF" "2023-01-01 00:00:00.000000"
10 "Toy10" "Descr10" 1250 5.99 "CompanyG" "2023-01-01 00:00:00.000000"
Read Objects from a Database
Once a class has been mapped to an existing database table, objects of that class can be constructed by reading data from the database.
Use the ormread
method to read data from the database. This method uses the mapping to determine which tables to read, and also determines how the column values correspond to the properties.
% Clear all Product objects from the workspace clear toy productArray % Recreate the objects by reading from the database and view the first and % last allProducts = ormread(conn,"Product") allProducts(1)
ans = Product with properties: ID: 1 Name: "Toy1" Description: "Descr1" Quantity: 0 CostPerItem: 24.9900 Supplier: "CompanyA" InventoryDate: 01-Jan-2023
allProducts(end)
ans = Product with properties: ID: 10 Name: "Toy10" Description: "Descr10" Quantity: 1250 CostPerItem: 5.9900 Supplier: "CompanyG" InventoryDate: 01-Jan-2023
Read in a Subset of Objects
Use the ormread
method with the RowFilter
name-value argument to import a subset of the objects in the database.
Filter the items where CostPerItem
is less than $10.
rf = rowfilter("CostPerItem"); rf = rf.CostPerItem < 10; inexpensiveItems = ormread(conn,"Product",RowFilter=rf) % Verify by checking the properties of one of the objects inexpensiveItems(1)
ans = Product with properties: ID: 2 Name: "Toy2" Description: "Descr2" Quantity: 1000 CostPerItem: 5.9900 Supplier: "CompanyB" InventoryDate: 01-Jan-2023
Update the Database with Objects
The ormupdate
method updates existing rows in a database table based on changes to one or more mapped MATLAB® objects.
Use the receiveProduct
method of the Product
class to increase the inventory of Toy1
.
% Find the Toy1 product on the database rf = rowfilter("Name"); rf = rf.Name == "Toy1"; toy = ormread(conn,"Product",RowFilter=rf)
toy = Product with properties: ID: 1 Name: "Toy1" Description: "Descr1" Quantity: 0 CostPerItem: 24.9900 Supplier: "CompanyA" InventoryDate: 01-Jan-2023
% Use the receiveProduct method of Product to increase the amount of % products in the inventory toy = recieveProduct(toy,500)
toy = Product with properties: ID: 1 Name: "Toy1" Description: "Descr1" Quantity: 500 CostPerItem: 24.9900 Supplier: "CompanyA" InventoryDate: 14-Dec-2023
Use the fetch
function to see that these changes are not reflected in the database.
fetch(conn,"SELECT * FROM products WHERE Name = 'Toy1'")
ans=1×7 table
ProductNumber Name Description Quantity UnitCost Manufacturer InventoryDate
_____________ ______ ___________ ________ ________ ____________ ____________________________
1 "Toy1" "Descr1" 0 24.99 "CompanyA" "2023-01-01 00:00:00.000000"
Use the ormupdate
method to push the changes made in MATLAB® to the database. Then, use the fetch
function to verify that Quantity
and InventoryDate
are updated in the database.
ormupdate(conn,toy);
fetch(conn,"SELECT * FROM products WHERE Name = 'Toy1'")
ans=1×7 table
ProductNumber Name Description Quantity UnitCost Manufacturer InventoryDate
_____________ ______ ___________ ________ ________ ____________ ____________________________
1 "Toy1" "Descr1" 500 24.99 "CompanyA" "2023-12-14 00:00:00.000000"
Refresh Objects to Match the Database
You can refresh an object in MATLAB® to reflect the current state of the database. First, change the quantity of Toy1
to 1000
and view the result using the fetch
function.
execute(conn,"UPDATE products SET Quantity = 1000 WHERE Name = 'Toy1'"); fetch(conn,"SELECT * FROM products WHERE Name = 'Toy1'")
ans=1×7 table
ProductNumber Name Description Quantity UnitCost Manufacturer InventoryDate
_____________ ______ ___________ ________ ________ ____________ ____________________________
1 "Toy1" "Descr1" 1000 24.99 "CompanyA" "2023-12-14 00:00:00.000000"
Use the ormread
method
to refresh the properties of the object.
toy = ormread(conn,toy)
toy = Product with properties: ID: 1 Name: "Toy1" Description: "Descr1" Quantity: 1000 CostPerItem: 24.9900 Supplier: "CompanyA" InventoryDate: 14-Dec-2023
clear allProducts inexpensiveItems toy close(conn)