Hibernate
-
Upload
shaharyar-khan -
Category
Technology
-
view
1.016 -
download
0
description
Transcript of Hibernate
1
By Shaharyar [email protected]
If you have completed 2 versions of your product and the product is now stable , working great without any mess up and then
one day your user ask you to remove mySQL from backend and use Oracle as I am thinking that this is more good and efficient
2
Everyone knows that this will be like a bomb on the head of developers Because it is possible but while doing this developers can suicide due to extreme bugs in code, massive conversions of queries and may be DB design(For instance oracle supports foreign key but mySQL doesn’t).
So , there should be a mechanism or a smart API which provide us a layer between Database and code
This layer purpose is to interact with DB and our logical layer should have no concern or have no direct interaction with Databases.
So when we want to change our backend then nothing will be changed and we can save our a lot of time.
Basically Hibernate purpose is to cater this But not only this , Hibernate also provide us ORM
4
Developers Red Hat
Stable release4.1.4 Final / May 31, 2012 (some days ago)
Development status Active
Written in Java
Operating system Cross-platform (JVM)
Platform Java Virtual Machine
Type Object-relational mapping
LicenseGNU Lesser General Public License
Website www.hibernate.org
While working with hibernate , you can bump with these words which are the basic part of Hibernate
ORMMappingPersistence
And may beHQL
Data management tasks in object-oriented (OO) programming are typically implemented by manipulating objects
consider an address book entry that represents a single person along with zero or more phone numbers and zero or more addresses. This could be modeled in an object-oriented implementation by a "Person object" with attributes/fields to hold each data item that the entry comprises: the person's name, a list of phone numbers, and a list of addresses
Simply We can say that we are talking about Domain model
So ,the mapping of domain model into entity relationship model is called Object relational mapping or ORM
For ORM , We map JAVA classes into database tables
It is accomplished through the configuration of an XML file or by using Java Annotations
Hibernate can use the XML file or the annotations to maintain the database schema
Facilities to arrange one-to-many and many-to-many & all other relationships between classes are provided
Hibernate provides transparent persistence for Plain Old Java Objects(POJOs)
The only strict requirement for a persistent class is a no-argument constructor, not necessarily public
Collections of data objects are typically stored in Java collection objects such as Set and List
Hibernate can be configured to lazy load associated collections. Lazy loading is the default as of Hibernate 3
Hibernate provides an SQL inspired language called Hibernate Query Language (HQL)
It allows SQL-like queries to be written against Hibernate's data objects
Criteria Queries are provided as an object-oriented alternative to HQL
10
A “virtual object database” is created that can be used from within the programming language
Previous diagram shows minimal architecture of Hibernate
It creates a layer between Database and the Application
It loads the configuration details like Database connection string, entity classes, mappings etc
Hibernate creates persistent objects which synchronize data between application and database
Let see this architecture in detail diagram11
The above diagram shows a comprehensive architecture of Hibernate
In order to persist data to a database, Hibernate create an instance of entity class (Java class mapped with database table)
This object is called Transient object as they are not yet associated with the session or not yet persisted to a database
To persist the object to database, the instance of SessionFactory interface is created. SessionFactory is a singleton instance which implements Factory design pattern
SessionFactory loads hibernate.cfg.xml file (Hibernate configuration file) and with the help of TransactionFactory and ConnectionProvider implements all the configuration settings on a database
Each database connection in Hibernate is created by creating an instance of Session interface
Session represents a single connection with database
Session objects are created from SessionFactory object
Hibernate also provides built-in Transaction APIs which abstracts away the application from underlying JDBC or JTA transaction
Each transaction represents a single atomic unit of work
One Session can span through multiple transactions.
Before starting any example , We should know about some configuration files
These files are needed for mapping and to load many other properties and create database connection
Hibernate provide following type of configurtions:hibernate.cfg.xml – A standard XML file which contains
hibernate configuration like database connection, class mappings etc and which resides in root of application’s CLASSPATH
hibernate.properties: A Java compliant property file which holds key value pair for different hibernate configuration strings
Programmatic configuration: This is the manual approach. The configuration can be defined in Java class
16
<hibernate-configuration><session-factory> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/EmployeeDB</property>
<property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- Mapping files --> <mapping resource="contact.hbm.xml"/></session-factory></hibernate-configuration>
Once the hibernate.cfg.xml file is created and placed in root of application’s CLASSPATH, the same can be loaded in Hibernate using following API
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
17
This above code will load default hibernate.cfg.xml file and all the configuration mentioned in it
In case you want to override default naming convention and want to have your own configuration file like “employeedb.cfg.xml”, following API can be used:SessionFactory sf = new Configuration().configure("employeedb.cfg.xml")
.buildSessionFactory()
hibernate.connection.driver_class=com.mysql.jdbc.Driverhibernate.connection.url=
jdbc:mysql://localhost:3306/employeeDBhibernate.connection.username=roothibernate.connection.password=hibernate.dialect = org.hibernate.dialect.MySQLDialecthibernate.connection.pool_size=1 // C3P0(open source
JDBC // connection pool //distributed along
with //Hibernate in the lib //directory)
Note: Both hibernate.cfg.xml and hibernate.properties files can be provided simultaneously in an application. In this case hibernate.cfg.xml gets precedence over hibernate.properties.
We can obtain a org.hibernate.cfg.Configuration instance by instantiating it directly and specifying XML mapping documents. If the mapping files are in the classpath, use addResource().
Configuration cfg = new Configuration() .addResource("Employee.hbm.xml")
.addResource("Department.hbm.xml");
19
An alternative way is to specify the mapped class and allow Hibernate to find the mapping document for you Configuration cfg = new Configuration()
.addClass(com.deltasoft.hibernate.Employee.class) .addClass(com.deltasoft.hibernate.Department.class);
Hibernate will then search for mapping files named /com/deltasoft/hibernate/Employee.hbm.xml and /com/deltasoft/hibernate/Department.hbm.xml in the classpath. This approach eliminates any hardcoded filenames.
A org.hibernate.cfg.Configuration also allows you to specify configuration properties
Configuration cfg = new Configuration().addClass(com.deltasoft.hibernate.Employee.class).addClass(com.deltasoft.hibernate.Department.class).setProperty("hibernate.dialect",
"org.hibernate.dialect.MySQLInnoDBDialect").setProperty(" hibernate.connection.url ", "
jdbc:mysql://localhost/EmployeeDB ").setProperty("hibernate.order_updates", "true");
Let see in this example that how can we insert record in MySQL database using Hibernate
In this example , We will create a contact objecta and save it in Database ……
public class Contact { private String firstName; private String lastName; private String email;
private long id; //Contact.java//This is a POJO class
public String getEmail() { return email; }
public String getFirstName() { //We Can Assume that contact is an entity and these all return firstName; // are attributes of contact } public String getLastName() { return lastName; } public void setEmail(String string) { email = string; } public void setFirstName(String string) { firstName = string; } public void setLastName(String string) { lastName = string; } public long getId() { return id; } public void setId(long l) { id = l; }}
import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;
public class FirstExample { public static void main(String[] args) { Session session = null;
//FirstExample.java try{ // This step will read hibernate.cfg.xml and prepare hibernate for use SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); session =sessionFactory.openSession(); //Create new instance of Contact and set values in it by reading them from form object System.out.println("Inserting Record"); Contact contact = new Contact(); contact.setId(3); contact.setFirstName(“Shaharyar"); contact.setLastName("Khan"); contact.setEmail(“[email protected]"); session.save(contact); System.out.println("Done"); //same as we have update() , delete() methods }catch(Exception e){ System.out.println(e.getMessage()); }finally{ // Actual contact insertion will happen at this step session.flush(); session.close();} } }
?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration><session-factory> <property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">
jdbc:mysql://localhost/EmployeeDB</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- Mapping files --> <mapping resource="contact.hbm.xml"/></session-factory></hibernate-configuration>
In the above configuration file we specified to use the “EmployeeDB" which is running on localhost and the user of the database is root with no password. The dialect property is org.hibernate.dialect.MySQLDialect which tells the Hibernate that we are using MySQL Database.
25
DB2 - org.hibernate.dialect.DB2DialectHypersonicSQL - org.hibernate.dialect.HSQLDialect Informix - org.hibernate.dialect.InformixDialect Ingres - org.hibernate.dialect.IngresDialect PostgreSQL - org.hibernate.dialect.PostgreSQLDialect Microsoft SQL Server - org.hibernate.dialect.SQLServerDialect MySQL - org.hibernate.dialect.MySQLDialect Oracle (any version) - org.hibernate.dialect.OracleDialect Oracle 9 - org.hibernate.dialect.Oracle9Dialect Progress - org.hibernate.dialect.ProgressDialect SAP DB - org.hibernate.dialect.SAPDBDialect Sybase - org.hibernate.dialect.SybaseDialect Sybase Anywhere - org.hibernate.dialect.SybaseAnywhereDialect
Some dialects of different databases
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping> <class name=“com .deltasoft.hibernate.Contact" table="CONTACT"> <id name="id" type="long" column="ID" > <generator class="assigned"/> </id>
<property name="firstName"> <column name="FIRSTNAME" /> </property> <property name="lastName"> <column name="LASTNAME"/> </property> <property name="email"> <column name="EMAIL"/> </property> </class></hibernate-mapping>
27
It is better to get these jar files like this Go to http://sourceforge.net/projects/hibernate/files/ Click on
Download hibernate-search-4.1.1.Final-dist.zip (31.0 MB) Now a folder will be downloaded on your machine. Extract the folder and in extracted folder you will see a
folder “required” placed in “hibernate-search-4.1.1.Final/dist/lib/required”
Copy all the jar files present in “required” folder into your classpath
<hibernate-mapping> elementThe first or root element of hibernate mapping document is
<hibernate-mapping> element. Between the <hibernate-mapping> tag class element(s) are present
28
<class> elementThe <Class> element maps the class object with corresponding entity
in the database. It also tells what table in the database has to access and what column in that table it should use. Within one <hibernate-mapping> element, several <class> mappings are possible
<id> elementThe <id> element in unique identifier to identify and object. In fact
<id> element map with the primary key of the table. In our code :<id name="id" type="long" column="ID" >primary key maps to the ID field of the table CONTACT. The
attributes of the id element are: name: The property name used by the persistent class. column: The column used to store the primary key value. type: The Java data type used. unsaved-value: This is the value used to determine if a class has been
made persistent. If the value of the id attribute is null, then it means that this object has not been persisted.
<generator> elementThe <generator> method is used to generate the primary key
for the new record. Here is some of the commonly used generators :
Increment - This is used to generate primary keys of type long, short or int that are unique only. It should not be used in the clustered deployment environment.
Sequence - Hibernate can also use the sequences to generate the primary key. It can be used with DB2, PostgreSQL, Oracle, SAP DB databases.
Assigned - Assigned method is used when application code generates the primary key.
29
<property> elementThe property elements define standard Java attributes and
their mapping into database schema. The property element supports the column child element to specify additional properties, such as the index name on a column or a specific column type
Same like JSF and other frameworks of java , Hibernate also supports annotations
Now if we want to transfer our previous contact example into annotations then we havn’t need “contact.hbm.xml” so delete this if you want to introduce annotations in your code
Now our Contact.java would be like this
31
@Entity@Table(name="EMPLOYEE")public class Contact {
@Id @GeneratedValue private long id; //Contact.java with annotations @Column(name="firstname“) private String firstName; @Column(name=“lastname“) private String lastName; @Column(name=“email“) private String email; //getter and setters
}
32
Now in FirstExample.java just change this line
SessionFactory sessionFactory = new Configuration().configure().
buildSessionFactory();
TO
SessionFactory sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();And in hibernate.cfg.xml change this
<mappingresource="net/viralpatel/hibernate/Employee.hbm.xml"/>
TO <mapping class=“com.deltasoft.hibernate.Employee"/>
34
Lets take an example that
Employee has a one to one relation with EmployeeDetail
So, First we create a Employee class and then EmployeeDetail in which we map them by annotations
@Entity@Table(name="EMPLOYEE")public class Employee { @Id @GeneratedValue @Column(name="employee_id") private Long employeeId; @Column(name="firstname") private String firstname; @Column(name="lastname") private String lastname; @Column(name="birth_date") private Date birthDate; @Column(name="cell_phone") private String cellphone; @OneToOne(mappedBy="employee", cascade=CascadeType.ALL) private EmployeeDetail employeeDetail; public Employee() { } public Employee(String firstname, String lastname, Date birthdate, String phone) { this.firstname = firstname; this.lastname = lastname; this.birthDate = birthdate; this.cellphone = phone; } // Getter and Setter methods}
<?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property
name="connection.driver_class">com.mysql.jdbc.Driver</property> <property
name="connection.url">jdbc:mysql://localhost:3306/tutorial</property> <property name="connection.username">root</property> <property name="connection.password"></property> <property name="connection.pool_size">1</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="current_session_context_class">thread</property> <property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property> <property name="hbm2ddl.auto">validate</property> <mapping class="net.viralpatel.hibernate.EmployeeDetail"/> <mapping class="net.viralpatel.hibernate.Employee"/> </session-factory></hibernate-configuration>
public class Main {
public static void main(String[] args) { System.out.println("Hibernate One-To-One example (Annotation)"); SessionFactory sf = = new AnnotationConfiguration().configure() .buildSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); EmployeeDetail employeeDetail = new EmployeeDetail("10th
Street", "LA", "San Francisco", "U.S."); Employee employee = new Employee(“Ali", “Asim", new
Date(121212), "114-857-965"); employee.setEmployeeDetail(employeeDetail); employeeDetail.setEmployee(employee); session.save(employee); }
@Entity@Table(name="EMPLOYEE")public class Employee { @Id @GeneratedValue @Column(name="employee_id") private Long employeeId; @Column(name="firstname") private String firstname; @Column(name="lastname") private String lastname; @Column(name="birth_date") private Date birthDate; @Column(name="cell_phone") private String cellphone; @ManyToOne @JoinColumn(name="department_id") private Department department; public Employee() { } public Employee(String firstname, String lastname, String phone) { this.firstname = firstname; this.lastname = lastname; this.birthDate = new Date(System.currentTimeMillis()); this.cellphone = phone; } // Getter and Setter methods}
public class Main { @SuppressWarnings("unchecked") public static void main(String[] args) { SessionFactory sf = = new AnnotationConfiguration().configure() .buildSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Department department = new Department(); department.setDepartmentName("Sales"); session.save(department); Employee emp1 = new Employee("Nina", "Mayers", "111"); Employee emp2 = new Employee("Tony", "Almeida", "222"); emp1.setDepartment(department); emp2.setDepartment(department); session.save(emp1); session.save(emp2); session.getTransaction().commit(); session.close(); }} 40
41
Many Employees have many Meetings
So
We will Map Employee class with meeting class
42
@Entity@Table(name="EMPLOYEE")public class Employee { @Id @Column(name="EMPLOYEE_ID") @GeneratedValue private Long employeeId; @Column(name="FIRSTNAME") private String firstname; @Column(name="LASTNAME") private String lastname; @ManyToMany(cascade = {CascadeType.ALL}) @JoinTable(name="EMPLOYEE_MEETING", joinColumns={@JoinColumn(name="EMPLOYEE_ID")}, inverseJoinColumns={@JoinColumn(name="MEETING_ID")}) private Set<Meeting> meetings = new HashSet<Meeting>(); public Employee() { } public Employee(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; } // Getter and Setter methods} [email protected]
@Entity@Table(name="MEETING")public class Meeting { @Id @Column(name="MEETING_ID") @GeneratedValue private Long meetingId; @Column(name="SUBJECT") private String subject; @Column(name="MEETING_DATE") private Date meetingDate; @ManyToMany(mappedBy="meetings") private Set<Employee> employees = new HashSet<Employee>(); public Meeting(String subject) { this.subject = subject; this.meetingDate = new Date(); } // Getter and Setter methods}
44
public class Main { public static void main(String[] args) { SessionFactory sf = new AnnotationConfiguration().configure() .buildSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Meeting meeting1 = new Meeting("Quaterly Sales meeting"); Meeting meeting2 = new Meeting("Weekly Status meeting"); Employee employee1 = new Employee("Sergey", "Brin"); Employee employee2 = new Employee("Larry", "Page"); employee1.getMeetings().add(meeting1); employee1.getMeetings().add(meeting2); employee2.getMeetings().add(meeting1); session.save(employee1); session.save(employee2); session.getTransaction().commit(); session.close(); }}
Hibernate Query Language or HQL for short is extremely powerful query language
HQL is much like SQL and are case-insensitive, except for the names of the Java Classes and properties
Hibernate Query Language is used to execute queries against database
Hibernate automatically generates the sql query and execute it against underlying database if HQL is used in the application.
Hibernate Query Language uses Classes and properties instead of tables and columns. 45
46
SubqueriesSubqueries are nothing but its a query within another query.
Hibernate supports Subqueries if the underlying database supports it.
//Using from Clause
String SQL_QUERY ="from Insurance insurance";
Query query = session.createQuery(SQL_QUERY); for(Iterator it=query.iterate();it.hasNext();){
Insurance insurance=(Insurance)it.next(); System.out.println("ID: " +
insurance.getLngInsuranceId()); System.out.println("First
Name: " + insurance.getInsuranceName()); }
String SQL_QUERY ="Select insurance.
lngInsuranceId,insurance.insuranceName," +
"insurance.investementAmount,insurance.
investementDate from Insurance insurance";
Query query = session.createQuery(SQL_QUERY); for(Iterator it=query.iterate();it.hasNext();){
Object[] row = (Object[]) it.next(); System.out.println("ID: " + row[0]); System.out.println("Name: " + row[1]);
System.out.println("Amount: " + row[2]); }
It returns resultset in form of objects
String SQL_QUERY =" from Insurance as insurance where insurance.lngInsuranceId='1'";
Query query = session.createQuery(SQL_QUERY);
//remaining code
String SQL_QUERY = "select avg
(investementAmount) from Insurance insurance";Query query = sess.createQuery(SQL_QUERY); List list = query.list();System.out.println("Average of Invested Amount: " + list.get(0));
__________________________________________________
String SQL_QUERY = "select
max(investementAmount)from Insurance insurance";Query query = sess.createQuery(SQL_QUERY);List list = query.list();
System.out.println("Max Invested Amount: " + list.get(0);
50
avg(..) usage
max(…
)
usage