[New] Updated model documentation with simplified API
This commit is contained in:
parent
a59272cfd2
commit
a379d892eb
|
@ -9,6 +9,11 @@ be modelled in Strolch and use in Strolch:
|
|||
|
||||
![Strolch model example](/assets/images/strolch-model-example.png)
|
||||
|
||||
The model has four entities, which will be modelled using 3 Resources and 1 Order object. The objects have numerous fields and the following relationships:
|
||||
* Bidirectional between Article <-> Product
|
||||
* Unidirectional from Order -> Article
|
||||
* Unidirectional from Order -> Customer
|
||||
|
||||
A possible model would look as follows:
|
||||
|
||||
```xml
|
||||
|
@ -60,158 +65,181 @@ A possible model would look as follows:
|
|||
|
||||
Let's go through this model:
|
||||
|
||||
* In the above model we see that the id and name fields are always on the
|
||||
element, and thus aren't added as parameters. Further most elements have a
|
||||
parameters ParameterBag, with one or more parameters, modelling the fields.
|
||||
* Note that in this example the Type of all the elements is Template. Strolch
|
||||
has API support to create a clone of these elements, so that they have a
|
||||
unique ID, and the proper type for persistence.
|
||||
* The Product element has three parameters: description, color and form. In
|
||||
this case they are all of type String. Further the relations ParameterBag
|
||||
defines the relationships, i.e. the product knows its articles. Note how
|
||||
the relation is first defined in a relations ParameterBag and that the
|
||||
Parameter has Interpretation="Resource-Ref" Uom="Product" attributes.
|
||||
Strolch has API support for this, making it trivial to retrieve a dependency.
|
||||
* The Article element has two parameters description and barcode. Further it
|
||||
has a reference to its Product.
|
||||
* The Order element doesn't model the date and state fields as parameters, as
|
||||
these are inherently part of an Order element. The Order does define two
|
||||
references to customer and articles. A special case is the quantities
|
||||
ParameterBag. This bag of parameters is used to store the per article
|
||||
quantity for this order. With ParameterBags, you can eliminate the use of
|
||||
simple aggregate classes, as is commonly used in object-oriented programming.
|
||||
* The Customer element models a address ParameterBag to store the address of
|
||||
a customer. Using a separate bag allows for further more direct fields to
|
||||
stored on the default parameters bag.
|
||||
* In the above model we see that the `id` and `name` fields are always on the
|
||||
element, and thus aren't added as parameters. Further best practice is to use
|
||||
a `parameters` ParameterBag, with one or more parameters, modelling the
|
||||
fields. There is API support to not have to always type the `parameters` bag
|
||||
id.
|
||||
* Note that in this example the Type of all the elements is `Template`. Strolch
|
||||
has API support to create a clone of these elements, so that they have a
|
||||
unique id, and the proper type for persistence.
|
||||
* The `Product` element has three parameters: `description`, `color` and `form`. In this
|
||||
case they are all of type String. Further the `relations` ParameterBag defines
|
||||
the relationships, i.e. the product knows its articles. Note how the relation
|
||||
is first defined in a relations ParameterBag and that the Parameter has
|
||||
`Interpretation="Resource-Ref" Uom="Product"` attributes. Strolch has API
|
||||
support for this, making it trivial to retrieve a dependency.
|
||||
* The `Article` element has two parameters `description` and `barcode`. Further it has
|
||||
a reference to its Product.
|
||||
* The `Order` element doesn't model the `date` and `state` fields as parameters, as
|
||||
these are inherently part of an Order element. The Order does define two
|
||||
references to customer and articles. A special case is the `quantities`
|
||||
ParameterBag. This bag of parameters is used to store the per article quantity
|
||||
for this order. With ParameterBags, you can eliminate the use of simple
|
||||
aggregate classes, as is commonly used in object-oriented programming.
|
||||
* The `Customer` element models an `address` ParameterBag to store the address of a
|
||||
customer. Using a separate bag allows for further more direct fields to stored
|
||||
on the default parameters bag.
|
||||
|
||||
Now that we have a basic understanding of te model, it is of far more interest
|
||||
in how to create and interact with these elements at runtime. The following
|
||||
Now that we have a basic understanding of te model, it is of far more interest
|
||||
in how to create and interact with these elements at runtime. The following
|
||||
listing will perform simple operations:
|
||||
|
||||
```java
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, false)) {
|
||||
|
||||
/*
|
||||
* create a new product
|
||||
*/
|
||||
Resource dafalgan = tx.getResourceTemplate("Product", true);
|
||||
dafalgan.setName("Dafalgan 100mg");
|
||||
dafalgan.getParameter("description", true).setValue("Dafalgan is for pain.");
|
||||
dafalgan.getParameter("color", true).setValue("Yellow");
|
||||
dafalgan.getParameter("form", true).setValue("flat");
|
||||
|
||||
StringListParameter articlesP = dafalgan.getRelationsParam("articles", true);
|
||||
|
||||
/*
|
||||
* create articles
|
||||
*/
|
||||
Resource dafalgan1 = tx.getResourceTemplate("Article", true);
|
||||
dafalgan1.setName("Dafalgan 100mg 10 pce");
|
||||
dafalgan1.getParameter("description", true).setValue("This is pack with 10 pieces.");
|
||||
dafalgan1.getParameter("barcode", true).setValue("654654");
|
||||
|
||||
Resource dafalgan2 = tx.getResourceTemplate("Article", true);
|
||||
dafalgan2.setName("Dafalgan 100mg 20 pce");
|
||||
dafalgan2.getParameter("description", true).setValue("This is pack with 20 pieces.");
|
||||
dafalgan2.getParameter("barcode", true).setValue("654655");
|
||||
|
||||
/*
|
||||
* add reference to product
|
||||
*/
|
||||
dafalgan1.getRelationParam("product").setValue(dafalgan.getId());
|
||||
articlesP.addValue(dafalgan1.getId());
|
||||
dafalgan2.getRelationParam("product").setValue(dafalgan.getId());
|
||||
articlesP.addValue(dafalgan2.getId());
|
||||
|
||||
/*
|
||||
* create a new customer
|
||||
*/
|
||||
Resource customer1 = tx.getResourceTemplate("Customer", true);
|
||||
customer1.setName("John Doe");
|
||||
|
||||
// set address
|
||||
ParameterBag addressBag = customer1.getParameterBag("address", true);
|
||||
addressBag.getParameter("street", true).setValue("Main Str. 1");
|
||||
addressBag.getParameter("zip", true).setValue("1234");
|
||||
addressBag.getParameter("city", true).setValue("Hometown");
|
||||
addressBag.getParameter("country", true).setValue("Switzerland");
|
||||
|
||||
/*
|
||||
* create a new order
|
||||
*/
|
||||
Order order = tx.getOrderTemplate("Order", true);
|
||||
order.setName("Order for " + customer1.getName());
|
||||
order.setDate(LocalDate.of(2021, 2, 1));
|
||||
order.setState(State.PLANNED);
|
||||
|
||||
// store reference to customer
|
||||
order.getRelationParam("customer", true).setValue(customer1.getId());
|
||||
|
||||
StringListParameter orderArticlesP = order.getRelationsParam("articles", true);
|
||||
ParameterBag quantitiesBag = order.getParameterBag("quantities", true);
|
||||
FloatParameter quantityT = quantitiesBag.removeParameter("quantity");
|
||||
|
||||
// order quantity of 20 for Dafalgan 1
|
||||
FloatParameter q1P = quantityT.getClone();
|
||||
q1P.setId(dafalgan1.getId());
|
||||
q1P.setValue(20);
|
||||
quantitiesBag.addParameter(q1P);
|
||||
orderArticlesP.addValue(dafalgan1.getId());
|
||||
|
||||
// set order quantity of 10 for Dafalgan 2
|
||||
FloatParameter q2P = quantityT.getClone();
|
||||
orderArticlesP.addValue(dafalgan2.getId());
|
||||
q2P.setId(dafalgan2.getId());
|
||||
q2P.setValue(20);
|
||||
quantitiesBag.addParameter(q2P);
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
|
||||
// keep IDs for later use
|
||||
dafalganId = dafalgan.getId();
|
||||
dafalgan1Id = dafalgan1.getId();
|
||||
dafalgan2Id = dafalgan2.getId();
|
||||
customerId = customer1.getId();
|
||||
orderId = order.getId();
|
||||
String dafalganId;
|
||||
String dafalgan1Id;
|
||||
String dafalgan2Id;
|
||||
String customerId;
|
||||
String orderId;
|
||||
|
||||
/*
|
||||
* persist
|
||||
*/
|
||||
tx.add(dafalgan);
|
||||
tx.add(dafalgan1);
|
||||
tx.add(dafalgan2);
|
||||
tx.add(customer1);
|
||||
tx.add(order);
|
||||
// first transaction to create the data
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, false)) {
|
||||
|
||||
// commit
|
||||
tx.commitOnClose();
|
||||
/*
|
||||
* create a new product
|
||||
*/
|
||||
Resource dafalgan = tx.getResourceTemplate("Product", true);
|
||||
dafalgan.setName("Dafalgan 100mg");
|
||||
dafalgan.setString("description", "Dafalgan is for pain.");
|
||||
dafalgan.setString("color", "Yellow");
|
||||
dafalgan.setString("form", "flat");
|
||||
|
||||
/*
|
||||
* create articles
|
||||
*/
|
||||
Resource dafalgan1 = tx.getResourceTemplate("Article", true);
|
||||
dafalgan1.setName("Dafalgan 100mg 10 pce");
|
||||
dafalgan1.setString("description", "This is pack with 10 pieces.");
|
||||
dafalgan1.setString("barcode", "654654");
|
||||
|
||||
Resource dafalgan2 = tx.getResourceTemplate("Article", true);
|
||||
dafalgan2.setName("Dafalgan 100mg 20 pce");
|
||||
dafalgan2.setString("description", "This is pack with 20 pieces.");
|
||||
dafalgan2.setString("barcode", "654655");
|
||||
|
||||
/*
|
||||
* add reference to product
|
||||
*/
|
||||
dafalgan1.setRelation("product", dafalgan);
|
||||
dafalgan2.setRelation("product", dafalgan);
|
||||
|
||||
dafalgan.addRelation("articles", dafalgan1);
|
||||
dafalgan.addRelation("articles", dafalgan2);
|
||||
|
||||
/*
|
||||
* create a new customer
|
||||
*/
|
||||
Resource customer1 = tx.getResourceTemplate("Customer", true);
|
||||
customer1.setName("John Doe");
|
||||
|
||||
// set address
|
||||
ParameterBag addressBag = customer1.getParameterBag("address", true);
|
||||
addressBag.setString("street", "Main Str. 1");
|
||||
addressBag.setString("zip", "1234");
|
||||
addressBag.setString("city", "Hometown");
|
||||
addressBag.setString("country", "Switzerland");
|
||||
|
||||
/*
|
||||
* create a new order
|
||||
*/
|
||||
Order order = tx.getOrderTemplate("Order", true);
|
||||
order.setName("Order for " + customer1.getName());
|
||||
order.setDate(LocalDate.of(2021, 2, 1));
|
||||
order.setState(State.PLANNED);
|
||||
|
||||
// store reference to customer
|
||||
order.setRelation("customer", customer1);
|
||||
|
||||
StringListParameter orderArticlesP = order.getRelationsParam("articles", true);
|
||||
ParameterBag quantitiesBag = order.getParameterBag("quantities", true);
|
||||
FloatParameter quantityT = quantitiesBag.removeParameter("quantity");
|
||||
|
||||
// order quantity of 20 for Dafalgan 1
|
||||
quantitiesBag.setDouble(dafalgan1.getId(), 20);
|
||||
order.addRelation("articles", dafalgan1);
|
||||
|
||||
// set order quantity of 10 for Dafalgan 2
|
||||
quantitiesBag.setDouble(dafalgan2.getId(), 20);
|
||||
order.addRelation("articles", dafalgan2);
|
||||
|
||||
// keep IDs for later use
|
||||
dafalganId = dafalgan.getId();
|
||||
dafalgan1Id = dafalgan1.getId();
|
||||
dafalgan2Id = dafalgan2.getId();
|
||||
customerId = customer1.getId();
|
||||
orderId = order.getId();
|
||||
|
||||
/*
|
||||
* persist
|
||||
*/
|
||||
tx.add(dafalgan);
|
||||
tx.add(dafalgan1);
|
||||
tx.add(dafalgan2);
|
||||
tx.add(customer1);
|
||||
tx.add(order);
|
||||
|
||||
// commit
|
||||
tx.commitOnClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true)) {
|
||||
class Scratch {
|
||||
public static void main(String[] args) {
|
||||
|
||||
// get order
|
||||
Order order = tx.getOrderBy("Order", orderId, true);
|
||||
assertNotNull(orderId);
|
||||
assertEquals("Order for John Doe", order.getName());
|
||||
// keep IDs for later use
|
||||
String dafalganId;
|
||||
String dafalgan1Id;
|
||||
String dafalgan2Id;
|
||||
String customerId;
|
||||
String orderId;
|
||||
|
||||
//
|
||||
// .. snip ...
|
||||
//
|
||||
|
||||
// get customer
|
||||
Resource customer = tx.getResourceByRelation(order, "customer", true);
|
||||
assertNotNull(customer);
|
||||
assertEquals("John Doe", customer.getName());
|
||||
// second transaction to query the data
|
||||
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true)) {
|
||||
|
||||
// get articles
|
||||
List<Resource> articles = tx.getResourcesByRelation(order, "articles", true);
|
||||
assertEquals(2, articles.size());
|
||||
// get order
|
||||
Order order = tx.getOrderBy("Order", orderId, true);
|
||||
assertEquals("Order for John Doe", order.getName());
|
||||
|
||||
// get products
|
||||
List<Resource> products = articles.stream().map(a -> tx.getResourceByRelation(a, "product", true))
|
||||
.distinct().collect(Collectors.toList());
|
||||
assertEquals(1, products.size());
|
||||
// get customer
|
||||
Resource customer = tx.getResourceByRelation(order, "customer", true);
|
||||
assertEquals("John Doe", customer.getName());
|
||||
|
||||
// search for all orders in state PLANNED and with customer
|
||||
List<Order> orders = new OrderSearch().types("Order").stateIsIn(State.PLANNED)
|
||||
.where(ExpressionsSupport.relationParam("customer").isEqualTo(customerId)).search(tx).toList();
|
||||
assertEquals(1, orders.size());
|
||||
// get articles
|
||||
List<Resource> articles = tx.getResourcesByRelation(order, "articles", true);
|
||||
assertEquals(2, articles.size());
|
||||
|
||||
// get products by stream
|
||||
List<Resource> products = articles.stream().map(a -> tx.getResourceByRelation(a, "product", true))
|
||||
.distinct().collect(Collectors.toList());
|
||||
assertEquals(1, products.size());
|
||||
|
||||
// search for all orders in state PLANNED and with customer
|
||||
List<Order> orders = new OrderSearch().types("Order").stateIsIn(State.PLANNED)
|
||||
.where(ExpressionsSupport.relationParam("customer").isEqualTo(customerId)).search(tx).toList();
|
||||
assertEquals(1, orders.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in New Issue