Hibernate之关系对象映射详解

在上一篇Hibernate文章中,做出了第一个Hibernate例子,接下来就详细说说Hibernate。

java应用程序通过getter和setter操作内存中的javabean对象,而Hibernate作为java应用与数据库的中间层通过gette将javabean对象的属性信息映射为数据库中的表的列,setter将数据库中的数据填入javabean对象。

确切的说,当Hibernate的session对象调用save,update方法时会调用javabean的getter方法,而执行load,get方法时调用javabean的setter方法,由于Hibernate是通过反射调用的javabean中的方法,所以方法的访问权限可以是private。

在持久化类和数据库表的映射文件(如Customer.hbm.xml)中,有这么一个元素:

<property name="sex"       column="SEX"       type="character"/>    

其中property的属性可以有access,如果给一个field的值,那么Hibernate利用反射直接对持久化类的属性域进行读写,默认的是通过getXXX()和setXXX()来读写的。因此,在默认的方式下,可以在getter和setter中写业务逻辑,如,将name拆为firstname和lastname分别设置,而该类中并没有对应的name属性,而是firstname属性和lastname属性。例:

private String firstname;
private String lastname;
public void setName(String name){
	String[] names = name.split(" ");
	firstname = names[0];
	firstname = names[1];
}
public String getName(){
	return firstname+" " + lastname;
}

另外,property元素还有几个重要的属性:


标识符

字段作为标识符需要满足如下三个条件:不为空,在表中唯一,不会改变

Hibernate使用OID来标识每个对象,可以使用identity,hilo,native,increment这四个。

在持久类与表的映射文件中,

<id name="id" column="ID" type="long">
      <generator class="increment"/>
    </id>

更改class的值即可。

一对多的关联

当两个类是一对多的关系(如顾客与订单)时,需要考虑以下:

是单向的关联还是双向的关联,这取决于逻辑业务。如,一个顾客有多笔订单,经常要找一个顾客的所有订单以及一笔订单属于哪个顾客,就需要双向关联。

当保存一方时,是否需要先保存另一方,即级联保存。如保存订单对象时是否要先保存顾客对象。

当一方删除时,另一方是否有必要删除,即级联删除。如顾客删除时,所有属于该顾客的订单都被删除。

顾客的映射文件:

<set 
        name="orders"
        inverse="true"
        cascade="save-update" 
        >
        
        <key column="CUSTOMER_ID" />
        <one-to-many class="mypack.Order" />
     </set>   

订单的映射文件:
<many-to-one
        name="customer"
        column="CUSTOMER_ID"
        class="mypack.Customer"
        cascade="save-update"
       />

Hibernate持久化一个对象的细节

在Hibernate的Session类中有个缓存,这个缓存中的对象就是持久化对象,通过清理缓存来同步数据库时。站在持久层的角度上看,对象有四种状态:游离状态(数据库中存在但不在session缓存中的对象),删除状态(即将被删除的记录),持久化状态(在session缓存中的对象),临时状态(在jvm内存的对象,即刚new完的对象)。

当session对象调用save()时,持久化对象被加入到缓存中;当调用get()方法时判断缓存中是否有要查找的对象,有的话就直接返回session缓存中的那个对象,没有的话就去数据库中加载;当调用close()时就清理缓存,进行脏检查,如果缓存中的数据和数据库中的数据不一致就更新数据库。

另外,在以下情况也会清理缓存:

Transaction对象调用commit()时

执行一些查询操作时

session调用flush()时

可以通过session的setFlushMode()来更改清理缓存的时间点。


类型映射

<property name="sex"       column="SEX"       type="character"/>    
对于这样的映射,其中的type的值是Hibernate的类型,那么它是将什么java类型映射成什么数据库类型呢?且看下表:

Hibernate类型 java类型标准sql类型

int Integer(int)int

long  Long(long)bigint

short Short(short)  smallint

byte Byte(byte) tinyint

float Float(float)float

double Double(double) double

character Character(char)char(1)

string Stringvarchar()

boolean Boolean(boolean) bit

yes_no Boolean(boolean)char(1)

true_false Boolean(boolean) char(1)

时间日期的映射:

date java.util.Date(java.sql.Date)date(YYYY-MM-DD)

time java.util.Date(java.sql.Date) time(HH:mm:ss)

timestamp java.util.Date(java.sql.Timestamp)timestamp(YYYYMMDDHHmmss)

calendar java.util.Calendartimestamp

calendar_date java.util.Calendar date

大对象的映射:

text Stringclob

binary byte[]varbinary(blob)

serializable Serializable接口类varbinary(blob)

blob java.sql.Blobblob

clob java.sql.Clob clob


你可能感兴趣的:(Hibernate,映射)