I have a class with multiple value types.
I want to save it as key-value pair.
Let's say we have a class
class MyClass{
String p1;
Double p2;
}
I want it in DB as
id | a | b | c
1 | - | - | -
id |fkId | propetyName | propertyValue
1 |1 | p1 | hello
2 |1 | p2 | 10
Related
Suppose we have 3 entities named A, B, and C. And Relations between these Entities are something like this:
A -- one to many --> B
B -- many to many --> C
Example tables:
A
| id |
| -- |
| 1 |
| 2 |
B
| id | a_id |
| -- | -- |
| 1 | 1 |
| 2 | 2 |
B_C
| b_id | c_id |
| -- | -- |
| 1 | 1 |
| 2 | 2 |
C
| id |
| -- |
| 1 |
| 2 |
If we wanna make the relationship between A and C in laravel, what should we do? is it possible at all?
For these situations, you can use Has Many Through relationships and for more information, you can follow the laravel documentation.
to get the relation between your A and C model you can use has many though like this:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class A extends Model
{
public function c()
{
return $this->hasManyThrough(
C::class,
B::class,
'a_id', // Foreign key on the a table...
'b_id', // Foreign key on the b table...
'id', // Local key on the a table...
'id' // Local key on the b table...);
}
}
The first argument passed to the hasManyThrough method is the name of the final model we wish to access, while the second argument is the name of the intermediate model.
I have a database like this.
+----------------+
| Tables_in_test |
+----------------+
| a_b |
| a_c |
| as |
| bs |
| cs |
+----------------+
bs and cs tables have many to many relationship with as table. So a_b table and a_c table are pivot tables.
This is as table
+----+------+
| id | name |
+----+------+
| 1 | A1 |
| 2 | A2 |
+----+------+
This is bs table
+----+------+
| id | name |
+----+------+
| 1 | B1 |
+----+------+
And this is cs table
+----+------+------+
| id | b_id | name |
+----+------+------+
| 1 | 1 | C1 |
| 2 | 1 | C2 |
+----+------+------+
this is a_b pivot table
+------+------+
| a_id | b_id |
+------+------+
| 1 | 1 |
+------+------+
And this is a_c pivot table.
+------+------+
| a_id | c_id |
+------+------+
| 1 | 1 |
| 2 | 2 |
+------+------+
And this is my A model for the as table.
class A extends Model
{
protected $table = "as";
public function b(){
return $this->belongsToMany("App\B");
}
public function c(){
return $this->belongsToMany("App\C");
}
}
And this is B model for bs table
class B extends Model
{
protected $table = "bs";
public function c(){
return $this->hasMany("App\C");
}
}
I just want to query C table values as related to A table.
I tried this query
A::where("id",1)->with("b.c")->get();
But this result also gives me C2 value which is related to A2 in "as" table. I want to get only C1 value which is related only A1 value in "as" table.
How can I do this ? Thank you for your help
In your example data A1 relates to B1 which in turn relates to C2. And you are in fact nesting the b.c eager load, so you are loading Bs and Cs related to those Bs.
Have you tried A::where("id",1)->with(["b", "c"])->get();
?
I have two tables in a database:
Grade
+--------+--------------+-----------------+
| int id | varchar name | varchar teacher |
+--------+--------------+-----------------+
| 1 | CL-2A | E. Wright |
| 2 | CL-2B | B. Springsteen |
+--------+--------------+-----------------+
Student
+--------+------------------+-----------+
| int id | varchar name | int grade |
+--------+------------------+-----------+
| 1 | Michael Wallings | 1 |
| 2 | Rowen Tress | 1 |
| 3 | Alys Harverd | 2 |
| 4 | Jeff Bass | 1 |
| 5 | Harry Farewell | 2 |
+--------+------------------+-----------+
As you've probably seen already, Student.grade refers to Grade.id with a foreign key.
Now I've made some entity objects for both tables. But how do I implement to relation between Student and Grade?
public class Student {
private int id;
private String name;
private int grade; // Keep the grade as an int.
...
or
public class Student {
private int id;
private String name;
private Grade grade; // Hold a reference to the corresponding entity object Grade.
...
or something?
The second code snippet requires me to also get the grade entity object derived from the database.
I'm trying to produce a web page report of Orders Per Customer with line item details for each order.
So it looks like this:
Customer 1 | Order 1 | Item 1 |
| | == New Row == |
| | Item 2 |
| | == New Row == |
| | Item 3 |
| | == New Row == |
| ====== New Row ========= |
| Order 2 | Item 1 |
| | == New Row == |
| | Item 2 |
| | == New Row == |
| | Item 3 |
| | == New Row == |
| ====== New Row ========= |
| Order 3 | Item 1 |
| | Item 2 |
== New Row ==============================
Customer 2 | Order 1 | Item 1 |
| | == New Row == |
| | Item 2 |
| | == New Row == |
| | Item 3 |
| | == New Row == |
| | Item 4 |
| | == New Row == |
| | Item 5 |
| | == New Row == |
| ====== New Row ========= |
| Order 2 | Item 1 |
| | == New Row == |
| | Item 2 |
| | == New Row == |
| | Item 3 |
== New Row ==============================
Is it better to get an array list of data as follows:
1 | 1 | 1 |
1 | 1 | 2 |
1 | 1 | 3 |
1 | 2 | 1 |
1 | 2 | 2 |
1 | 2 | 3 |
1 | 3 | 1 |
1 | 3 | 2 |
2 | 1 | 1 |
2 | 1 | 2 |
2 | 1 | 3 |
2 | 1 | 4 |
2 | 1 | 5 |
2 | 2 | 1 |
2 | 2 | 2 |
2 | 2 | 3 |
and pass 1 JavaBean and use JSTL to determine the nesting as follows:
this is incomplete for brevity
<table><tr><th>Customer No</th><th>Orders</th></tr>
<c:forEach var="custOrderLineItem" items="${customerOrderLineItemList}">
<c:set var="currentOrder" value="custOrderLineItem.orderId">
<c:set var="currentCustomer" value="custOrderLineItem.customerId">
<c:if test="${currentOrder != custOrderLineItem.orderId}">
==New Row==
</c:if>
or is it better to use nested JavaBeans
Customer.setOrders<List>
Orders.setOrderDetails<List>
OrderDetails.setLineItem<List>
and then use JSTL as such
<c:forEach var="customer" items="${customerList}">
<c:forEach var="order" items="${customer.orderList}">
<c:forEach var="lineItem" items="${order.detailList}">
After spending the time writing this, I feel like the second method looks cleaner and easier. But the first method seems to have an easier SQL query. I'm not using JPA, just basic JDBC sql calls. So how does one populate nested JavaBeans, without JPA? Do you do something like this?
List<Customer> custList = getCustomerList();
ListIterator custListIter = custList.listIterator();
while (custListIter.hasNext()) {
customer = (Customer) custListIter.next();
List<Order> orderList = getOrderList(customer.getId());
ListIterator orderListIter = orderList.listIterator();
while (orderListIter.hasNext()) {
order = (Order) orderListIter.next();
List orderDetailsList<OrderDetail> = getOrderDetailList(order.getId);
order.setOrderDetails(orderDetailsList);
orderListIter.set(order);
}
customer.setOrderList(orderList);
custListIter.set(customer);
}
You could simply make the SQL query which returns everything, and build the graph of objects from the result set. Using maps to keep an association between IDs and the corresponding objects:
Map<Long, Customer> customersById = new HashMap<Long, Customer>();
Map<Long, Order> ordersById = new HashMap<Long, Order>();
Map<Long, Item> itemsById = new HashMap<Long, Item>();
while (rs.next()) {
Long customerId = rs.getLong(1);
Customer customer = customersById.get(customerId);
if (customer == null) {
customer = new Customer(customerId);
// populate other fields of customer
customersById.put(customerId, customer);
}
Long orderId = rs.getLong(5);
Order order = ordersById.get(orderId);
if (order == null) {
order = new Order(orderId);
customer.addOrder(order);
// populate other fields of order
ordersById.put(orderId, order);
}
// same for items
}
At the end of the loop, you have all the customers, each with their orders, each with their items.
I'm new to datamapper. I have a problem on trying to duplicate a result into a new id.
This is a simplified table for my database:
Job Table
| id | property_id | name | type |
| 1 | 1 | abc | i |
| 2 | 2 | def | ii |
Property Table
| id | job_id | size |
| 1 | 1 | 90 |
| 2 | 2 | 40 |
How can I automatically duplicate a new job based on job id 1 into new job/property id like
Job Table
| id | property_id | name | type |
| 1 | 1 | abc | i |
| 2 | 2 | def | ii |
| 3 | 3 | abc | i |
Property Table
| id | job_id | size |
| 1 | 1 | 90 |
| 2 | 2 | 40 |
| 3 | 3 | 90 |
Thanks for helping! :)
In the documentation for DataMapper Overzealous Edition: http://datamapper.wanwizard.eu/pages/clonecopy.html There's clone and copy, copy will clear the id. Here's their example, just skip the part of making changes:
// Let's save a new hosting plan
$p = new Plan();
$p->name = 'The 100GB Plan';
$p->storage = 1000;
$p->bandwidth = 2000;
$p->databases = 5;
$p->domains = 5;
$p->emails = 50;
$p->save();
// Now, lets make a copy of that saved plan and base a new one off of it
$p = $p->get_copy();
// Change only what we need to
$p->name = 'The Big 150GB Plan';
$p->storage = 1500;
$p->bandwidth = 2500;
// And now save a new record
$p->save();
You can also just modify the object you retrieve, and then use save_as_new() to save it as a new record.