Jump to content

Can an ORM do this?


Recommended Posts

I've never used a ORM before and have always wondered why bother.  I am definitely stronger in SQL than OOP, and it just seemed easier/better to just perform some query.

I've recently, however, been forcing myself to use entities and mappers and am starting to see the light.

Question.  Can a 3rd party ORM be used to create $obj such as shown below and then determine which records in the database need to be updated to reflect what was changed in the object?

Also, can an ORM such as Doctrine deal with recursive queries?

Lastly, I would appreciate better understanding the benefits of using an ORM.  I've read that they provide benefits such as Productivity, Application design, Code Reuse, and Application Maintainability, but I am looking for some of the specifics which allow them to meet these goals.

Thanks

$obj=Class1($stmt1->fetch(), Class2($stmt2->fetch()), Class3($stmt3->fetch()));
$obj->methodA(123);
$obj->methodBwhichSomehowUsesClass2(321);


 

Link to comment
Share on other sites

Yes, an ORM can do it in general, but you're almost guaranteed to have to create some sort of mapper. Possibly involving direct queries. Which means you'll need a fancier ORM than just a simple table-class/column-property translator.

Yes, ORMs can typically deal with recursive queries at a basic level. I'm not entirely sure what you mean by a recursive query, though.

Like many things in software, an ORM is supposed to give you a wheel so you don't have to invent it yourself. Given comparable skills and experience, an ORM or any framework will be less efficient and effective than a custom solution, but the main selling point for frameworks is the time you'll save by using them. And apparently the majority of programmers like seeing immediate results and quick payoffs, so saving time appeals to them.

Link to comment
Share on other sites

MySQL didn't support WITH RECURSIVE until 8.0 so I assume you'd have a hard time finding an ORM that supports it.

But keep in mind that the queries an ORM will design won't necessarily/often be the same ones you come up with. If you know your queries need to be more complex than simple SELECTs with occasional JOINs then you might want to go for a minimalist ORM after all: one that lets you map query resultsets to objects (virtually all do) and maybe do the reverse too.

 

I don't have a favorite PHP ORM. I loved Entity Framework back in my .NET days, while people in the Java world tend to like Hibernate, which I believe has a PHP port if you're curious. But I think Doctrine's is the de facto standard for PHP.

Link to comment
Share on other sites

Based on what little I know of Doctrine I think it supports what I'm thinking of. Basically, it's an ORM with a very dumb mapper. Simple dumb, not bad dumb. It's smart enough to understand how to map columns to properties, possibly with some phpdoc markup, but that's about it. You can execute a query then tell it to map the results to a set of classes, then it constructs the objects and fills in the properties. When saving, it reads the properties and sets up INSERT or UPDATE queries according to the primary/unique keys.

Code might look like

<?php

namespace Db;

class User {
  
  use \ORM\Trait\Entity; // provides find, query, save methods
  
  /**
   * @ORM\Column
   */
  public $active = false;
  
  /**
   * @ORM\Column primary=true
   */
  public $id = 0;
  
  /**
   * @ORM\Column
   * @var \DateTime
   */
  public $last_active = null;
  
}
<?php

$users = Db\User::find("last_active < NOW() - INTERVAL 1 YEAR");
// $users = Db\User::query("SELECT * FROM users WHERE last_active < NOW() - INTERVAL 1 YEAR");

foreach ($users as $u) {
  $u->active = false;
  $u->save();
}

You can probably extrapolate how it works from there.

Like I said, I think Doctrine can do something like that. At least I know one of the popular ORMs can, even if I don't remember which framework it came with/from.

Link to comment
Share on other sites

Most of the 'ORMs' across the popular web development languages are 'ActiveRecord' clones.  On the surface of things, ActiveRecord is attractive to people for its simplicity.  It offers a 1-1 mapping between a database table and a class.  As the underlying design pattern for Laravel's eloquent and the ORM for most of the popular frameworks of the old school PHP days (Cake, Yii, Lithium, etc.), ActiveRecord leads to simple code like:

 

$artist->setName('Robert Plant');
$artist->save();

Doctrine on the other hand is a 'Data-mapper' implementation, which is different design pattern.  

The first thing you notice is that you don't have the wonky $class-save() method.  Instead you have an entity manager that keeps track of objects and saves things for you as needed when that is important.  In cases where you might be adding a number of different objects within a transaction, the entity manager fits the underlying RDBMS transaction system.

With ActiveRecord, you are never far from the underlying structure of a table.  Doctrine2 on the other hand, is really trying to insulate you from the individual tables.  For example, you can define the relationships between classes and after you've done that, you can interact with the related classes naturally, rather than having to manage each individual table or do joins.  

It separates searching and querying from the model/relational mapping into repositories, which keeps the actual object classes a lot leaner.  You can have custom repository classes if you want them, but basic searching on one or more attributes comes as a built in.

Doctrine has event handlers that let you create the equivalent of trigger code that executes when an entity is inserted or updated.  At the point that you're creating something sophisticated, it provides you a features that go beyond what ActiveRecord can.  

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.