Object-Relational Mapping with Hibernate
-
Upload
dillon-hendricks -
Category
Documents
-
view
52 -
download
0
description
Transcript of Object-Relational Mapping with Hibernate
The Object-Oriented Paradigm
The world consists of objectsSo we use object-oriented languages to write applicationsWe want to store some of the application objects (a.k.a. persistent objects)So we use a Object Database?
The Reality of DBMS
Relational DBMS are still predominant Best performance Most reliable Widest support
Bridge between OO applications and relational databases CLI and embedded SQL (JDBC) Object-Relational Mapping (ORM) tools
JDBC Call-Level Interface (CLI)
Application interacts with database through functions calls
String sql = "select name from items where id = 1";
Connection c = DriverManager.getConnection( url );Statement stmt = c.createStatement();ResultSet rs = stmt.executeQuery( sql );
if( rs.next() ) System.out.println( rs.getString(“name”) );
Embedded SQL
SQL statements are embedded in host language
String name;#sql {select name into :name from items where id = 1};System.out.println( name );
Employee – Application Object
public class Employee { Integer id; String name; Employee supervisor;
}
Employee – Database Table
create table employees ( id integer primary key, name varchar(255), supervisor integer references employees(id)
);
From Database to Application
So how do we construct an Employee object based on the data from the database?
public class Employee {
Integer id;String name;Employee supervisor;
public Employee( Integer id ) { // access database to get name and supervisor … … }}
Problems with CLI and Embedded SQL …
SQL statements are hard-coded in applications
public Employee( Integer id ) { … PreparedStatment p; p = connection.prepareStatment( “select * from employees where id = ?” ); …}
… Problems with CLI and Embedded SQL …
Tedious translation between application objects and database tables
public Employee( Integer id ) { … ResultSet rs = p.executeQuery(); if( rs.next() ) { name = rs.getString(“name”); … }}
… Problems with CLI and Embedded SQL
Application design has to work around the limitations of relational DBMS
public Employee( Integer id ) { … ResultSet rs = p.executeQuery(); if( rs.next() ) { … supervisor = ?? }}
What is Hibernate?
It is an object-relational mapping (ORM) solution that allows for persisting Java objects in a relational databaseOpen sourceDevelopment started late 2001
Object-Relational Mapping
It is a programming technique for converting object-type data of an object oriented programming language into database tables.Hibernate is used convert object data in JAVA to relational database tables.
Hibernate vs. JDBC (an example)
JDBC tuple insertion –st.executeUpdate(“INSERT INTO book VALUES(“Harry Potter”,”J.K.Rowling”));
Hibernate tuple insertion – session.save(book1);
The ORM Approach
customer
employee
account
Application
Persistent Data Store
ORM tool
Oracle, MySQL, SQL Server …Flat files, XML …
Hibernate Architecture
Hibernate sits between your code and the database
Maps persistent objects to tables in the database
Java Classes
Plain Java classes (POJOs); however, it is recommended that Each persistent class has an identity
field Each persistent class has no argument
constructor Each persistent field has a pair of
getter and setter, which don’t have to be public
19
Employee Persistable Class
public class Employee { private int id; ; Identifier property private String first_name; private String last_name; private int salary;public Employee() {} ; No-argument constructor
; Getters and Setterspublic int getId() {}public void setId(int ID) {}……}
20
Database TablePersistable classes have an associated table
create table EMPLOYEE ( id INT NOT NULL auto_increment, first_name VARCHAR(20) default NULL, last_name VARCHAR(20) default NULL, salary INT default NULL, PRIMARY KEY (id) );
24
Hibernate mapping types
Hibernate will translate Java types to SQL / database types for the properties of your mapped classes
26
Configuration
Represents a set of mapping files
Database Connection: Handled through one or more configuration files.
These files are hibernate.properties and hibernate.cfg.xml. Class Mapping Setup:
Creates the connection between the Java classes and database tables
27
Session Factory
Obtained from a Configuration instanceShared among application threadsMain purpose is to provide Session instancesCreated during application start up and kept for later use. You would need one SessionFactory object per database using a separate configuration file. So if you are using multiple databases then you would have to create multiple SessionFactory objects.
private static SessionFactory factory=new Configuration().configure().buildSessionFactory();
28
Session
Lightweight and inexpensive to create/destroyNot threadsafe – each thread needs its ownObtained from SessionFactory instance
Session session = sessionFactory.openSession();
// perform persistence operations
session.close();
29
Transaction
Set of operations that are all committed or all rolled backObtained from Session instanceCan perform multiple transactions within session
Transaction tx = session.beginTransaction();// perform persistence operationstx.commit();
30
Object Lifecycle
Transient Newly created object
Persistent New object has been “saved” Previously saved object has been “read”
Detached Session closed Can be reattached later to become
persistent
31
Query Options (CH.13,14,15)
Hibernate Query Language (HQL)Query q = session.createQuery(“from Employee E where
e.salary > :value”);q.setParameter(“value”, someValue);List widgets = q.list();
Criteria API Criteria cr = session.createCriteria(Employee.class); cr.add(Restrictions.eq("salary", 2000)); List results = cr.list();
Native SQLQuery q = session.createSQLQuery(“"SELECT * FROM EMPLOYEE ”);List Employees = q.list();
32
1- Hibernate Query Language
- FROM Clause String hql = "FROM Employee"; Query query = session.createQuery(hql); List results = query.list();
- AS ClauseString hql = "FROM Employee AS E"; Query query = session.createQuery(hql); List results = query.list();
33
Hibernate Query Language(1)
- Where ClauseString hql = "FROM Employee E WHERE E.id = 10"; Query query = session.createQuery(hql); List results = query.list();
- ORDER BY Clause String hql = "FROM Employee E WHERE E.id > 10 ORDER BY
E.salary DESC"; Query query = session.createQuery(hql); List results = query.list();
34
Hibernate Query Language(2)
- GROUP BY Clause String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E
" + "GROUP BY E.firstName"; Query query = session.createQuery(hql); List results = query.list();
- Using Named Paramters
String hql = "FROM Employee E WHERE E.id = :employee_id"; Query query = session.createQuery(hql); query.setParameter("employee_id",10); List results = query.list();
35
Hibernate Query Language(3)
- Paging Using Query
String hql = "FROM Employee"; Query query = session.createQuery(hql); query.setFirstResult(0); query.setMaxResults(10); List results = query.list();
36
2- Restrictions with Criteria
Criteria cr = session.createCriteria(Employee.class); cr.add(Restrictions.eq("salary", 2000));
// To get records having salary more than 2000 cr.add(Restrictions.gt("salary", 2000));
// To get records having salary less than 2000 cr.add(Restrictions.lt("salary", 2000));
// To get records having fistName starting with zara cr.add(Restrictions.like("firstName", "zara%"));
37
Sorting Using Criteria
Package org.hibernate.criterion.Order :Criteria cr = session.createCriteria(Employee.class);
// To get records having salary more than 2000 cr.add(Restrictions.gt("salary", 2000));
// To sort records in descening order crit.addOrder(Order.desc("salary"));
// To sort records in ascending order crit.addOrder(Order.asc("salary")); List results = cr.list();
38
3- Hibernate Native SQL
Scalar queries :String sql = "SELECT first_name, salary FROM EMPLOYEE"; SQLQuery query = session.createSQLQuery(sql); List results = query.list();
Entity queries :String sql = "SELECT * FROM EMPLOYEE"; SQLQuery query = session.createSQLQuery(sql); query.addEntity(Employee.class); List results = query.list();
39
3- Hibernate Native SQL(1)
Named SQL queries :
String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id"; SQLQuery query = session.createSQLQuery(sql); query.addEntity(Employee.class); query.setParameter("employee_id", 10); List results = query.list();
Example Application
/* 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(); } } }
51
Association mapping
Supports all association types one-to-one one-to-many many-to-many
Inherently unidirectionalSupports bidirectional
Why Hibernate?
Java developers are not database developers– Reduce the need for developers to know and fully
understand database design, SQL, performance tuning
– Increase portability across database vendorsIncrease performance by deferring to experts
– Potential decrease in database calls– Hibernate cache usage
Why Hibernate?
Handles all create-read-update-delete(CRUD) operations using simple API; no SQL.
Flexibility to hand-tune SQL and call stored procedures to optimize performance.
Supports over 20 RDBMS; change the database by tweaking configuration files.
Why not Hibernate?
Overkill for small number of tables Complex legacy database schema Heavy batch processing Advanced queries / more SQL control Scaling concerns
Hibernate and JPA
Java Persistence API (JPA) Annotations for object-relational
mapping Data access API An object-oriented query language JPQL
Hibernate The most popular Java ORM library An implementation of JPA
Hibernate Usage
Hibernate without JPA API: SessionFactory, Session, Query, Transaction
More features
Hibernate with JPA API: EntityManagerFactory, EntityManager, Query, Transaction
Better portability Behaviors are better defined and
documented
A Hibernate Example
Java classes Employee.java
JPA configuration file persistence.xml
Code to access the persistent objects EmployeeTest.java
O/R Mapping Annotations
Describe how Java classes are mapped to relational tables
@Entity Persistent Java Class
@Id Id field
@Basic (can be omitted)
Fields of simple types
@ManyToOne@OneToMany@ManyToMany@OneToOne
Fields of class types
Basic Object-Relational Mapping
Class-level annotations @Entity and @Table
Id field @Id and @GeneratedValue
Fields of simple types @Basic (can be omitted) and @Column
Fields of class types @ManyToOne and @OneToOne
persistence.xml
<persistence-unit> name
<properties> Database information Provider-specific properties
No need to specify persistent classes
Access Persistent Objects
EntityManagerFactory
EntityManager
Query and TypedQueryTransaction A transaction is required for updates
Some EntityManager Methods
find( entityClass, primaryKey )createQuery( query )createQuery( query, resultClass )persist( entity )merge( entity )getTransaction()
http://sun.calstatela.edu/~cysun/documentation/jpa-2.0-api/javax/persistence/EntityManager.html
Persist() vs. Merge()Scenario Persist Merge
Object passed was never persisted
1. Object added to persistence context as new entity2. New entity inserted into database at flush/commit
1. State copied to new entity.2. New entity added to persistence context3. New entity inserted into database at flush/commit4. New entity returned
Object was previously persisted, but not loaded in this persistence context
1. EntityExistsException thrown (or a PersistenceException at flush/commit)
1. Existing entity loaded.2. State copied from object to loaded entity3. Loaded entity updated in database at flush/commit4. Loaded entity returned
Object was previously persisted and already loaded in this persistence context
1. EntityExistsException thrown (or a PersistenceException at flush or commit time)
1. State from object copied to loaded entity2. Loaded entity updated in database at flush/commit3. Loaded entity returned
http://blog.xebia.com/2009/03/jpa-implementation-patterns-saving-detached-entities/
Java Persistence Query Language (JPQL)
A query language that looks like SQL, but for accessing objectsAutomatically translated to DB-specific SQL statementsselect e from Employee e where e.id = :id From all the Employee objects, find
the one whose id matches the given value
See Chapter 4 of Java Persistence API, Version 2.0
Hibernate Query Language (HQL)
A superset of JPQLhttp://docs.jboss.org/hibernate/core/4.2/manual/en-US/html/ch16.html
Advantages of ORM
Make RDBMS look like ODBMSData are accessed as objects, not rows and columnsSimplify many common operations. E.g. System.out.println(e.supervisor.name)Improve portability Use an object-oriented query language (OQL) Separate DB specific SQL statements from
application code
Object caching