Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 3 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Someone suggested I use an ORM for a project that I'm designing, but I'm having trouble finding information on what it is or how it works.
Can anyone give me a brief explanation of what an ORM is and how it works and how I should get started using one?
Introduction
Object-Relational Mapping (ORM) is a technique that lets you query and manipulate data from a database using an object-oriented paradigm. When talking about ORM, most people are referring to a library that implements the Object-Relational Mapping technique, hence the phrase "an ORM".
An ORM library is a completely ordinary library written in your language of choice that encapsulates the code needed to manipulate the data, so you don't use SQL anymore; you interact directly with an object in the same language you're using.
For example, here is a completely imaginary case with a pseudo language:
You have a book class, you want to retrieve all the books of which the author is "Linus". Manually, you would do something like that:
book_list = new List();
sql = "SELECT book FROM library WHERE author = 'Linus'";
data = query(sql); // I over simplify ...
while (row = data.next())
{
book = new Book();
book.setAuthor(row.get('author');
book_list.add(book);
}
With an ORM library, it would look like this:
book_list = BookTable.query(author="Linus");
The mechanical part is taken care of automatically via the ORM library.
Pros and Cons
Using ORM saves a lot of time because:
DRY: You write your data model in only one place, and it's easier to update, maintain, and reuse the code.
A lot of stuff is done automatically, from database handling to I18N.
It forces you to write MVC code, which, in the end, makes your code a little cleaner.
You don't have to write poorly-formed SQL (most Web programmers really suck at it, because SQL is treated like a "sub" language, when in reality it's a very powerful and complex one).
Sanitizing; using prepared statements or transactions are as easy as calling a method.
Using an ORM library is more flexible because:
It fits in your natural way of coding (it's your language!).
It abstracts the DB system, so you can change it whenever you want.
The model is weakly bound to the rest of the application, so you can change it or use it anywhere else.
It lets you use OOP goodness like data inheritance without a headache.
But ORM can be a pain:
You have to learn it, and ORM libraries are not lightweight tools;
You have to set it up. Same problem.
Performance is OK for usual queries, but a SQL master will always do better with his own SQL for big projects.
It abstracts the DB. While it's OK if you know what's happening behind the scene, it's a trap for new programmers that can write very greedy statements, like a heavy hit in a for loop.
How to learn about ORM?
Well, use one. Whichever ORM library you choose, they all use the same principles. There are a lot of ORM libraries around here:
Java: Hibernate.
PHP: Propel or Doctrine (I prefer the last one).
Python: the Django ORM or SQLAlchemy (My favorite ORM library ever).
C#: NHibernate or Entity Framework
If you want to try an ORM library in Web programming, you'd be better off using an entire framework stack like:
Symfony (PHP, using Propel or Doctrine).
Django (Python, using a internal ORM).
Do not try to write your own ORM, unless you are trying to learn something. This is a gigantic piece of work, and the old ones took a lot of time and work before they became reliable.
ORM stands for "Object to Relational Mapping" where
The Object part is the one you use with your programming language ( python in this case )
The Relational part is a Relational Database Manager System ( A database that is ) there are other types of databases but the most popular is relational ( you know tables, columns, pk fk etc eg Oracle MySQL, MS-SQL )
And finally the Mapping part is where you do a bridge between your objects and your tables.
In applications where you don't use a ORM framework you do this by hand. Using an ORM framework would allow you do reduce the boilerplate needed to create the solution.
So let's say you have this object.
class Employee:
def __init__( self, name ):
self.__name = name
def getName( self ):
return self.__name
#etc.
and the table
create table employee(
name varcar(10),
-- etc
)
Using an ORM framework would allow you to map that object with a db record automagically and write something like:
emp = Employee("Ryan")
orm.save( emp )
And have the employee inserted into the DB.
An ORM (Object Relational Mapper) is a piece/layer of software that helps map your code Objects to your database.
Some handle more aspects than others...but the purpose is to take some of the weight of the Data Layer off of the developer's shoulders.
Here's a brief clip from Martin Fowler (Data Mapper):
Patterns of Enterprise Application Architecture Data Mappers
Like all acronyms it's ambiguous, but I assume they mean object-relational mapper -- a way to cover your eyes and make believe there's no SQL underneath, but rather it's all objects;-). Not really true, of course, and not without problems -- the always colorful Jeff Atwood has described ORM as the Vietnam of CS;-). But, if you know little or no SQL, and have a pretty simple / small-scale problem, they can save you time!-)
Object Model is concerned with the following three concepts
Data Abstraction
Encapsulation
Inheritance
The relational model used the basic concept of a relation or table.
Object-relational mapping (OR mapping) products integrate object programming language capabilities with relational databases.
I'm interested in learning more about design practices in PHP for Database Abstraction & Factory methods. For background, my site is a common-interest social networking community currently in beta mode.
Currently, I've started moving my old code for object retrieval to factory methods. However, I do feel like I'm limiting myself by keeping a lot of SQL table names and structure separated in each function/method.
Questions:
Is there a reason to use PDO (or similar) if I dont anticipate
switching databases?
Can PDO interface with the MySqli prepared statements I
currently use?
Will it help me separate table names from each method? (If no, what
other design patterns might I want
to research?)
Will it slow down my site once I have a significantly large member base?
Nettuts recently had an article on some of the benefits to using PDO.
As for your question regarding abstraction, you might look into Object Relational Mapping (ORM) which lets you access database records the same way you would native php objects. Most of my experience has been with the Kohana framework, and I like how their ORM works, but many of the popular php frameworks should have good examples of database abstraction methods. I find that reading where someone else did it the "right" way helps me out.
I would like to second Rookwood on looking at ORM. I have had good experciences with Doctrine. Building something yourself would be a waste of your time in moste cases.
I would recommend using PEAR or PDO.. why?
1) It's tested and used by tens of thousands of programmers. If you need another programmer to help you, there is a good chance they know PDO. There is basically zero chance they will know your API.
2) You don't think you will change databases.... BUT, what if a version change or something like that happens that forces you to migrate?
I've currently got a site that depends on an Active Record pattern using the Doctrine ORM in PHP. I'm generally a fan of this approach - it's very straightforward and works well for managing for simple CRUD apps. But as this site grows, I think my need for more robust domain functionality will grow as well. I was wondering what other kinds of data design patterns work well in conjunction with an ORM.
My basic problem right now is that Doctrine seems to work best as a fancy querying language, so my models are littered with methods like:
function getBySomeClassfication($classification)
{
return Doctrine_Query::create()
->select('stuff')
->from('ModelClass')
->where('something = ?', $classification)
->execute();
}
or if I want to access a model class directly:
Doctrine::getTable('ModelClass')->findAll();
This means I end up working with Doctrine's object wrappers instead of directly on my domain objects. I feel like all this should exist at a lower level of abstraction.
I'm just not quite sure what the best approach is. I feel like the ORM is an excellent layer for querying single tables and dealing with relationships. But I'd like to have more flexibility in creating domain objects that work across multiple models/tables.
I've read up on using the Repository pattern, but still have a few hesitations:
I don't want to just create a pointless layer of abstraction that simply bubbles up the original problem.
I don't want to re-create or render useless the whole point of using an Active Record ORM.
Any thoughts or suggestions?
You need to work with the object wrappers (Data Access Objects) at some point and at some point your calls will be implementation (here Doctrine-) specific. It mainly depends on your current architecture on how many layers you want to put in between, but I would say - as less as possible. Is there any specific problem you have that Doctrine doesn't solve?
I sometimes don't see the point in having to deal with database specifics (e.g. one Domain Entity spreading over several tables) at all when using the ORM as a tool for (from scratch) Object Oriented Domain Model development.
I recently answered a more Java specific question here, but maybe it helps you, too for the architecture idea.
You might have a look at the Zend Framework ORM implementation(if you haven't already) where it is also possible to define relationships across multiple tables.
I hope that helps.
The Problem: Object models built using an ORM often need to perform multiple queries to perform a single action. For example a "get" action may pull information from multiple tables, particularly when you have a nested object structure. On complicated requests these queries can add up and your database will start blocking long before it would if you were manually writing SQL.
The Question: Where do you load balance the ORM to cut down on the number of queries that need to be made, and more importantly why did you choose this approach? Do you have separate models to load data dependent on context, or do you specify which data should load in the controller? Or something else?
ORM is really there for a good reason -- to speed up your development.
If performance becomes an issue for me, I'd rather implement some caching mechanisms instead of taking a step back and hard-coding SQL.
I recommend using the Domain Model pattern, to provide an interface to data data in an OO-friendly way. As part of the implementation of persistence within your Domain Model classes, it's appropriate to use a mix of ORM and SQL.
For instance, you'll have some simple queries against a single table. Use a convenient ActiveRecord pattern for this. But as you describe, you'll also typically need some complex queries against multiple tables for more complex related data. ActiveRecord is a clumsy solution in this case, so use plain SQL. It's the best tool when you need a complex query with relational operators like JOIN or GROUP BY.
#pestaa mentions caching which is another good tool. Here's another one you can consider: Identity Map. The point is that you should learn multiple tools, and think about which one is the best in any given situation.
Trying to use only one pattern for every situation is like driving your car everywhere in first gear.
A lot of it depends on the ORM, its philosophy and features. But assuming you've got a good set of model classes between your ORM and the rest of your application, you can do the following:
Provide methods in your models that provide the right amount of depth for most cases. If your ORM doesn't allow you to specify things efficiently, consider a different ORM (if you have that luxury)
Plan and implement caching. Since we're talking in a data-centric context, this means writing/leveraging data caching in your model.
Have a plan to split reads from writes. Either in your model or ORM configuration. Especially if reads are your bottleneck, using some replication to create a gang of read-only slaves can be immensely useful. However, if you don't plan for it, you can easily design yourself into a position where it's a pain.
This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
Is there a good object-relational-mapping library for PHP?
I know of PDO/ADO, but they seem to only provide abstraction of differences between database vendors not an actual mapping between the domain model and the relational model. I'm looking for a PHP library that functions similarly to the way Hibernate does for Java and NHibernate does for .NET.
Look into Doctrine.
Doctrine 1.2 implements Active Record. Doctrine 2+ is a DataMapper ORM.
Also, check out Xyster. It's based on the Data Mapper pattern.
Also, take a look at DataMapper vs. Active Record.
Try RedBean, its requires:
No configuration
No database (it creates everything on the fly)
No models
etc.
It even does all the locking and transactions for you and monitors performance in the background. (Heck! it even does garbage collection....) Best of all... you don't have to write a single... line of code... Jesus this, ORM layer, saved me ass!
There are only two good ones: Doctrine and Propel. We favor Doctrine, and it works well with Symfony. However if you're looking for database support besides the main ones you'll have to write your own code.
Axon ORM is part of the Fat-Free Framework - it features an on-the-fly mapper. No code generators. No stupid XML/YAML configuration files. It reads the database schema directly from the backend, so in most CRUD operations you don't even have to extend a base model. It works with all major PDO-supported database engines: MySQL, SQLite, SQL Server/Sybase, Oracle, PostgreSQL, etc.
/* SQL */
CREATE TABLE products (
product_id INTEGER,
description VARCHAR(128),
PRIMARY KEY (product_id)
);
/* PHP */
// Create
$product=new Axon('products'); // Automatically reads the above schema
$product->product_id=123;
$product->description='Sofa bed';
$product->save(); // ORM knows it's a new record
// Retrieve
$product->load('product_id=123');
echo $product->description;
// Update
$product->description='A better sofa bed';
$product->save(); // ORM knows it's an existing record
// Delete
$product->erase();
Most of all, the plug-in and accompanying SQL data access layer are just as lightweight as the framework: 14 KB (Axon) + 6 KB (SQLdb). Fat-Free is just 55 KB.
I've been developing Pork.dbObject on my own. (A simple PHP ORM and Active Record implementation)
The main reason is that I find most ORMs too heavy.
The main thought of Pork.dbObejct is to be light-weight and simple to set up. No bunch of XML files, just one function call in the constructor to bind it, and an addRelation or addCustomRelation to define a relation to another dbObject.
Give it a look: Pork.dbObject
Try Doctrine2. It's probably the most powerful ORM tool for PHP. I'm mentioning it separately from Doctrine 1, because it's a completely different piece of software. It's been rewritten from scratch, is still in beta phase, but it's usable now and developed.
It's a very complex ORM, but well designed. Lot of magic from original Doctrine 1 disappeared. It provides a complete solution, and you can write your own ORM on top of Doctrine2 or use just one of its layers.
I just started with Kohana, and it seems the closest to Ruby on Rails without invoking all the complexity of multiple configuration files like with Propel.
I really like Propel, here you can get an overview, the documentation is pretty good, and you can get it through PEAR or SVN.
You only need a working PHP5 install, and Phing to start generating classes.
Check out Outlet ORM. It is simpler than Propel and Doctrine and it works similar to Hibernate, only with more of a PHP feel to it.
I found ORM related classes in the PHP library Flourish.
You should check out Idiorm and Paris.
Give a shot to dORM, an object relational mapper for PHP 5. It supports all kinds of relationships (1-to-1), (1-to-many), (many-to-many) and data types. It is completely unobtrusive: no code generation or class extending required. In my opinion it is superior to any ORM out there, Doctrine and Propel included. However, it is still in beta and might change significantly in the next couple months. http://www.getdorm.com
It also has a very small learning curve. The three main methods you will use are:
<?php
$object = $dorm->getClassName('id_here');
$dorm->save($object);
$dorm->delete($object);
I am currently working on phpDataMapper, which is an ORM designed to have simple syntax like Ruby's Datamapper project. It's still in early development as well, but it works great.
I have had great experiences with Idiorm and Paris. Idiorm is a small, simple ORM library. Paris is an equally simple Active Record implementation built on Idiorm. It's for PHP 5.2+ with PDO. It's perfect if you want something simple that you can just drop into an existing application.
Tried the ORM of Flourish library.
Until PHP 5.3 release don't expect to have a good ORM. It's a OO limitation of PHP.
My friend Kien and I have improved upon an earlier version of an ORM that he had written prior to PHP 5.3. We have essentially ported over Ruby on Rails' Active Record to PHP. It is still lacking some key features we want such as transactions, composite primary key support, a few more adapters (only MySQL and SQLite 3 work right now). But, we are very close to finishing this stuff up. You can take a look at PHP ActiveRecord with PHP 5.3.
Try PHP ADOdb.
I can't say it's the best, because I haven't used the others. But it's fast, it supports Memcached and caching.
And it's waaaay faster than Zend Framework's DB/Select.
Have a look at the LEAP ORM for Kohana. It works with a bunch of databases, including DB2, Drizzle, Firebird, MariaDB, SQL Server, MySQL, Oracle, PostgreSQL, and SQLite. With a simple autoload function, it can work with almost any PHP framework. The source code is on GitHub at https://github.com/spadefoot/kohana-orm-leap. You can checkout LEAP's tutorials online.
The ORM library works with non-integer primary keys and composite keys. Connections are managed via a database connection pool and it works with raw SQL queries. The ORM even has a query builder that makes building SQL statements super simple.
Brazilian ORM: http://www.hufersil.com.br/lumine. It works with PHP 5.2+. In my opinion, it is the best choice for Portuguese and Brazilian people, because it has easy-to-understand documentation and a lot of examples for download.
You can check out Repose if you are feeling adventurous. Like Outlet, it is modeled after Hibernate.
It is still very early in its development, but so far the only restrictions on the domain model are that the classes are not marked final and properties are not marked private. Once I get into the land of PHP >= 5.3, I'll try to implement support for private properties as well.
If you are looking for an ORM that implements the Data Mapper paradigm rather than Active Record specifically, then I would strongly suggest that you take a look at GacelaPHP.
Gacela features:
Data mapper
Foreign key mapping
Association mapping
Dependent mapping
Concrete table inheritance
Query object
Metadata mapping
Lazy & eager loading
Full Memcached support
Other ORM solutions are too bloated or have burdensome limitations when developing anything remotely complicated. Gacela resolves the limitations of the active record approach by implementing the Data Mapper Pattern while keeping bloat to a minimum by using PDO for all interactions with the database and Memcached.
MicroMVC has a 13 KB ORM that only relies on a 8 KB database class. It also returns all results as ORM objects themselves and uses late static binding to avoid embedding information about the current object's table and meta data into each object. This results in the cheapest ORM overhead there is.
It works with MySQL, PostgreSQL, and SQLite.
Agile Toolkit has its own unique implementation of ORM/ActiveRecord and dynamic SQL.
Introduction: http://agiletoolkit.org/intro/1
Syntax (Active Record):
$emp=$this->add('Model_Employee');
$emp['name']='John';
$emp['salary']=500;
$emp->save();
Syntax (Dynamic SQL):
$result = $emp->count()->where('salary','>',400)->getOne();
While Dynamic SQL and Active Record/ORM is usable directly, Agile Toolkit further integrates them with User Interface and jQuery UI. This is similar to JSF but written in pure PHP.
$this->add('CRUD')->setModel('Employee');
This will display AJAXified CRUD with for Employee model.
NotORM
include "NotORM.php";
$pdo = new PDO("mysql:dbname=software");
$db = new NotORM($pdo);
$applications = $db->application()
->select("id, title")
->where("web LIKE ?", "http://%")
->order("title")
->limit(10)
;
foreach ($applications as $id => $application) {
echo "$application[title]\n";
}
Look at http://code.google.com/p/lworm/ . It is a really simple, but powerful, lightweight ORM system for PHP. You can also easily extend it, if you want.
Another great open source PHP ORM that we use is PHPSmartDb. It is stable and makes your code more secure and clean. The database functionality within it is hands down the easiest I have ever used with PHP 5.3.
Doctrine is probably your best bet. Prior to Doctrine, DB_DataObject was essentially the only other utility that was open sourced.
If you are looking for an ORM, like Hibernate, you should have look at PMO.
It can be easily integrated in an SOA architecture (there is only a webservice classe to develop).
A really good simple ORM is MyActiveRecord. MyActiveRecord documentation. I have been using it a lot and can say it's very simple and well tested.