什么是对象关系映射框架?

正如标题所说: 什么是 ORM 框架,它有什么用处?

99114 次浏览

From wikipedia:

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. This creates, in effect, a "virtual object database" that can be used from within the programming language. There are both free and commercial packages available that perform object-relational mapping, although some programmers opt to create their own ORM tools.

It's good for abstracting the datastore (flat file / SQL / whatever) out in order to provide an interface that can be used in your code. For example, (in rails) instead of constructing SQL to find the first user in a users table, we could do this:

User.first

Which would return us an instance of our user model, with the attributes of the first user in the users table.

From Wikipedia: http://en.wikipedia.org/wiki/Object-relational_mapping

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. This creates, in effect, a "virtual object database" that can be used from within the programming language. There are both free and commercial packages available that perform object-relational mapping, although some programmers opt to create their own ORM tools.

Pros and cons ORM often reduces the amount of code needed to be written, making the software more robust (the fewer the lines of code in a program, the fewer the errors contained within them).[1].

There are costs as well as benefits for using O/R mapping. For instance, some O/R mapping tools do not perform well during bulk deletions of data. Stored procedures may have better performance but are not portable.

A simple answer is that you wrap your tables or stored procedures in classes in your programming language, so that instead of writing SQL statements to interact with your database, you use methods and properties of objects.

In other words, instead of something like this:

String sql = "SELECT ... FROM persons WHERE id = 10"
DbCommand cmd = new DbCommand(connection, sql);
Result res = cmd.Execute();
String name = res[0]["FIRST_NAME"];

you do something like this:

Person p = repository.GetPerson(10);
String name = p.FirstName;

or similar code (lots of variations here.) Some frameworks also put a lot of the code in as static methods on the classes themselves, which means you could do something like this instead:

Person p = Person.Get(10);

Some also implement complex query systems, so you could do this:

Person p = Person.Get(Person.Properties.Id == 10);

The framework is what makes this code possible.

Now, benefits. First of all, you hide the SQL away from your logic code. This has the benefit of allowing you to more easily support more database engines. For instance, MS SQL Server and Oracle has different names on typical functions, and different ways to do calculations with dates, so a query to "get me all persons edited the last 24 hours" might entail different SQL syntax just for those two database engines. This difference can be put away from your logic code.

Additionally, you can focus on writing the logic, instead of getting all the SQL right. The code will typically be more readable as well, since it doesn't contain all the "plumbing" necessary to talk to the database.

It allows you to do things like this (this is Doctrine code):

$activeUsers = Doctrine::getTable('User')->createQuery('u')->addWhere('u.active = false');
foreach($activeUsers as $user)
{
$user->active = true;
$user->save();
}

ORM is:

An abstraction and like any abstraction it makes life easier for you.

Databases usually work on relational model: you have tables (simplifying: like a spreadsheet), and relations between them - one-to-one, one-to-many, many-to-many, etc, meaning for instance that one record in table A has many related records in table B. You can retrieve data from them as rows (collection of values representing rows from table/tables) More in wikipedia.

Modern programming languages use object model. Objects have methods, attributes (simple or complex) etc.

ORM software does a transition between those models. For instance, it puts all related records from table B into an attribute of object A. This kind of software makes it easier to use relational databases (most popular kind) with object programming languages.

Object-relational mapping (ORM) libraries provide this mapping of database tables to domain object classes.

Whenever you go with ORM (Object Relational Mapper) you will find DBAL (Database Abstraction Layer) side by side. So its necessary to know what these are, so as to get good insights of what you are using and whats the advantages that you will get.

DBAL (Database Abstraction Layer)

It acts as a layer between your code and database. Irrespective of whatever your database, the code written will work fine with minor tweaking.

Assume that for the current project your using MySQL once its a fully matured and gets huge traffic your team plan to switch the database to Oracle for some reason then the code you have written in MySQL must be rewritten to Oracle based queries. And rewriting the queries for the whole project is a tedious task.

Instead if you use any DBAL libraries then you can switch the configuration of the database and make sure your project will be up and running within a day (May be with some minor tweaking).

ORM (Object Relational Mapper)

Object Relational Mapping (ORM) is a technique (Design Pattern) of accessing a relational database from an object-oriented language.

If you have used any kind of frameworks like Symfony (if you come from PHP background)/Hibernate (Java), then your familiar with these. Its nothing but Entities.

In order to access the database in Object Oriented context and interface translating the object logic is necessary, this interface is called as ORM. Its make up of the object that give access to data and keep the business rules with themselves.

Eg.

class User{
private $email;


private $password;


public function setEmail($email){
$this->email = $email;
return $this;
}


public function getEmail(){
return $this->email;
}




public function setPassword($password){
$this->password = $password;
return $this;
}


public function getPassword(){
return $this->password;
}
}


/* To save User details you would do something like this */
$userObj = new User();
$userObj->setEmail('sanitizedEmail');
$userObj->setPassword('sanitizedPassword');
$userObj->save();


/* To fetch user details you would do something like this */
$userObj = new User();
$userDetails = $userObj->find($id);

Eg. Doctrine, Propel, RedBean