对象-关系映射(ORM)提供了一个框架,应用程序可以使用一个对象范例,查询并操作数据库中的数据。该框架以多种语言实现,封装了数据操作所需的代码。这样,您无需了解SQL,即可使用一个对象访问数据,该对象隐藏了每个数据库查询语言的变化。
假设有以下的Employees表:
ID | Name | Address | Department | Salary |
---|---|---|---|---|
1 | John | Milpitas, CA | Engineer | $100,000 |
2 | Tom | Cupertino, CA | Support | $80,000 |
3 | James | Sunnyvale, CA | Pubs | $70,000 |
4 | Mike | San Jose, CA | Marketing | $95,000 |
5 | Maya | Fremont, CA | Sales 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.n...。
使用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;*
2.创建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();
}
}
3.创建映射配置文件。
以下文件告诉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
4.创建应用程序类文件(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方言作出的贡献