对象-关系映射(ORM)提供了一个框架,应用程序可以使用一个对象范例,查询并操作数据库中的数据。该框架以多种语言实现,封装了数据操作所需的代码。这样,您无需了解SQL,即可使用一个对象访问数据,该对象隐藏了每个数据库查询语言的变化。

假设有以下的Employees表:

IdNameAddressDepartmentSalary
1JohnMilpitas, CAEngineer$ 100,000
2TomCupertino, CASupport$ 80,000
3JamesSunnyvale, CAPubs$ 70,000
4MikeSan Jose, CAMarketing$ 95,000
5MayaFremont, CASales Rep$ 80,000

以下示例在Employees表中检索可获得的ID、Name和Salary列:

SQL> SELECT ID, NAME, SALARY FROM Employees where ID = 1;

如果用编程的方式,您必须创建以下代码:

String selectSQL = “SELECT ID, NAME FROM Employees WHERE ID = 1” ;
Statement = dbConnection.createStatement() ;
ResultSet rs = Statement.executeQuery(selectSQL ) ;
while (rs.next())
{
String userid = rs.getString(“ID”) ;
String username = rs.getString(“NAME”) ;
}

但是,ORM的代码为:

Employee_list = EmployeeTable.query(ID=1) ;

如您所见,ORM简化了复杂的代码。除此之外,ORM还具有以下优点:

  • 数据模型在一个地方,节约时间。
  • 便于代码的更新、维护和重新使用。
  • 使用您的首选编程语言,灵活性高。

当然,您必须要花点时间学习ORM。Hibernate (Java)、Propel或Doctrine (PHP)、Django或SQLAlchemy (Python)周围有很多ORM。

本文重点讨论Hibernate。Hibernate ORM (Hibernate)是一个Java的对象-关系映射框架,提供面向对象的域模型-传统关系型数据库的映射。Hibernate用高层级的对象处理函数替代直接的持久化相关数据库访问,解决了对象-关系的抗阻失配问题。Hibernate是自由软件,符合GNU宽通用公共许可协议2.1。功能包括Java类-数据库表的映射(和Java数据类型-SQL数据类型的映射)、数据查询和检索。Hibernate生成SQL调用,减轻开发人员的手动结果集处理和对象转换。使用Hibernate的应用程序是非常轻便的,只需很小的性能开销,即可支持SQL数据库。

Hibernate位于传统的Java对象和数据库服务器之间,根据适当的O/R机制和模式,处理持久化这些对象的所有操作。

Hibernate采用分层架构,分离了底层的API。Hibernate利用数据库和配置数据,向应用程序提供持久化服务(和持久对象)。下图显示了Hibernate的高层架构:

接下来,了解Trafodion如何支持Hibernate框架。若要支持Hibernate,数据库的供应商必须创建一个方言,该方言要能够实现最佳性能、能够利用丰富的功能。有些功能/函数可能只在Trafodion(或其他数据库)中可用,不受Hibernate的支持。在这种情况下,Hibernate SQL方言会将您的Hibernate应用程序翻译成SQL语言,与您的数据库进行通信。我们创建了一个Trafodion方言,如果遇到Hibernate应用程序,Hibernate将解析此类功能。Trafodion方言的JIRA:https://hibernate.atlassian.net/browse/HHH-10216

使用Trafodion方言的步骤和示例代码

  1. 创建Trafodion数据库表。

SET SCHEMA TRAFODION.SEABASE;
DROP TABLE employee;
CREATE TABLE EMPLOYEE (
id INT NOT NULL ,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);
CREATE SEQUENCE trafodion.seabase.empseq;

  1. 创建POJO类。

Employee.java的内容:

package trafodion.hibernate.common;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}

HibernateUtil.java的内容:

package trafodion.hibernate.persistence;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println(“Initial SessionFactory creation failed.” + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}

  1. 创建映射配置文件。

以下文件告诉Hibernate如何映射Java类型-数据库表:

Employee.hbm.xml文件的内容:

“http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”

该Java类包含员工的详细信息:

trafodion.seabase.empseq

Trafodion数据库的hibernate配置文件内容:

“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>
false
org.trafodion.jdbc.t4.T4Driver
zz
jdbc:t4jdbc://10.12.10.21:12345/:
zz
org.hibernate.dialect.TrafodionDialect
true

  1. 创建应用程序类文件(ManageEmployee.java)。
package trafodion.hibernate.common;
import java.util.List;
import java.util.Date;
import java.util.Iterator;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class ManageEmployee {
  private static SessionFactory factory;
   public static void main(String[] args) {
      try{
         factory = new Configuration().configure().buildSessionFactory();
      }catch (Throwable ex) {
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex);
      }
      ManageEmployee ME = new ManageEmployee();
      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("AAA", "Ali", 1000);
      Integer empID2 = ME.addEmployee("BBB", "Das", 5000);
      Integer empID3 = ME.addEmployee("CCC", "Paul", 10000);
      /* List down all the employees */
      ME.listEmployees();
      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);
      /* List down all the employees */
      ME.listEmployees();
      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);
      /* List down new list of the employees */
      ME.listEmployees();
   }
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      try{
         tx = session.beginTransaction();
         Employee employee = new Employee(fname, lname, salary);
         employeeID = (Integer) session.save(employee);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
      return employeeID;
   }
   /* Method to  READ all the employees */
   public void listEmployees( ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Query qry= session.createQuery("FROM Employee");
         List employees= qry.list();
         //List employees = session.createQuery("FROM Employee").list();
         for (Iterator iterator =
                    employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next();
            System.out.print("First Name: " + employee.getFirstName());
            System.out.print("  Last Name: " + employee.getLastName());
            System.out.println("  Salary: " + employee.getSalary());
         }
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
   }
   /* Method to UPDATE salary for an employee */
   public void updateEmployee(Integer EmployeeID, int salary ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Employee employee =
            (Employee)session.get(Employee.class, EmployeeID);
         employee.setSalary( salary );
         session.update(employee);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
   }
   /* Method to DELETE an employee from the records */
   public void deleteEmployee(Integer EmployeeID){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Employee employee =
             (Employee)session.get(Employee.class, EmployeeID);
         session.delete(employee);
         tx.commit();
      }catch (HibernateException e) {
        if (tx!=null) tx.rollback();
         e.printStackTrace();
      }finally {
         session.close();
      }
   }
 }

致谢:感谢ADP首席数据科学家,Haifeng Li(李海峰,音译)为Trafodion方言作出的贡献。