配置映射属性
Hibernate 允许您在配置文件中将类及其属性与数据库的表映射。
该映射文件的名称有以下语法:
<persistent class name>.hbm.xml
<persistent class name>
是用于处理应用程序中数据存储和检索的类的名称。
Hibernate 映射文件:
克服了在类中使用的数据类型和表的列中所使用数据类型之间的差异问题。
包含类数据类型与特定于数据库的数据类型之间的映射信息。
Hibernate 通过允许用户使用他们选择的关系数据库来提供透明的持久性。
Hibernate 类型:
提供底层数据库类型的抽象表示。
允许您开发应用程序,而无需担心目标数据库及其支持的数据类型。
为您提供了在无需更改应用程序代码的情况下更改数据库的灵活性。
Hibernate 基本值类型:
能让您将特定于数据库的数据类型映射到类属性的数据类型。
是内置类型,将Java 数据类型与SQL 数据类型映射。
下表列出了一些Hibernate 内置类型以及相应的Java 和SQL 数据类型:
Hibernate类型 | Java类型 | SQL类型 |
---|---|---|
integer、long、short | Integer、int、long short | NUMERIC、NUMBER、INT 或其他特定于供应商的类型。 |
character | char | CHAR |
big_decimal | java.math.BigDecimal | NUMERIC、NUMBER |
float、double | float、double | FLOAT、DOUBLE |
boolean、yes_no、true_false | java.lang.Boolean、boolean | BOOLEAN、INT |
string | java.lang.String | VARCHAR、VARCHAR2 |
date、time、timestamp | java.util.Date | DATE、TIME 和TIMESTAMP |
calendar、calendar_date | java.util.Calendar | TIMESTAMP、DATE |
locale | java.util.Locale | VARCHAR、VARCHAR2 |
timezone | java.util.TimeZone | VARCHAR、VARCHAR2 |
Currency | java.util.Currency | VARCHAR、VARCHAR2 |
Class | java.util.Class | VARCHAR、VARCHAR2 |
Binary | byte array | binary field |
Text | java.lang.String | CLOB、TEXT |
clob | java.sql.Clob | CLOB |
Blob | java.sql.Blob | BLOB |
Hibernate 映射文件:
充当持久性类与数据库表之间的通信介质。
能通过使用Hibernate 类型将持久性类中使用的数据类型与特定于数据库的数据类型映射来进行通信。
在将持久性类对象与数据库中的表映射起来时,Hibernate 将对象按以下类型分类:
- 实体类型
是一个独立的实体,并且在数据库表中有其自己的主键。
- 值类型
没有标识符并依赖于实体类型对象存在。
Hibernate 映射文件包含以下常用的元素:
<DOCTYPE>
指定了当前XML 文档的类型以及包含验证当前XML 文档中所使用元素的规则的DTD 名称。
<hibernate-mapping>
指包含其他映射元素(例如:<class>、<id>和<generator>)的根映射元素。
指与数据库表映射的Java 类。
<class>
指与数据库表映射的Java 类。
<id>
指数据库表的主键列。
<generator>
指用于为数据库表中持久性类的实例生成唯一标识符的Java 类
<property>
用于将Java 类的属性与数据库表的特定列映射。
例如:
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!--Generated Oct 17, 2010 3:42:14 PM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
<class name="HibernateTest.Employee" table="EMPLOYEE">
<id name="empID" type="int">
<column name="EMPID" />
<generator class="assigned" />
</id>
<property name="empName" type="string" column ="EMPNAME" length="30"/>
<property name="empAddress" type="string" column ="EMPADDRESS" length="200"/>
</class>
</hibernate-mapping>
在开发应用程序时,您可能会发现一般属性会在应用程序的各个类间共享。
此外,共享属性包含多个构成元素。
为了在您的应用程序中实现可重用性和模块性,您可以:
- 创建Java 类来表示共享属性。
- 在应用程序中从任何类引用Java 类。
此Java 类称作值类型。
引用此Java 类的类称作“实体类”。
映射实体类的组件
值类型:
- 作为实体类的组件映射。
- 在Hibernate 映射文件中使用元素映射。
例如:
CREATE TABLE ORDERS (
ORDER_ID INT PRIMARY KEY,
WEEKDAY_RECIPIENT VARCHAR(40),
WEEKDAY_PHONE VARCHAR(20),
WEEKDAY_ADDRESS VARCHAR(100),
HOLIDAY_RECIPIENT VARCHAR(40),
HOLIDAY_PHONE VARCHAR(20),
HOLIDAY_ADDRESS VARCHAR(100)
)
为应用程序创建ORDERS表,该应用程序将有关组织中各个客户所下的订单的信息存储在数据库中
要映射ORDERS 表,使用以下代码段创建名为OrderDetails的Java 类:
public class OrderDetails{
private int orderID;
private String weekdayRecipient;
private String weekdayPhone;
private String weekdayAddress;
private String holidayRecipient;
private String holidayPhone;
private String holidayAddress;
. . . }
工作日和假日的收件人的recipient、phone 和address 属性重复了。
为了解决上述问题,您创建了新类ContactDetails,如以
下代码段所示:
public class ContactDetails {
private String recipient;
private String phone;
private String address;
. . . . . . . . . . . .
}
此类封装了客户的联系详细信息。
现在,您可以为工作日和周末联系人详细信息创建ContactDetails类的两个不同的实例。
OrderDetails类可以使用这些实例来指定工作日和假日联
系人详细信息。
例如:
public class OrderDetails {
private int orderID;
//Instances for weekdays and holiday contacts
private ContactDetails weekdayContact;
private ContactDetails holidayContact;
. . . . . . }
指定联系人详细信息依赖于OrdersDetails类。
在Hibernate 应用程序中,组件类的映射与实体类的映射不同。
实体类的映射在标记下配置。
标记为对象创建唯一标识符。
组件类则在标记下配置。
例如:
<hirbernate-mapping>
<class name="OrderDetails" table="ORDER">
<id name="orderID" type="int" column="ORDER_ID">
<generator class="native" />
</id>
<component name="weekdayContact" class="ContactDetails">
<property name="recipient" type="string" column="WEEKDAY_RECIPIENT”/>
......
</component>
<component name="holidayContact" class="ContactDetails">
<property name="recipient" type="string" column="HOLIDAY_RECIPIENT”/>
......
</component>
</class>
</hibernate-mapping>
将ContactDetails类的两个实例表示为两个不同的组件。
映射集合
当类的属性声明为集合时,您需要在Hibernate 映射文件中执行集合映射。
在Hibernate 映射文件中常用的集合映射元素有:
<set>
<list>
<bag>
<set>
元素:
- 当集合中不需要重复的元素时使用。
- 不维持集合中其元素的顺序。
- 用于在Hibernate 映射文件中映射java.util.Set集合类型的属性。
- -
- 使用以下子元素和属性来完成应用程序和数据库表之间的映射:
cascade属性:
指定在实体上执行的操作也会更新相关的实体。它可以有以下值:
none 用于忽略实体间的关系。因此,实体中发生的任何更改都不会反映在其相关的实体中。
save-update 用于在其相关实体中反映在实体中进行保存或更新操作所引起的更改。
delete 用于在其相关实体中反映在实体中进行删除操作所引起的更改。
all 用于在其相关实体中反映在实体中进行保存、更新或删除操作所引起的更改。
name属性:
指定存储集合对象的数据库表名称。
<key>
元素:
借助以下常用的属性指定将实体和集合对象关联起来的属性:
Column
指定作为外键存储在集合表中的实体表的列名。
not-null
指定外键列是否包含空值。
<one-to-many>
元素:
指定实体和集合对象之间的一对多关系。
包含class属性。这个属性包含集合对象的名称。
例如:
package Test;
import java.util.Set;
public class Authors {
private String authorID;
private Set<Books> books;
public String getAuthorID() {
return authorID;
}// getters and setters...... }
声明三个属性:authorID、authorName和books
Authors类称作一个实体,它拥有Books类的集合。
您可以使用以下代码段创建Books类:
package Test;
public class Books {
private String bookID;
private String bookName;
public String getBookID() {
return bookID;
}//getters and setters?
}
声明两个属性:bookID和bookName。
Authors类使用Books类的对象作为Set类型的集合值。
要在数据库中存储作者和书籍详细信息,您需要将Books类
作为对象集合映射。
例如:
<hibernate-mapping>
<class name="Test.Authors" table="AUTHORS">
<id name="authorID" type="string">
<column name="AUTHORID" length="20" />
<generator class="assigned" />
</id>
<property name="authorName" type="string">
<column name="AUTHORNAME" length="40" />
</property>
<set cascade="all" name="BOOKS">
<key column="authorid"/>
<one-to-many class="Test.Books"/>
</set>
</class>
<class name="Test.Books" table="BOOKS">
<id name="bookID" type="string">
<column name="bookid" length="20"/>
<generator class="assigned"/>
</id>
<property name="bookName" type="string">
<column name="bookname" length="40"/>
</property>
</class>
</hibernate-mapping>
指定通过使用<set>
元素将Books类作为集合与BOOKS表映射。指定AUTHORS表中的authorid列作为外键存储在BOOKS集合表中。
表示AUTHORS和BOOKS表之间的一对多关系。cascade属性的all值指定在AUTHORS表上执行的所有保存、更新或删除操作也都反映在BOOKS表中。
<list>
元素:
用于表示在其中允许有重复的元素而且元素以升序存储的集合。
需要在集合表中有额外的索引列,此列维持集合中每个元素的位置。
定义每个元素在集合中的位置的列值称作“索引值”。
包含类似于<set>
元素的属性和子元素。
包含<list-index>
子元素。
例如:
package Test;
import java.util.List;
public class Authors{ . . . . . . .
private List<Books> books;
. . . . . . . . . .
public List<Books> getBooks() {
return books;}
public void setBooks(List<Books> books) {
this.books = books;
}
}
Authors类将books属性声明为List类型的集合。
现在,思考以下代码段:
<hibernate-mapping>
. . . . . . . .
<list cascade="all" name="BOOKS">
<key column="authorid" />
<list-index column="bookid"/>
<one-to-many class="Test.Books"/>
</list>
. . . . . . . . . . . . . .
</hibernate-mapping>
指定通过使用元素将Books类作为List类型集合与BOOKS表映射。BOOKS 表的bookid列定义为存储索引值的列。
<bag>
元素:
表示可以有重复的对象集合。
没有任何顺序,与没有索引的ArrayList集合类似。
使用java.util.List或java.util.Collection集合接口来实现。
仅当应用程序中使用的集合可能包含重复值且不维持其元素的顺序时才使用。
使用元素映射。
包含类似于元素的属性和子元素。
例如:
package Test;
import java.util.Collection;
public class Authors{ . . . . . . .
private Collection<Books> books;
. . . . . . .}
public Collection<Books> getBooks() {
return books;}
public void setBooks(Collection<Books> books)
{this.books = books;}
}
将Authors类的books属性声明为Collection类型的集合。
要在Hibernate 映射文件中将Books类映射为包(bag) 集合,您需要使用元素,如以下代码段所示:
<hibernate-mapping>
. . . . . .
<bag cascade="all" name="BOOKS">
<key column="authorid" />
<one-to-many class="Test.Books"/>
</bag>
. . . . . . . . . . . .
</hibernate-mapping>
<bag>
元素用于将Books类作为集合与BOOKS表映射。元素指定了AUTHORS表和BOOKS表之间的一对多关系。