[New] Updated model documentation with simplified API

This commit is contained in:
Robert von Burg 2021-07-15 09:55:25 +02:00
parent a59272cfd2
commit a379d892eb
1 changed files with 163 additions and 135 deletions

View File

@ -9,6 +9,11 @@ be modelled in Strolch and use in Strolch:
![Strolch model example](/assets/images/strolch-model-example.png) ![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: A possible model would look as follows:
```xml ```xml
@ -60,158 +65,181 @@ A possible model would look as follows:
Let's go through this model: Let's go through this model:
* In the above model we see that the id and name fields are always on the * 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 element, and thus aren't added as parameters. Further best practice is to use
parameters ParameterBag, with one or more parameters, modelling the fields. a `parameters` ParameterBag, with one or more parameters, modelling the
* Note that in this example the Type of all the elements is Template. Strolch fields. There is API support to not have to always type the `parameters` bag
has API support to create a clone of these elements, so that they have a id.
unique ID, and the proper type for persistence. * Note that in this example the Type of all the elements is `Template`. Strolch
* The Product element has three parameters: description, color and form. In has API support to create a clone of these elements, so that they have a
this case they are all of type String. Further the relations ParameterBag unique id, and the proper type for persistence.
defines the relationships, i.e. the product knows its articles. Note how * The `Product` element has three parameters: `description`, `color` and `form`. In this
the relation is first defined in a relations ParameterBag and that the case they are all of type String. Further the `relations` ParameterBag defines
Parameter has Interpretation="Resource-Ref" Uom="Product" attributes. the relationships, i.e. the product knows its articles. Note how the relation
Strolch has API support for this, making it trivial to retrieve a dependency. is first defined in a relations ParameterBag and that the Parameter has
* The Article element has two parameters description and barcode. Further it `Interpretation="Resource-Ref" Uom="Product"` attributes. Strolch has API
has a reference to its Product. support for this, making it trivial to retrieve a dependency.
* The Order element doesn't model the date and state fields as parameters, as * The `Article` element has two parameters `description` and `barcode`. Further it has
these are inherently part of an Order element. The Order does define two a reference to its Product.
references to customer and articles. A special case is the quantities * The `Order` element doesn't model the `date` and `state` fields as parameters, as
ParameterBag. This bag of parameters is used to store the per article these are inherently part of an Order element. The Order does define two
quantity for this order. With ParameterBags, you can eliminate the use of references to customer and articles. A special case is the `quantities`
simple aggregate classes, as is commonly used in object-oriented programming. ParameterBag. This bag of parameters is used to store the per article quantity
* The Customer element models a address ParameterBag to store the address of for this order. With ParameterBags, you can eliminate the use of simple
a customer. Using a separate bag allows for further more direct fields to aggregate classes, as is commonly used in object-oriented programming.
stored on the default parameters bag. * 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 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 in how to create and interact with these elements at runtime. The following
listing will perform simple operations: listing will perform simple operations:
```java ```java
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, false)) { public class Example {
public static void main(String[] args) {
/*
* 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);
// keep IDs for later use // keep IDs for later use
dafalganId = dafalgan.getId(); String dafalganId;
dafalgan1Id = dafalgan1.getId(); String dafalgan1Id;
dafalgan2Id = dafalgan2.getId(); String dafalgan2Id;
customerId = customer1.getId(); String customerId;
orderId = order.getId(); String orderId;
/* // first transaction to create the data
* persist try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, false)) {
*/
tx.add(dafalgan);
tx.add(dafalgan1);
tx.add(dafalgan2);
tx.add(customer1);
tx.add(order);
// 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 ```java
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true)) { class Scratch {
public static void main(String[] args) {
// get order // keep IDs for later use
Order order = tx.getOrderBy("Order", orderId, true); String dafalganId;
assertNotNull(orderId); String dafalgan1Id;
assertEquals("Order for John Doe", order.getName()); String dafalgan2Id;
String customerId;
String orderId;
//
// .. snip ...
//
// get customer // second transaction to query the data
Resource customer = tx.getResourceByRelation(order, "customer", true); try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true)) {
assertNotNull(customer);
assertEquals("John Doe", customer.getName());
// get articles // get order
List<Resource> articles = tx.getResourcesByRelation(order, "articles", true); Order order = tx.getOrderBy("Order", orderId, true);
assertEquals(2, articles.size()); assertEquals("Order for John Doe", order.getName());
// get products // get customer
List<Resource> products = articles.stream().map(a -> tx.getResourceByRelation(a, "product", true)) Resource customer = tx.getResourceByRelation(order, "customer", true);
.distinct().collect(Collectors.toList()); assertEquals("John Doe", customer.getName());
assertEquals(1, products.size());
// search for all orders in state PLANNED and with customer // get articles
List<Order> orders = new OrderSearch().types("Order").stateIsIn(State.PLANNED) List<Resource> articles = tx.getResourcesByRelation(order, "articles", true);
.where(ExpressionsSupport.relationParam("customer").isEqualTo(customerId)).search(tx).toList(); assertEquals(2, articles.size());
assertEquals(1, orders.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());
}
}
} }
``` ```