Hibernate使用简介

作者 板桥banq

上页

更新对象

在同一Session中更新 ,直接的更改一个对象的方法就是load()它,保持Session打开,然后直接修改即可: Cat cat = (Cat) sess.load( Cat.class, new Long(69) );
//update db

cat.setName("PK");
sess.flush();

 

更新从session脱离的对象

// 第一段sessio

Cat cat = (Cat) firstSession.load(Cat.class, catId);

Cat potentialMate = new Cat();

firstSession.save(potentialMate);

 

// 在更高层次的应用

cat.setMate(potentialMate);

 

// 最后,在新sessio

firstSession.update(cat); // update cat

secondSession.update(mate); // update mate

update() or saveOrUpdate()

在如下场景有特别意义:

1 .在第一个session中取出实体。

2. 实体被传递到表现层。

3. 客户端在界面修改实体数据

4. 修改后的实体被提交。

5. 使用update()在新的session中保存这些修改

 

 

saveOrUpdate

saveOrUpdate在发现主键为空时,可以执行插入insert动作。

saveOrUpdate在版本校验时,会insert:

if the object is versioned (by a <version> or <timestamp>), and the versioproperty value is the same value assigned to a newly instantiated object, save() it

其他情况就类似update

 

 

merge

Merge 类似saveOrUpdate,可以新增。

主要区别是update;

Merge会在update之前查询,将当前实体和数据表进行比较,如果有变化就update,否则不做任何动作。

而saveOrUpdate和Update无论任何时候都作update SQL操作。

 

 

删除持久化对象

使用Session.delete()会把对象的状态从数据库中移除。当然,你的应用程序可能仍然持有一个指向它的引用。所以,最好这样理解:delete()的用途是把一个持久化实例变成临时实例。

sess.delete(cat);

你可以通过传递给delete()一个Hibernate 查询字符串来一次性删除很多对象。

 

 

模型与类图

关联的单向和双向

对于Category而言是一对多关系,这个一对多关系在Category表达,称为单向。

对于Product而言则是多对一关系,这个多对一关系在Product表达,也称为单向。

如果上述两种关系都在Category和Product中都进行了表达,称为双向。

 

 

一对一 使用外健

<class name="Person">

<id name="id" column="personId">
<generator class="native"/>

</id>

<many-to-one name="address" column="addressId" unique="true" not-null="true"/> </class>

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Perso( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )

 

 

 

一对一双向

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/> </id>
<one-to-one name="person" property-
ref="address"/>
</class>

“ property-
ref=”address“中的address为Person对象中的address

 

 

一对一使用共同主键

<class name="Person">

<id name="id" column="personId">
<generator class="native"/>
</id>
</class>
<class name="Address">
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person" constrained="true"/> </class>
create table Perso( personId bigint not null primary key )
create table Address ( personId bigint not null primary key )

 

 

一对一关系

<class name="person" table=“person_table">

<id name="id" column="PERSON_ID">

<generator class="foreign">

<param name="property">employee</param>

</generator>

</id> ...

<one-to-one name="employee" class="Employee" constrained="true"/>

</class>

通过主键一对一关联 , person和employee有相同的主键id名称。

双向关联:

<one-to-one name"employee" class="Employee" property-ref="person"/>

 

 

一对多关系

public class User {

private String id;

private String name;

private CollectiouserProps;

………

}

 

public class UserProperty {

private String propId;

private String name;

private String value;

 

private User user;
………

}

 

 

一对多关系:父方配置

<class name="sample.model.User" table="testuser">

<id name="userId" type="java.lang.String" >

<generator class="assigned"/>

</id>

<bag name="userProps"

inverse="true" cascade="all">

<key column="userId" />

<one-to-many

class="sample.model.UserProperty" />

</bag>

</class>

 

 

一对多关系:子方配置

<class name="sample.model.UserProperty" table="userprops">

<id name="propId" type="java.lang.String" unsaved-value="any">

<generator class="assigned"/>

</id>

<property name="name" />

<property name="value" />

<many-to-one name="user" column="userId" not-null="true"/>

</class>

 

 

多对一关系

多对一关系在Product表达:

public class Product{

private Category category;

…..

}

 

映射配置:

<many-to-one name="category" class="sample.model.Category" column="catId"/>

注释:name是Product中表示关系的属性。column是关系持久化对应的数据表字段。

 

 

双向一对多可提高性能

代表多的子方在保存数据表时,会由一个字段指向父方来代表数据表的多对一连接,如userId 。

缺省情况下:Hibernate首先插入一个子方记录,然后再更新这个子方数据表的连接,将父方的主键写入连接字段。效率比较低。

子方设置,表示由子方管理数据表连接:

<many-to-one name="user" column="userId" not-null="true"/>

父方设置: inverse=“true”,让父方不再管理数据表连接。

 

 

继承

<discriminator column="stateValue"/>

<subclass name="sample.state.ReadyState" discriminator-value="1"> </subclass>

<subclass name="sample.state.FinishedState" discriminator-value="0"> </subclass>

 

 

级联

级联指相互关系,一个对象被施加操作时,与之相关的对象也要进行相应的操作。有all none save-update delete(Hibernate2)

All 表示所有情况下进行级联操作

Save-update表示执行保存更新是进行级联操作

Delete表示在delete操作时进行级联操作。

见教程中的HibernateArticle案例

 

 

级联

Hibernate3针对Session的所有操作persist(), merge(), saveOrUpdate(), delete(), lock(), refresh(), evict(), replicate(),都有对应的create, merge, save-update, delete, lock, refresh, evict, replicate

级联对<one-to-one> 和<one-to-many> 关系有效。

delete-orphan(孤儿) 特殊只适合1:N的孩子

 

 

HQL Query

映射不能包办一切,进一步强大的功能还可以通过HQL 实现。

O/R mapping的征服路程是消灭SQL。

 

Transactiotx= session.beginTransaction();

 

Query query = session.createQuery("from Persoas c where c.id = :id");

query.setCharacter(“id", ‘123456');

 

for (Iterator it = query.iterate(); it.hasNext();) {

Persoperso= (Person) it.next();

out.println(“Find a perso: " + person.getName() );

}

tx.commit();

 

 


  下页

更多Hibernate专题

 

 

猜你喜欢