ORM/DAO/DataMapper/ActiveRecord/TableGateway differences?
That would require a pretty long answer. Instead of repeating what others have said better and in more detail before me, I link you to some relevant pages. I suggest to look through them. Maybe follow a few additional links. Wikipedia is always a good start. If you still have any questions about one or the other pattern after going through the links, feel free to come back to SO and ask again. But if you do, try to narrow it down. It's better to ask multiple questions and focus on particular aspects than expecting people to write an essay for you.
Object Relational Mapper
Object-relational mapping (ORM, O/RM, and O/R mapping) in computer software is a programming technique for converting data between incompatible type systems in relational databases and object-oriented programming languages.
Data Access Object
Use a Data Access Object (DAO) to abstract and encapsulate all access to the data source. The DAO manages the connection with the data source to obtain and store data.
DataMapper
A layer of Mappers (473) that moves data between objects and a database while keeping them independent of each other and the mapper itself.
Active Record
An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.
Table Data Gateway
An object that acts as a Gateway (466) to a database table. One instance handles all the rows in the table.
What is the difference between the Data Mapper, Table Data Gateway (Gateway), Data Access Object (DAO) and Repository patterns?
Your example terms; DataMapper, DAO, DataTableGateway and Repository, all have a similar purpose (when I use one, I expect to get back a Customer object), but different intent/meaning and resulting implementation.
A Repository "acts like a collection, except with more elaborate querying capability" [Evans, Domain Driven Design] and may be considered as an "objects in memory facade" (Repository discussion)
A DataMapper "moves data between objects and a database while keeping them independent of each other and the mapper itself" (Fowler, PoEAA, Mapper)
A TableDataGateway is "a Gateway (object that encapsulates access to an external system or resource) to a database table. One instance handles all the rows in the table" (Fowler, PoEAA, TableDataGateway)
A DAO "separates a data resource's client interface from its data access mechanisms / adapts a specific data resource's access API to a generic client interface" allowing "data access mechanisms to change independently of the code that uses the data" (Sun Blueprints)
Repository seems very generic, exposing no notion of database interaction.
A DAO provides an interface enabling different underlying database implementations to be used.
A TableDataGateway is specifically a thin wrapper around a single table.
A DataMapper acts as an intermediary enabling the Model object to evolve independently of the database representation (over time).
Data Mapper vs Data access object. Difference. Which one is the better one?
Data mapper saves the data from (and restores to) domain object directly, while data access object would be used as intermediary for exchange of information between domain object and storage abstraction.
<update>
The main difference between two approaches is that data mapper temporary takes control of the domain object, while data access object either receives data indirectly (through some higher level abstraction, like Service) or is controlled (and in some implementations, even instantiated) by domain object.</update>
Neither of patterns is remotely related to active record (anti)pattern, which combines domain logic and storage abstraction in single instance, thus breaking SRP.
And none of mentioned patterns are tied to ORMs. Some ORMs try to use the above mentioned pattern for implementation, but they usually do a quite bad job at that.
Most of, what you call, "modern frameworks" use active record pattern and call the instances of it "models", which extreme simplification of concept, perpetuated by Rails.
DAO vs ORM - Concept explained in the context of Sequelize.js
Here's some thoughts which might help clarify it for you. I'm more familiar with ActiveRecord than Sequelize, so I'll run with that, but the concepts should be the same for both.
You have a database. You can, completely independent of Rails (eg. using a database admin tool), go and run a query on that database - something like "select * from users limit 1"
. But that just gives you a set of results in some admin window, which aren't much use to your Rails app. You want to be able to execute SQL from your Rails app, and get data back in a form that Ruby/Rails can work with. You need to Access
your Data
through some kind of ruby Object
- you need a Data Access Object
, or DAO
.
In rails, you could run the query above with something like:
result = ActiveRecord::Base.connection.execute("select * from users limit 1")
The result
variable won't know or care about your User
model. All it will contain is essentially a list of plain ruby Hash
instances, like:
{
"id" => "1234",
"email" => "fred@example.com",
"first_name" => "Fred",
"last_name" => "Flintstone",
}
If you wanted to update the first_name
to Bob
, you couldn't just edit that hash and call save on it - it's just a plain old hash, just the data and no extra smarts. So you'd have to write your own SQL again, and get Rails to execute it for you:
ActiveRecord::Base.connection.execute("update users set first_name = 'Bob' where id = 1234")
So what you're using in this context is basically just Rail's DAO
, without using it's ORM
.
The ORM
is like a layer on top of the DAO
. You can have a DAO
without an ORM
, but you can't have an ORM
without a DAO
. The ORM
, or Object Relational Mapper
will Map
concepts / records in your Relational
database with Objects
in your programming language (ie, Ruby). So, if you wanted to do the stuff above, using Rail's ORM
rather than using it's DAO
, it might look like:
user = User.find(1234)
user.name = 'Bob'
user.save!
See how much nicer it is using an ORM? Now, the snippet above, using the ORM, will still essentially just execute the same SQL we detailed earlier. The ORM just abstracts away more of the details and provides smarter objects to save us a bunch of extra work.
Again, the concepts demonstrated are transferable to Sequelize / Javascript and other langs/frameworks.
So a DAO
is just "an object that can execute SQL and return results in some basic data structure native to the programming language". An ORM
will ultimately use a DAO
to communicate with the database, but provides a whole lot more on top.
in Zend, Why do We use DB Model class and Mapper class as two separate?
DataMapper is a design pattern from Patterns of Enterprise Application Architecture.
The Data Mapper is a layer of software that separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other. With Data Mapper the in-memory objects needn't know even that there's a database present; they need no SQL interface code, and certainly no knowledge of the database schema.
How you store data in a relational database is usually different from how you would structure objects in memory. For instance, an object will have an array with other objects, while in a database, your table will have a foreign key to another table instead. Because of the object-relational impedance mismatch, you use a mediating layer between the domain object and the database. This way, you can evolve both without affecting the other.
Separating the Mapping responsibility in its own layer is also more closely following the Single Responsibility Principle. Your objects dont need to know about the DB logic and vice versa. This gives you greater flexibility when writing your code.
When you dont want to use a Domain Model, you usually dont need DataMapper. If your database tables are simple, you might be better off with a TableModule and TableDataGateway or even just ActiveRecord.
For various other patterns see my answer to
- ORM/DAO/DataMapper/ActiveRecord/TableGateway differences? and
- http://martinfowler.com/eaaCatalog/index.html
What does a Data Mapper typically look like?
From DataMapper in PoEA
The Data Mapper is a layer of software
that separates the in-memory objects
from the database. Its responsibility
is to transfer data between the two
and also to isolate them from each
other. With Data Mapper the in-memory
objects needn't know even that there's
a database present; they need no SQL
interface code, and certainly no
knowledge of the database schema. (The
database schema is always ignorant of
the objects that use it.) Since it's a
form of Mapper (473), Data Mapper
itself is even unknown to the domain
layer.
Thus, a Cat should not extend CatDataMapper because that would create an is-a relationship and tie the Cat to the Persistence layer. If you want to be able to handle persistence from your Cats in this way, look into ActiveRecord or any of the other Data Source Architectural Patterns.
You usually use a DataMapper when using a Domain Model. A simple DataMapper would just map a database table to an equivalent in-memory class on a field-to-field basis. However, when the need for a DataMapper arises, you usually won't have such simple relationships. Tables will not map 1:1 to your objects. Instead multiple tables could form into one Object Aggregate and viceversa. Consequently, implementing just CRUD methods, can easily become quite a challenge.
Apart from that, it is one of the more complicated patterns (covers 15 pages in PoEA), often used in combination with the Repository pattern among others. Look into the related questions column on the right side of this page for similar questions.
As for your question about multiple users editing the same Cat, that's a common problem called Concurrency. One solution to that would be locking the row, while someone edits it. But like everything, this can lead to other issues.
Related Topics
Check for Session Timeout in Laravel
Get_Instance() in Codeigniter: Why Assign It to a Variable
Group MySQL Results by Category and Display Them into Groups Under Each Category
How to Get a Service from the Container Directly, If I Didn'T/Couldn't Inject the Service Using Di
Shuffles Random Numbers with No Repetition in JavaScript/Php
How to Set an Absolute Include Path in PHP
PHP Merge Array(S) and Delete Double Values
PHP If Single or Double Equals
Fatal Error - Too Many Open Files
How to Format an Utc Date to Use the Z (Zulu) Zone Designator in PHP
Convert a JSON into a Utf-8 String
How to Start a Get/Post/Put/Delete Request and Judge Request Type in PHP
Laravel: Auth::User()->Id Trying to Get a Property of a Non-Object
How to Add a Method to an Existing Class in PHP
Regex Ignore Url Already in HTML Tags
Parse HTML Table Using File_Get_Contents to PHP Array