Love and Hate relationship between ORM and Query Builders
-
Upload
romans-malinovskis -
Category
Software
-
view
159 -
download
0
Transcript of Love and Hate relationship between ORM and Query Builders
Love and Hate between ORM and
Query Builders
Myself
‣ Love Web Apps
‣ 25 years of coding
‣ Entrepreneur
‣ I buy Software
My Startup
‣ Focused on Coders
‣ Learning curve
‣ Open-source
‣ Service/Paid
About Me
Make your first lines of code really matter.
Agile Toolkit
Download
Result
Make UI better
How
Agile UI Agile Data
Web Framework
DB
High-level Code
HTML CSSWidgets
How
Database Access Layer search quest
Query
‣ Control
‣ Advanced Features
‣ Multi-Record
ORM
‣ 10+ tables
‣ SoftDelete, Audit
‣ Domain Model
Database Interaction Today
MapperEntity Query
ORM: How it should work
Database
Business Logic
ORM
MapperEntity SQL Query
The Reality
SQL Database
Business Logic
ORM
no ORM
SQL Query
Why Bother…
SQL Database
Business Logic no ORM
Love Compatibility
Love Compatibility
Field Entity Relation Join
Raw SQL
Aliases
Query
Expression
ORM Components
Que
ry C
ompo
nent
s
Love Compatibility
Field Entity Relation Join
Raw SQL no some no no
Aliases some some no some
Query no yes no some
Expression no no some no
ORM Components
Que
ry C
ompo
nent
s
Business Opportunity
Database Access Framework that combine benefits of
ORM and Queries
Agile Data
Agile Data
Field Entity Relation Join
Raw SQL both ways both ways both ways yes
Aliases yes yes yes yes
Query both ways yes both ways both ways
Expression both ways yes both ways yes
ORM Components
Que
ry C
ompo
nent
s
Simple DemoaddExpression
Agile Data
Field Entity Relation Join
Raw SQL both ways both ways both ways yes
Aliases yes yes yes yes
Query both ways yes both ways both ways
Expression both ways yes both ways yes
ORM Components
Que
ry C
ompo
nent
s
PersistenceLine Query
Agile Data
Database
Business Logic
PersistenceLine Query
Agile Data
Database
Business Logic
PersistenceLine Query
Agile Data
Database
Business Logic
Invoice
Referencesand formulas
Agile Data
Field Entity Reference Join
Raw SQL both ways both ways both ways yes
Aliases yes yes yes yes
Query both ways yes both ways both ways
Expression both ways yes both ways yes
ORM Components
Que
ry C
ompo
nent
s
DataSet
Project
DataSet $m = new Project($db);
Project
$m = new Project($db); $m->addCondition( 'client_id', 1 );
client=1
Project
$m = new Project($db); $m->addCondition( 'client_id', 1 ); $m->addCondition( 'is_cancelled', false );
client=1client=1 is_cancelled = 0
Just a tip of an iceberg!
Agile Data
Field Entity Relation Join
Raw SQL both ways both ways both ways yes
Aliases yes yes yes yes
Query both ways yes both ways both ways
Expression both ways yes both ways yes
ORM Components
Que
ry C
ompo
nent
s
Entity to Query Builder
$q = $client->action('field', ['industry']);
$q->field('count(*)', 'c'); $q->group('industry');
$data = $q->get();
Mapper creates Query which you can then group and tweak for generating aggregated report
Raw into Field
$client->addExpression( 'balance', 'coalesce([total_invoice]-[total_paid],0)' );
Define custom SQL code for your field.
Query into Field
$client->addExpression('last_sale', function($m){ return $m->refLink('Invoice') ->setLimit(1) ->setOrder('date desc') ->action('field',['total']); }, 'type'=>'money' );
Convert Entity into Query then use inside Field / Expression.
Expression into Field
$book->addExpression('display_name', [ '[title] (by [])', $book->refLink('author_id') ->action('field', ['name']) ]);
Fetch author's name from related entity into a new Expression
Join on Expression
$invoice->hasOne('client_id', new Client()) ->addField('client_country_id', 'country_id');
$invoice->join('country', 'client_country_id') ->addFields([ 'country_short_code'=>'short_code', 'country_is_eu'=>'is_eu', 'country'=>'name'
If you need country data inside your Invoice report, but country_id
is defined through Client.
Aliasing
Self-referencingclass Folder extends \atk4\data\Model { public $table = 'folder'; public function init() { parent::init(); $this->addField('name');
$this->hasMany('SubFolder', [ new Folder(), 'their_field'=>'parent_id'] )->addField('count', [ 'aggregate'=>'count', 'field'=>$this->expr('*')] );
$this->hasOne('parent_id', new Folder()) ->addTitle(); } }
Unique Aliases
select `id`,`name`,
(select count(*) from `folder` `S` where `parent_id` = `folder`.`id`) `count`,
`folder`.`parent_id`,
(select `name` from `folder` `p` where `id` = `folder`.`parent_id`) `parent` from `folder`
Union
$q_inv = $client->ref('Invoice') ->action('field',['date','total']); $q_pay = $client->ref('Payment') ->action('field',['date','paid']);
foreach($db->expr( 'select * from ([] UNION []) u1', $q_inv, $q_pay ) as $row) { /// }
And the best part..
Deep Traversal
$author->withID(20) ->ref('App') ->ref('Review') ->ref('user_id') ->ref('country_id') ->action('field', ['name']) ->field('count(*)') ->group('name') ->get(); // 1 QUERY!!
There are only 2 basic relation type. OneToMany. OneToOne. BUT!!
git.io/ad
✓Works in any framework / PHP app ✓ Lightweight and Agile ✓ Integrates with UI frameworks (like ATK) ✓ Commercial Support
Agile Data is Open-Source
✓ ACL, Audit, Undo, Logging, .. ✓ File Management ✓ Import/Export utility ✓ RestAPI server
Commercial Extensions
git.io/ad