890 likes | 1.63k Views
Hibernate Overview. www.ascenttech.com.cn. 中国北京: 电话:( 010 ) 82780848/62969799 地址:北京市海淀区创业中路 36 号 留学人员创业园 306 室. CONFIDENTIAL. Hibernate Introduction. Why object/relational mapping? Solving the mismatch with tools Basic Hibernate features Hibernate Query Options
E N D
Hibernate Overview www.ascenttech.com.cn 中国北京: 电话:(010)82780848/62969799 地址:北京市海淀区创业中路36号 留学人员创业园306室 CONFIDENTIAL
Hibernate Introduction • Why object/relational mapping? • Solving the mismatch with tools • Basic Hibernate features • Hibernate Query Options • Detached Objects
Hibernate Introduction • The Structural Mismatch. • Java types vs. SQL datatypes • user-defined types (UDT) are in SQL:1999 • current products are proprietary • Type inheritance • no common inheritance model • Entity relationships.
Hibernate Introduction • “Modern” ORM Solutions • Transparent Persistence (POJO/JavaBeans) • Persistent/transient instances • Automatic Dirty Checking • Transitive Persistence • Lazy Fetching • Outer Join Fetching • Runtime SQL Generation • Three Basic Inheritance Mapping Strategies
Hibernate Introduction • Why ORM • Structural mapping more robust • Less error-prone code • Optimized performance all the time • Vendor independence
Hibernate Introduction • What do RDBs do well? • Work with large amounts of data • Searching, sorting • Work with sets of data • Joining, aggregating • Sharing • Concurrency (Transactions) • Many applications • Integrity • Constraints • Transaction isolation
Hibernate Introduction • What do RDBs do badly? • Modeling • No polymorphism • Fine grained models are difficult • Business logic • Stored procedures really bad
Hibernate Introduction • The Goal • Take advantage of those things that relational databases do well • Without leaving the language of objects / classes
Hibernate Introduction • Hibernate • Open Source (LGPL) • Mature • Popular (15,000 downloads/month) • Custom API • Will be core of JBoss CMP 2.0 engine
Hibernate Introduction • CMP (V.S. Hibernate)
Hibernate Introduction • Features • Persistence for POJOs (JavaBeans) • Flexible and intuitive mapping • Support for fine-grained object models • Powerful, high performance queries • Dual-Layer Caching Architecture (HDLCA) • Toolset for roundtrip development • Support for detached persistent objects
Conception • SessionFactory • A thread safe (immutable) cache of compiled mappings for a single database. A factory for Session and a client of Connection Provider • Session • A single-threaded, short-lived object representing a conversation between the application and the persistent store. Wraps a JDBC connection. Factory for Transaction. • Transaction • A single-threaded, short-lived object used by the application to specify atomic units of work. Abstracts application from underlying JDBC, JTA or CORBA transaction. A Session might span several Transactions in some cases • Persistent Objects and Collections • Short-lived, single threaded objects containing persistent state and business function. These might be ordinary JavaBeans/POJOs, • Transient Objects and Collections • Instances of persistent classes that are not currently associated with a Session. • .
Typical Usage Session sess = factory.openSession(); Transaction tx = null; try { tx = sess.beginTransaction(); // do some work ... tx.commit(); } catch (Exception e) { if (tx!=null) tx.rollback(); throw e; } finally { sess.close(); }
Hibernate Mapping • Single Table Example 1. PO(Persistent Object) layer: three components: 1) PO java class 2) hbm xml file 3) hibernate.cfg xml file 2. DAO(Data Access Object) layer one java client, having select, insert, delete, update.
Hibernate Mapping • Persistent Class • JavaBean specification (or POJOs) • No-arg constructor • Accessor methods for properties • Identifier property package com.ascent.po; import java.io.Serializable; public abstract class AbstractStudent implements Serializable { private java.lang.Integer id; private java.lang.String name; public AbstractStudent(){} public java.lang.Integer getId() { return id;} public void setId(Integer id) { this.id = id;} } public java.lang.String getName() { return this.name;} public void setName(String name) { this.name = name; }
Hibernate Mapping • Persistent Class(Cont’) package com.ascent.po; import java.io.Serializable; public class Student extends AbstractStudent implements Serializable { public Student() { } public Student(java.lang.Integer id) { super(id); } /* Add customized code below */ }
Hibernate Mapping • hbm xml file • <?xml version="1.0" encoding='UTF-8'?> • <!DOCTYPE hibernate-mapping PUBLIC • "-//Hibernate/Hibernate Mapping DTD 2.0//EN" • "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > • <hibernate-mapping package="com.ascent.po"> • <class name="Student" table="student"> • <id name="id" column="id" type="integer"> • <generator class="identity"/> • </id> • <property name="name" column="name" type="string" /> • </class> • </hibernate-mapping>
Hibernate Mapping • hibernate.cfg.xml file • <?xml version='1.0' encoding='UTF-8'?> • <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 2.0//EN" • "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"> • <hibernate-configuration> • <session-factory> • <!-- mapping files --> • <property name="myeclipse.connection.profile">MySQLProfile</property> • <property name="connection.url">jdbc:mysql://localhost:3306/test</property> • <property name="connection.username">root</property> • <property name="connection.password"></property> • <property name="connection.driver_class">com.mysql.jdbc.Driver</property> • <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property> • <property name="show_sql">false</property> • <mapping resource="com/ascent/po/Student.hbm.xml" /> • </session-factory> • </hibernate-configuration>
Hibernate Mapping • DAO class • package com.ascent.dao; • import java.util.*; • import net.sf.hibernate.*; • import com.ascent.po.*; • public class StudentFacade { • // select student • public Collection findAllStudent(){ • Collection collection = null; • try { • Session studentSession = HibernateSessionFactory.currentSession(); • Query query = studentSession.createQuery("from Student"); • List list = query.list(); • } catch (HibernateException e) { • e.printStackTrace(); • }finally{ • if(studentSession != null ) HibernateSessionFactory.closeSession( ); • } • return list; • }
Hibernate Mapping • DAO class cont’ • // insert student • public int addStudent(Student student){ • int flag = 0; • try{ • Session studentSession = HibernateSessionFactory.currentSession(); • Transaction studentTr = studentSession.beginTransaction(); • studentSession.save(student); • studentTr.commit(); • flag = 1; • }catch (HibernateException e) { • flag = 0; • e.printStackTrace(); • } • return flag; • }finally{ • if(studentSession != null ) HibernateSessionFactory.closeSession( ); • }
Hibernate Mapping • DAO class cont’ • //delete student • public int deleteStudent(int studentId){ • int flag = 1; • try { • Session session = HibernateSessionFactory.currentSession(); • Transaction tr = session.beginTransaction(); • Student student = (Student)session.load(Student.class,new Integer(studentId)); • session.delete(student); • tr.commit(); • } catch (HibernateException e) { • // TODO Auto-generated catch block • flag = 0; • e.printStackTrace(); • } • return flag ; • }
Hibernate Mapping • DAO class cont’ • //update student • public int updateStudent(Student student) { • int flag = 1; • try { • Session session = HibernateSessionFactory.currentSession(); • Transaction tr = session.beginTransaction(); • try{ • Student sTemp = (Student)session.load(Student.class,student.getId()); • sTemp.setName(student.getName()); • session.update(sTemp); • tr.commit(); • flag = 1; • }catch(Exception e){ • flag =0; tr.rollback(); • } catch (HibernateException e) { • // TODO Auto-generated catch block • flag = 0; e.printStackTrace(); } • return flag; • }
Hibernate Mapping • DAO class cont’ • public static void main(String []args){ • StudentFacade studentFacade = new StudentFacade(); • try { // insert student • Student s= new Student(); • s.setName("Zhou Jielun"); • studentFacade.addStudent(s); • // delete a student • /studentFacade.delectStudent(9); • // update student • Student s2 = new Student(); • s2.setId(new Integer(3)); • s2.setName("Liang Jinjin"); • studentFacade.updateStudent(s2); • //select all • Collection collection = studentFacade.findAllStudent(); • Iterator iterator = collection.iterator(); • while(iterator.hasNext()){ • Student StudentTemp = (Student)iterator.next(); • System.out.println(StudentTemp.getId() + ":" + StudentTemp.getName()); } • }catch (HibernateException e) {e.printStackTrace();}}}
Hibernate Mapping • DAO class cont’ • // Transaction Test 1 • try { • Session s = HibernateSessionFactory.currentSession(); • Transaction t = s.beginTransaction(); • try{ • Student my_hibernate = new Student(); • my_hibernate.setName("feng55"); • s.save(my_hibernate); • Query qq=s.createQuery("from Student"); • Student my_hibernate2=(Student)s.load(Student.class,new Integer(10)); • my_hibernate2.setName("Zhou Jielun"); • s.flush(); • t.commit(); • }catch(HibernateException e) { • t.rollback(); • e.printStackTrace(); • }
Hibernate Mapping • DAO class cont’ • //Transaction Test 2 • try{ • Student my_hibernate = new Student(); • //my_hibernate.setId(1); • my_hibernate.setName("ggjj"); • s.save(my_hibernate); • int a=s.delete("from Student where id=14"); • System.out.println(a); • if(a==0) t.rollback(); • s.flush(); • t.commit(); • }catch(HibernateException e) { • t.rollback(); • e.printStackTrace(); • }
Object state • Transient Objects Objects instantiated using the new operator aren’t immediately persistent. Their state is transient, which means they aren’t associated with any database table row, and so their state is lost as soon as they’re dereferenced. • Persistent Objects A persistent instance is any instance with a database identity. Persistent instances are associated with the persistence manager. Persistent instances are always associated with a Session and are transactional • Detached Objects Instances lose their association with the persistence manager when you close() the Session. We refer to these objects as detached, indicating that their state is no longer guaranteed to be synchronized with database state; they’re no longer under the management of Hibernate.
Hibernate Introduction • Persistent state • Retrieve an AuctionItem and change description Session session = sessionFactory.openSession(); Transaction tx = s.beginTransaction(); AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); item.setDescription(newDescription); tx.commit(); session.close();
Hibernate Introduction • Transitive Persistence • Retrieve an AuctionItem and create a new persistent Bid Bid bid = new Bid(); bid.setAmount(bidAmount); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); bid.setItem(item); item.getBids().add(bid); tx.commit(); session.close();
Hibernate Introduction • Detached objects • Retrieve an AuctionItem and change the description: Session session = sf.openSession(); Transaction tx = session.beginTransaction(); AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); tx.commit(); session.close(); item.setDescription(newDescription); Session session2 = sf.openSession(); Transaction tx = session2.beginTransaction(); session2.update(item); tx.commit(); session2.close();
Hibernate Introduction • Layer Communication • The presentation layer is decoupled from the service layer and business logic: Presentation Layer Remote? DTO? Service Layer Domain Objects
Hibernate Introduction • DTOs are Evil • “Useless” extra LOC • Not objects (no behavior) • Parallel class hierarchies smell • Shotgun change smell • Solution: detached object support
Hibernate Introduction • Detached Object Support • For applications using servlets + session beans • You don’t need to select a row when you only want to update it! • You don’t need DTOs anymore! • You may serialize objects to the web tier, then serialize them back to the EJB tier in the next request • Hibernate lets you selectively reassociate a subgraph! (essential for performance)
Hibernate Mapping • Multiple tables example
Hibernate Mapping • XML Mapping • Readable metadata • Column/table mappings • Surrogate key generation strategy • Collection metadata • Fetching strategies <class name=“AuctionItem” table=“AUCTION_ITEM”> <id name=“id” column=“ITEM_ID”> <generator class=“native”/> </id> <property name=“description” column=“DESCR”/> <many-to-one name=“successfulBid” column=“SUCCESSFUL_BID_ID”/> <set name=“bids” cascade=“all” lazy=“true”> <key column=“ITEM_ID”/> <one-to-many class=“Bid”/> </set> </class>
Hibernate Mapping • Persistent Class • JavaBean specification (or POJOs) • No-arg constructor • Accessor methods for properties • Collection property is an interface • Identifier property public class AuctionItem { private Long id; private Set bids; private Bid successfulBid private String description; public Long getId() { return id; } private void setId(Long id) { this.id = id; } public String getDescription() { return description; } public void setDescription(String desc) { escription=desc; } public Set getBids() { return bids; } private void setBids(Set bids) { this.bids = bids; } … }
Basic O/R Mapping • Class <class name="ClassName" table="tableName" discriminator-value="discriminator_value" mutable="true|false" schema="owner" proxy="ProxyInterface" dynamic-update="true|false" dynamic-insert="true|false" select-before-update="true|false" polymorphism="implicit|explicit" where="arbitrary sql where condition" persister="PersisterClass" batch-size="N" optimistic-lock="none|version|dirty|all" lazy="true|false" />
Basic O/R Mapping • ID <id name="propertyName" type="typename" column="column_name" unsaved-value="any|none|null|id_value" access="field|property|ClassName"> <generator class="generatorClass"/> </id> Generator: Increment, sequence, hilo, seqhilo, uuid.hex, native, assigned, foreign
Basic O/R Mapping • Composite-id <composite-id name="propertyName" class="ClassName" unsaved-value="any|none" access="field|property|ClassName"> <key-property name="propertyName" type="typename" column="column_name"/> <key-many-to-one name="propertyName class="ClassName" column="column_name"/> ...... </composite-id>
Basic O/R Mapping • Property <property name="propertyName" column="column_name" type="typename" update="true|false" insert="true|false" formula="arbitrary SQL expression" access="field|property|ClassName" />
Basic O/R Mapping • Many to one <many-to-one name="propertyName" column="column_name" class="ClassName" cascade="all|none|save-update|delete" outer-join="true|false|auto" update="true|false" insert="true|false" property-ref="propertyNameFromAssociatedClass" access="field|property|ClassName" unique="true|false" /> • One to one <one-to-one name="propertyName" class="ClassName" cascade="all|none|save-update|delete" constrained="true|false" outer-join="true|false|auto" property-ref="propertyNameFromAssociatedClass" access="field|property|ClassName" />
Basic O/R Mapping • Collection (<set>, <list>, <map>, <bag>, <array>) <map name="propertyName" table="table_name" schema="schema_name" lazy="true|false" inverse="true|false" cascade="all|none|save-update|delete|all-delete-orphan" sort="unsorted|natural|comparatorClass" order-by="column_name asc|desc" where="arbitrary sql where condition" outer-join="true|false|auto" batch-size="N" access="field|property|ClassName" > <key .... /> <index .... /> <element .... /> </map>
Basic O/R Mapping • Many-to-many <many-to-many column="column_name" class="ClassName" outer-join="true|false|auto" />
Hibernate Mapping • one to one example: Address and Customer 1. DB script: create table CUSTOMER ( ID bigint not null, NAME varchar(15), primary key (ID) ); create table ADDRESS( ID bigint not null, STREET varchar(128), CITY varchar(128), PROVINCE varchar(128), ZIPCODE varchar(6), primary key (ID) );
Hibernate Mapping 2. hbm files: <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping package="mypack"> <class name="Customer" table="customer"> <id name="id" column="ID" type="long"> <generator class="identity"/> </id> <property name="name" column="NAME" type="string" /> <one-to-one name="address" class="mypack.Address" cascade="all" /> </class> </hibernate-mapping>
Hibernate Mapping <hibernate-mapping package="mypack"> <class name="Address" table="address"> <id name="id" column="ID" type="long"> <generator class="identity"/> </id> <property name="street" column="STREET" type="string" /> <property name="city" column="CITY" type="string" /> <property name="province" column="PROVINCE" type="string" /> <property name="zipcode" column="ZIPCODE" type="string" /> <one-to-one name="customer" class="mypack.Customer" constrained="true" /> </class> </hibernate-mapping>
Hibernate Mapping 3. PO class: public abstract class AbstractAddress implements Serializable { … private Customer customer; public mypack.Customer getCustomer() { return this.customer; } public void setCustomer(mypack.Customer customer) { this.customer = customer; } … public abstract class AbstractCustomer implements Serializable{ … private Address address; public mypack.Address getAddress() { return this.address; } public void setAddress(mypack.Address address) { this.address = address; }…
Hibernate Mapping 4. DAO class: … public void printCustomer(Customer customer) throws Exception{ Address address=customer.getAddress(); System.out.println("Address of "+customer.getName()+" is: " +address.getProvince()+" " +address.getCity()+" " +address.getStreet()); if(address.getCustomer()==null) System.out.println("Can not naviagte from address to Customer."); } ….