Love and Hate relationship between ORM and Query Builders

Post on 13-Apr-2017

159 views 0 download

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