这篇文章主要说的是在Hibernate中的组件(Component)映射,可以参考Hibernate官方文档的第7章。至于环境设置,可以参考这个系列的前面几篇文章。
1. 创建项目
· 新建一个Java项目:ComponentMapping,注意选中“创建单独的源文件夹和输出文件夹”,同时添加“用户库”:hibernate。
2. 编写类文件
· 新建一个类,包名:javamxj.hibernate.component,类名:Person。
Person.java
/*
* Hibernate - 组件(Component)映射
* 创建日期 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类调用了Address类,注意在“getAddress()”方法上的“ @hibernate.component”标记。
· Address类只含有一些“ @hibernate.property”标记,没有将其独立映射为一个表。
Address.java
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+"区"
+"\n\t邮政编码: "+ zipCode);
}
}
3. 运行任务
· 复制《Eclipse快速上手Hibernate--4. 继承映射(1)》文中的build.xml到项目目录下。
· 双击“generate-hbm”任务,会发现在包中多了一个Animal.hbm.xml文件,在src目录下会多了一个hibernate.cfg.xml文件,如果没有,按F5键刷新一下。
Person.hbm.xml
<?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服务器,然后双击“schemaexport”任务,在项目根目录下,会产生一个“schema-export.sql”文件。
schema-export.sql
drop table if exists Person
drop table if exists hibernate_unique_key
create 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 )
· 切换到数据库中,会发现已经自动产生了数据表Person
5. 测试程序
● 这一次不同于前面的几个实例,这次先实现一个HibernateUtil辅助类,用来管理Hibernate的Session,这样测试类的代码就比较简单了,可以参考Hibernate官方文档的第1章。
· 新建一个类,包名:javamxj.hibernate.util,类名:HibernateUtil,代码如下:
HibernateUtil.java
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类。
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();
}
}
· 运行这个类,控制台输出如下:
· 同时,数据表中生成如下数据:
· 最后的项目结构如下: