1 / 47

Object/Relational Mapping with Hibernate

Object/Relational Mapping with Hibernate. Practical ORM. 基础配置. Managed environment— 池资源像 database connections 和 允许 transaction,security 靠指定的声明 Non-managed environment— 提供基本的并发管理通过线程池,不提供自动 transaction or resource management or 安全机制. 自己管理 database connections 和划分 transaction 边界. 非管理环境的配置.

gbourgeois
Download Presentation

Object/Relational Mapping with Hibernate

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Object/Relational Mapping with Hibernate Practical ORM

  2. 基础配置 • Managed environment—池资源像database connections和 允许transaction,security 靠指定的声明 • Non-managed environment—提供基本的并发管理通过线程池,不提供自动transaction or resource management or 安全机制. 自己管理database connections和划分transaction边界

  3. 非管理环境的配置 • Using a connection pool • C3P0,Apache DBCP and Proxool.

  4. Using hibernate.properties for C3P0 connection pool settings hibernate.connection.driver_class = org.postgresql.Driver hibernate.connection.url = jdbc:postgresql://localhost/auctiondb hibernate.connection.username = auctionuser hibernate.connection.password = secret hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.timeout=300 hibernate.c3p0.max_statements=50(缓存中最大的prepared statements 数) hibernate.c3p0.idle_test_period=3000(释放连接)

  5. 管理环境的配置

  6. Sample hibernate.properties for a container-provided datasource hibernate.connection.datasource =java:/comp/env/jdbc/AuctionDB hibernate.transaction.factory_class = \ net.sf.hibernate.transaction.JTATransactionFactory(CMT) hibernate.transaction.manager_lookup_class = \ net.sf.hibernate.transaction.JBossTransactionManagerLookup hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect

  7. Using XML-based configuration <?xml version='1.0'encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"> <hibernate-configuration> <session-factory name="java:/hibernate/HibernateFactory"> <property name="show_sql">true</property> <property name="connection.datasource">java:/comp/env/jdbc/AuctionDB</property> <property name="dialect">net.sf.hibernate.dialect.PostgreSQLDialect</property> <property name="transaction.manager_lookup_class"> net.sf.hibernate.transaction.JBossTransactionManagerLookup </property> <mapping resource="auction/Item.hbm.xml"/> <mapping resource="auction/Category.hbm.xml"/> <mapping resource="auction/Bid.hbm.xml"/> </session-factory> </hibernate-configuration>

  8. JNDI-bound SessionFactory hibernate.connection.datasource = java:/comp/env/jdbc/AuctionDB hibernate.transaction.factory_class = \ net.sf.hibernate.transaction.JTATransactionFactory hibernate.transaction.manager_lookup_class = \ net.sf.hibernate.transaction.JBossTransactionManagerLookup hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect hibernate.session_factory_name = hibernate/HibernateFactory hibernate.jndi.class = com.sun.jndi.fscontext.RefFSContextFactory hibernate.jndi.url = file:/auction/jndi

  9. log4j.properties ### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} ➾ %5p %c{1}:%L - %m%n ### root logger option ### log4j.rootLogger=warn, stdout ### Hibernate logging options ### log4j.logger.net.sf.hibernate=info ### log JDBC bind parameters ### log4j.logger.net.sf.hibernate.type=info ### log PreparedStatement cache activity ### log4j.logger.net.sf.hibernate.ps.PreparedStatementCache=info

  10. POJO implementation of the User class public class User implements Serializable { private String username; private Address address; public User() {} public String getUsername() { return username;} public void setUsername(String username) { this.username = username;} public Address getAddress() { return address;} public void setAddress(Address address) { this.address = address;} public MonetaryAmount calcShippingCosts(Address fromLocation) { } }

  11. Implementing POJO associations Category aParent = new Category(); Category aChild = new Category(); aChild.setParentCategory(aParent); aParent.getChildCategories().add(aChild);

  12. many-to-many association

  13. Hibernate XML mapping of the Category class

  14. Basic property and class mappings <property name="description" column="DESCRIPTION" type="string"/> <property name="description" column="DESCRIPTION"/> 以上配置是等同的,以下配置是等同的 <property name="description" column="DESCRIPTION" type="string"/> <property name="description" type="string"> <column name="DESCRIPTION"/> </property> <property name="initialPrice" column="INITIAL_PRICE" not-null="true"/>

  15. 使用合成属性 <property name="totalIncludingTax" formula="TOTAL + TAX_RATE * TOTAL" type="big_decimal"/> <property name="averageBidAmount" formula="( select AVG(b.AMOUNT) from BID b ➾where b.ITEM_ID = ITEM_ID )" type="big_decimal"/>

  16. Property access strategies <property name="name" column="NAME" type="string" access=“field”/>(这种配置不需要get()/set()) • Default uses the property accessors(get/set method pair) • The field strategy uses reflection to access the instance variable directly

  17. 控制插入和更新 • <property name="name" column="NAME" type="string" insert="false" update="false"/> • immutable=“false”设置改属性为只读 • <class name="org.hibernate.auction.model.User" dynamic-insert="true" dynamic-update="true"> ... </class> • 只插入\更新需要的属性

  18. Using quoted SQL identifiers • <property name="description" column="`Item Description`"/>

  19. SQL schemas <hibernate-mapping> <class name="org.hibernate.auction.model.Category" table="CATEGORY" schema="AUCTION"> ... </class> </hibernate-mapping> 在整个文档中声明: <hibernate-mapping default-schema="AUCTION"> .. </hibernate-mapping>

  20. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping> <class name="org.hibernate.auction.model.Category" table="CATEGORY"> ... </class> </hibernate-mapping> <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping package="org.hibernate.auction.model"> <class name="Category" table="CATEGORY"> ... </class> </hibernate-mapping> Declaring class names

  21. // Get the existing mapping for User from Configuration PersistentClass userMapping = cfg.getClassMapping(User.class); // Define a new column for the USER table Column column = new Column(); column.setType(Hibernate.STRING); column.setName("MOTTO"); column.setNullable(false); column.setUnique(true); userMapping.getTable().addColumn(column); // Wrap the column in a Value SimpleValue value = new SimpleValue(); value.setTable( userMapping.getTable() ); value.addColumn(column); value.setType(Hibernate.STRING); // Define a new property of the User class Property prop = new Property(); prop.setValue(value); prop.setName("motto"); userMapping.addProperty(prop); // Build a new session factory, using the new mapping SessionFactory sf = cfg.buildSessionFactory(); Manipulating metadata at runtime

  22. 持久化实例的identifier property的值 这个值通过调用Session.getIdentifier(Object o)返回 Database identity with Hibernate public class Category { private Long id; ... public Long getId() { return this.id; } private void setId(Long id) { this.id = id; } ... } <class name="Category" table="CATEGORY"> <id name="id" column="CATEGORY_ID" type="long"> <generator class="native"/> </id> ... </class> <id column="CATEGORY_ID"> <generator class="native"/> </id> Long catId = (Long) session.getIdentifier(category); category.getId();

  23. 使用components

  24. <component name="homeAddress" class="Address"> <parent name="user"/> <property name="street" type="string" column="HOME_STREET"/> <property name="city" type="string" column="HOME_CITY"/> <property name="zipcode" type="short" column="HOME_ZIPCODE"/> </component> 使用components-2

  25. 表对应具体的类—在关系模型中放弃多态和继承(<class>)表对应具体的类—在关系模型中放弃多态和继承(<class>) 表对应类的继承关系—能在关系模型中使用多态,使用一个类型描述的列保持数据类型信息(<subclass>) 表对应子类—把 “is a” (inheritance) 关系作为 “has a”(foreign key) 关系(<joined-subclass>) 映射类的继承

  26. 表对应具体的类

  27. select CREDIT_CARD_ID, OWNER, NUMBER, CREATED, TYPE, ... from CREDIT_CARD where CREATED = ? select BANK_ACCOUNT_ID, OWNER, NUMBER, CREATED, BANK_NAME, ... from BANK_ACCOUNT where CREATED = ? select CREDIT_CARD_ID, TYPE, EXP_MONTH, EXP_YEAR from CREDIT_CARD where CREATED = ? SQL SELECTs

  28. 表对应类的继承关系

  29. XML Mapping

  30. 1.querying the BillingDetails class select BILLING_DETAILS_ID, BILLING_DETAILS_TYPE, OWNER, ..., CREDIT_CARD_TYPE, from BILLING_DETAILS where CREATED = ? 2. query the CreditCard subclass select BILLING_DETAILS_ID, CREDIT_CARD_TYPE, CREDIT_CARD_EXP_MONTH, ... from BILLING_DETAILS where BILLING_DETAILS_TYPE='CC' and CREATED = ? SQL SELECTs

  31. 表对应子类

  32. XML Mapping

  33. 1.querying the BillingDetails class select BD.BILLING_DETAILS_ID, BD.OWNER, BD.NUMER, BD.CREATED, CC.TYPE, ..., BA.BANK_SWIFT, ... case when CC.CREDIT_CARD_ID is not null then 1 when BA.BANK_ACCOUNT_ID is not null then 2 when BD.BILLING_DETAILS_ID is not null then 0 end as TYPE from BILLING_DETAILS BD left join CREDIT_CARD CC on BD.BILLING_DETAILS_ID = CC.CREDIT_CARD_ID left join BANK_ACCOUNT BA on BD.BILLING_DETAILS_ID = BA.BANK_ACCOUNT_ID where BD.CREATED = ? SQL SELECTs(outerjoin)

  34. SQL SELECTs(innerjoin) • select BD.BILLING_DETAILS_ID, BD.OWNER, BD.CREATED, CC.TYPE, ... from CREDIT_CARD CC inner join BILLING_DETAILS BD on BD.BILLING_DETAILS_ID = CC.CREDIT_CARD_ID where CC.CREATED = ?

  35. Managed associations(CMP->CMR) public class Bid { ... private Item item; public void setItem(Item item) { this.item = item; } public Item getItem() { return item; } ... } bid.setItem(item)->item.getBids().add(item)双向 <class name="Bid" table="BID"> ... <many-to-one name="item" column="ITEM_ID" class="Item" not-null="true"/> </class> 单向

  36. 双向关联关系 public class Item { ... private Set bids = new HashSet(); public void setBids(Set bids) { this.bids = bids; } public Set getBids() { return bids; } public void addBid(Bid bid) { bid.setItem(this); bids.add(bid); } ... } <class name="Item" table="ITEM"> ... <set name="bids"> <key column="ITEM_ID"/> <one-to-many class="Bid"/> </set> </class>

  37. 表关联(one-many)

  38. One-to-one associations <class name="Address" table="ADDRESS"> <id name="id" column="ADDRESS_ID"> <generator class="native"/> </id> <property name="street"/> <property name="city"/> <property name="zipcode"/> </class> <one-to-one name="user" class="User" property-ref="billingAddress"/>

  39. 表关联(one-one) Address address = new Address(); address.setStreet("646 Toorak Rd"); address.setCity("Toorak"); address.setZipcode("3000"); Transaction tx = session.beginTransaction(); User user = (User) session.get(User.class, userId); address.setUser(user); user.setBillingAddress(address); tx.commit();

  40. Using a primary key association 1.single address property address and map it with the User <one-to-one name="address" class="Address" cascade="save-update"/> 2.here’s the user of Address <one-to-one name="user" class="User" constrained="true"/>

  41. XML Mapping <class name="Address" table="ADDRESS"> <id name="id" column="ADDRESS_ID"> <generator class="foreign"> <param name="property">user</param> </generator> </id> ... <one-to-one name="user" class="User" constrained="true"/> </class>

  42. Many-to-many associations A unidirectional many-to-many association <set name="items" table="CATEGORY_ITEM" lazy="true" cascade="save-update"> <key column="CATEGORY_ID"/> <many-to-many class="Item" column="ITEM_ID"/> </set>

  43. Many-to-many associations We can also use a bag with a separate primary key column: <idbag name="items" table="CATEGORY_ITEM” lazy="true" cascade="save-update"> <collection-id type="long" column="CATEGORY_ITEM_ID"> <generator class="sequence"/> </collection-id> <key column="CATEGORY_ID"/> <many-to-many class="Item" column="ITEM_ID"/> </idbag>

  44. Many-to-many associations <list name="items" table="CATEGORY_ITEM” lazy="true" cascade="save-update"> <key column="CATEGORY_ID"/> <index column="DISPLAY_POSITION"/> <many-to-many class="Item" column="ITEM_ID"/> </list>

  45. Many-to-many associations Transaction tx = session.beginTransaction(); Category cat = (Category) session.get(Category.class, categoryId); Item item = (Item) session.get(Item.class, itemId); cat.getItems().add(item); tx.commit();

  46. Many-to-many associations • A bidirectional many-to-many association <class name="Category" table="CATEGORY"> ... < set name="items" table="CATEGORY_ITEM" lazy="true" cascade="save-update"> <key column="CATEGORY_ID"/> <many-to-many class="Item" column="ITEM_ID"/> </set> </class> • A bidirectional many-to-many association <class name="Item" table="ITEM"> ... <set name="categories" table="CATEGORY_ITEM" lazy="true" inverse="true" cascade="save-update"> <key column="ITEM_ID"/> <many-to-many class="Item" column="CATEGORY_ID"/> </set> </class>

  47. Understanding the Hibernate type system Built-in mapping types Java primitive mapping types Using mapping types Creating custom mapping types

More Related