這篇文章主要說的是在Hibernate中的組件(Component)映射,可以參考Hibernate官方文檔的第7章。至于環(huán)境設(shè)置,可以參考這個系列的前面幾篇文章。
1. 創(chuàng)建項目
· 新建一個Java項目:ComponentMapping,注意選中“創(chuàng)建單獨的源文件夾和輸出文件夾”,同時添加“用戶庫”:hibernate。
2. 編寫類文件
· 新建一個類,包名:javamxj.hibernate.component,類名:Person。
/* * Hibernate - 組件(Component)映射 * 創(chuàng)建日期 2005-4-10 * @author javamxj(分享java快樂) * @link Blog: htpp://javamxj.mblogger.cn * htpp://blog.csdn.net/javamxj/ */package javamxj.hibernate.component;/** * @hibernate.class */public class Person { private Long id; private String username; private Address address; /** * @hibernate.id * generator-class="hilo" * unsaved-value="null" */ public Long getId() {return id;} public void setId(Long id) {this.id = id;} /** * @hibernate.property * length="15" * unique="true" * not-null="true" */ public String getUsername() {return username;} public void setUsername(String username) {this.username = username;} /** * @hibernate.component */ public Address getAddress() {return address;} public void setAddress(Address address) {this.address = address;}}
· Person類調(diào)用了Address類,注意在“getAddress()”方法上的“ @hibernate.component”標(biāo)記。
· Address類只含有一些“ @hibernate.property”標(biāo)記,沒有將其獨立映射為一個表。
package javamxj.hibernate.component;public class Address { private String country; private String city; private String street; private String zipCode; public Address() {} public Address(String country, String city, String street, String zipcode) { super(); this.country = country; this.city = city; this.street = street; this.zipCode = zipcode; } /** * @hibernate.property * length = "12" */ public String getCity() {return city;} public void setCity(String city) {this.city = city;} /** * @hibernate.property * length = "12" */ public String getCountry() {return country;} public void setCountry(String country) {this.country = country;} /** * @hibernate.property * length = "6" */ public String getZipCode() {return zipCode;} public void setZipCode(String number) {this.zipCode = number;} /** * @hibernate.property * length = "12" */ public String getStreet() {return street;} public void setStreet(String street) {this.street = street;} public String toString(){ return ("居住在"+ country + city+"市"+ street+"區(qū)" + "\n\t郵政編碼: "+ zipCode); }}
· 雙擊“generate-hbm”任務(wù),會發(fā)現(xiàn)在包中多了一個Animal.hbm.xml文件,在src目錄下會多了一個hibernate.cfg.xml文件,如果沒有,按F5鍵刷新一下。
<?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"><hibernate-mapping> <class name="javamxj.hibernate.component.Person" dynamic-update="false" dynamic-insert="false" select-before-update="false" optimistic-lock="version" > <id name="id" column="id" type="java.lang.Long" unsaved-value="null" > <generator class="hilo"> <!-- To add non XDoclet generator parameters, create a file named hibernate-generator-params-Person.xml containing the additional parameters and place it in your merge dir. --> </generator> </id> <property name="username" type="java.lang.String" update="true" insert="true" access="property" column="username" length="15" not-null="true" unique="true" /> <component name="address" class="javamxj.hibernate.component.Address" > <property name="city" type="java.lang.String" update="true" insert="true" access="property" column="city" length="12" /> <property name="country" type="java.lang.String" update="true" insert="true" access="property" column="country" length="12" /> <property name="zipCode" type="java.lang.String" update="true" insert="true" access="property" column="zipCode" length="6" /> <property name="street" type="java.lang.String" update="true" insert="true" access="property" column="street" length="12" /> </component> <!-- To add non XDoclet property mappings, create a file named hibernate-properties-Person.xml containing the additional properties and place it in your merge dir. --> </class></hibernate-mapping>
· 運行MySql服務(wù)器,然后雙擊“schemaexport”任務(wù),在項目根目錄下,會產(chǎn)生一個“schema-export.sql”文件。
schema-export.sql |
drop table if exists Persondrop table if exists hibernate_unique_keycreate table Person ( id bigint not null, username varchar(15) not null unique, city varchar(12), country varchar(12), zipCode varchar(6), street varchar(12), primary key (id))create table hibernate_unique_key ( next_hi integer )insert into hibernate_unique_key values ( 0 ) |
· 切換到數(shù)據(jù)庫中,會發(fā)現(xiàn)已經(jīng)自動產(chǎn)生了數(shù)據(jù)表Person
5. 測試程序
● 這一次不同于前面的幾個實例,這次先實現(xiàn)一個HibernateUtil輔助類,用來管理Hibernate的Session,這樣測試類的代碼就比較簡單了,可以參考Hibernate官方文檔的第1章。
· 新建一個類,包名:javamxj.hibernate.util,類名:HibernateUtil,代碼如下:
package javamxj.hibernate.util;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import net.sf.hibernate.HibernateException;import net.sf.hibernate.Session;import net.sf.hibernate.SessionFactory;import net.sf.hibernate.Transaction;import net.sf.hibernate.cfg.Configuration;public class HibernateUtil { private static Log log = LogFactory.getLog(HibernateUtil.class); private static SessionFactory sessionFactory; private static final ThreadLocal threadSession = new ThreadLocal(); private static final ThreadLocal threadTransaction = new ThreadLocal(); public static SessionFactory getSessionFactory() { if (sessionFactory == null) { try { // Create the SessionFactory sessionFactory = new Configuration().configure() .buildSessionFactory(); } catch (HibernateException ex) { ex.printStackTrace(); throw new RuntimeException("Configuration problem: " + ex.getMessage(), ex); } } return sessionFactory; } public static Session currentSession() throws HibernateException { Session s = (Session) threadSession.get(); // Open a new Session, if this Thread has none yet if (s == null) { s = getSessionFactory().openSession(); log.debug("###Opening new Session for this thread:" + s); threadSession.set(s); } else { log.debug("###Session was existed:" + s); } return s; } public static void closeSession() throws HibernateException { Session s = (Session) threadSession.get(); threadSession.set(null); if (s != null) { log.debug("###Closing Session of this thread. " + s); s.close(); } } public static void beginTransaction() throws HibernateException { Transaction tx = (Transaction) threadTransaction.get(); try { if (tx == null) { tx = currentSession().beginTransaction(); log.debug("###Starting new database transaction in this thread:"+ tx); threadTransaction.set(tx); } else { log.debug("###Tx was existed:" + tx); } } catch (HibernateException ex) { throw ex; } } public static void commitTransaction() throws HibernateException { Transaction tx = (Transaction) threadTransaction.get(); try { if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) { log.debug("###Committing database transaction of this thread."); tx.commit(); } threadTransaction.set(null); } catch (HibernateException ex) { rollbackTransaction(); throw ex; } } public static void rollbackTransaction() throws HibernateException { Transaction tx = (Transaction) threadTransaction.get(); try { threadTransaction.set(null); if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) { log.debug("###Tyring to rollback database transaction of this thread."); tx.rollback(); } } catch (HibernateException ex) { throw ex; } finally { closeSession(); } }}
· 好了,然后在包javamxj.hibernate.component下新建一個ComponentDemo.java類。
package javamxj.hibernate.component;import java.util.Iterator;import java.util.List;import javamxj.hibernate.util.HibernateUtil;import net.sf.hibernate.HibernateException;import net.sf.hibernate.Session;public class ComponentDemo { public static void main(String[] args) { try { new ComponentDemo(); } catch (HibernateException he) { he.printStackTrace(); } } public ComponentDemo() throws HibernateException { Session sess = HibernateUtil.currentSession(); Person p = new Person(); p.setAddress(new Address("中國", "上海", "普陀", "200055")); p.setUsername("JavaMXJ"); sess.save(p); p = new Person(); p.setAddress(new Address("中國", "北京", "海淀", "100086")); p.setUsername("張三"); sess.save(p); List animals = sess.find("from " + Person.class.getName()); for (Iterator it = animals.iterator(); it.hasNext();) { Person person = (Person) it.next(); System.out.println(person.getUsername() + ":" + person.getAddress()); } HibernateUtil.closeSession(); }}
· 運行這個類,控制臺輸出如下:
· 同時,數(shù)據(jù)表中生成如下數(shù)據(jù):
· 最后的項目結(jié)構(gòu)如下: