Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57128
  • 博文数量: 11
  • 博客积分: 210
  • 博客等级: 二等列兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-01 11:55
文章分类
文章存档

2013年(6)

2008年(5)

我的朋友

分类: Java

2008-08-01 14:59:21

JAVA应用中建立Hibernate的步聚

 

建立Hibernate的配置文件

创建持久化类

创建对象-关系映射文件

通过Hibernate API访问数据库

Hibernate应用程序的结构

Hibernate的配置文件

Hibernate配置信息由一个XML文件来指定,常用的配置参数:

 

建立持久化类

持久化类必需符合JavaBean的规范,以及包含一些属性,以及与之对应的getXXX()setXXX的方法。

持久化类必需要有一个id属性用于唯一标识该类的对象。在面向对象的术语中这个id属性 又被 称之为对象标识符(OID,Object Identifier),一般用整数表示。

Hibernate要求持久化类必需提供一个不带参数的默认构造 方法。

    参见工程示例:Customer.java

建立数据库Schema

Create table Customer(

Id bigint not null primary key,

….

);

需要为对应实体类对应的表建立主键。

建立对象与关系映射文件

映射文件的名称及存放位置最好与持久化类的名称及位置保持一致。

Hbm文件:

          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

          "">

   

Id元素映射OID

子元素用于设定标识符生成器。Hibernate有提供多种类型的实现。

   

元素映射值类型属性

name属性:指定持久化类的属性名字。

column属性:指定持久化类的属性映射的表的字段名。

type属性:指定与类的属性映射类型。类型可以指定为hibernate类型或java类型 hibernate类型 是java类型 与SQL类型的桥梁。

Java类型、hibernate类型、及SQL类型之间的对应关系

采用XML文件配置对象-关系映射的优点

Hibernate即不会渗透到上层的域模型中,也不会渗透到下层的数据模型中。

软件开发人员可以独立的设计域模型,而必强迫遵守任何规范。

数据库设计人员也可以独立的设计数据 模型,而不必强迫遵守任何规范。

对象-关系的映射不依赖任何的程序代码,如果需要修改对象-关系的映射,只需要修改XML文件,而不需要修改任何的程序代码,提高了软件的灵活性,并且更加容易维护。

通过Hibernate API来操纵数据库

通过Hibernate API来操纵数据库

通过Hibernate API来操纵数据库

初始化Hibernate

通过HibernateSession接口来操作数据库:

保存持久化对象

更新持久化对象

加载持久化对象

删除持久化对象

检索持久化对象

Hibernate的初始化

    private static SessionFactory sessionFactory = null;

    static{

        try{

            //根据Hibernate的配置文件建立一个Configration的实例

            //其中configfile为配置文件类路径

            Configration config = new Configration(configfile);

            //建立SessionFactory实例

            sessionFactory = config.buildSessionFactory();

 

        }catch(Exception e){

            e.printStackTrance();

        }

    }

SessionFactory接口

一个SessionFactory的实例对应一个数据存储源,应用从SessionFactory中获取Session的实例。

SessionFactory具有以下几个特点:

它是线程序安全的,意味着它的同一个实例可以被 多个线程共享。

它是重量级的Java对象,这意味着它不能随意的创建或销毁。如果应用只有一个数据库,只需要建立一个SessionFactory的实例就可以了,应当在应用程序初始化时就建立,如果需要访问多个数据库,则需要建立多个SessionFactory实例。

 

Session接口

Session接口是Hibernate应用最为广泛的接口。

Session也被称为持久化管理器,它提供了持久化相关的操作,例如:添加,删除,更新,载入,查询对象等。

Session具有以下几个特点:

它不是线程安全的,因此在设计软件时,应当避免多个线程序共享同一个Session实例。

它是一个轻量级的对象,所谓轻量级是指对象的建立和销毁不需要消耗很多的系统资源,在应用程序中你可以经常建立和销毁Session对象。

Session接口常用的方法

Session接口有提供用于操作数据库的一些常用方法:

Save:把java对象保存到数据库中。

Update:更新数据库中的java对象。

Delete:删除数据库中的java对象。

Load:从数据库中加载java对象

Find:从数据库中查找java对象。

 

session来执行事务的流程

Transaction tx = null

try{

//开始一个事务

tx = session.beginTransaction();

    //执行事务

….

//提交事务

tx.commit();

}catch(Exception e){

    //回滚事务

    tx.rollback();

}

 

 

 

元素属性

name:设定待映射的持久化类的属性名。例如:Oder类中的customer属性。

column:设定和持久化类的属性对应的表的外键,例如:Orders表中的Customer_ID

class:设定持久化类的该属性的类型,例如:Customer

 

class=“Customer”/>

 

注意:使用多对一时,应当在多的一方使用例如在Order持久化类中。

元素的属性

一般包括以下几个属性:

name设定待映射的持久化的类的属性名,例如:Customer中的orders

cascade用于设定级联的级别,例如:save-update表示级联保存和更新。

inverse:当设为true时,表示在双向关联中,当前端为镜像端。

table:用于映射多对多时,表示对应的关联表。

元素的子元素:

用于设定与所关联的持久化类对应表的外键,例如:Order表中的Customer_ID

用于设定所关联的持久化类。

用于设定多对多所关联的关联持久化类。

 

cascade属性

映射category一对多双向自身关联

Category类图

Category的表的结构

映射一对多自身双向关联

    column=“CATEGORY_ID”

    class=“vo.Category”

    />

casecade=“all-delete-orphan”

inverse=“true”

>

映射一对一双向关联

一对一关可分为:共享主键一对一关联,及使用主键与外键实现一对一双向关联。

参见示例:StudClass StudGroup

   

映射多对多双向关联

产品类别:Category

   

    casecade=“save-update” inverse=“true”>

   

   

产品:Product

   

    >

   

   

 

nHibernate的缓存分为:

¨一级缓存,单个会话的对象缓存。

¨二级缓存,可插拔的缓存插件

 

nSession加载或保存一个对PO时,PO将被Session缓存。

n当再次通过Session加载相同OIDPO时,Hibernate将直接从Session的缓存中获取。

nSession关闭时,缓存将被清空。

 

//第一次加载时将产生SQL访问数据库

Customer cusa = (Customer)session.get(Customer.class, 1l);

//第二次加载同样的CustomerHibernate将从Session中获取

Customer cusb = (Customer)session.get(Customer.class, 1l);

//cusacusb应当是同一对象

If(cusa == cusb)System.out.println(“同一个对象!”);

//缓存被清空

session.close();

 

 

n减少访问数据库的频率。

应用程序从内存中获取对象明显快于从数据库中查找。

n保证缓存中的对象与数据库相关的记录同步。

当处于缓存中的PO的属性发生改变时,Session不会立即更新数据库,它可以将多次更新合并处理后产生一条更新语句。

Customer customer = (Customer)session.load(Customer.class, 1);

customer.setName("jack");

customer.setName("mike");

//以上只会产生一条sql语句。

update Customer set name = 'mike' ...

 

nHibernate会在特定的时间自动同步缓存与数据库

¨当提交事务时

¨当执行session的查询方法时

¨当执行session.flush

n注意:关闭Session时,Hibernate不会执行缓存同步。

 

n二级缓存是一个可以插拔的缓存插件,它由SessionFactory负责管理,由于SessionFactory对象的生命周期和应用程序的生命周期对应,因此二级缓存是进程范围或群集范围的缓存。

n缓存中存放的是对象的散装数据而不是对PO的引用。

n二级缓存是可选的,可以在每个类或每个集合的粒度上配置二级缓存。

 

nHibernate默认使用EhCacheProvider提供二缓存支持,可通过配置参数hibernate.cache.provider_class设置其它的缓存器。

n通过在元素或等集合元素中配置元素来设置Hibernate的二级缓存策略或通过Hibernate的配置 参数指定。

n配置属性:

¨usage用于指定缓存的策略

¨region指定缓存对象存放的区域名,默认为类名或集合名。

¨include表示缓存对象的种类all所有的,non-lazy不包含延迟加载的。

nread-only缓存的对象只可以读取。

nread-write缓存的对象可读写。

nnonstrict-read-write非严格的读写,适合于并发更新的情况非常小。

ntransaction适用于jta事务范围内的缓存

//Customer使用读写二级缓存

   

   

//执行下面一条时,Hibernate将产生一条SQL

Customer cus = (Customer)session.get(Customer.class, 1l);

//关闭Session的一级缓存清空,但二级缓存中仍保留有cus的数据

session.close();

//打开session再次获取Customer时,检查控制台并未产生一条SQL

//Hibernate此时并未从数据库中获取数据而是从二级缓存中获取。

Customer cus = (Customer)session.get(Customer.class, 1l);

 

PO状态

n临时状态(transient):刚刚用new语句建立,还没有被持久化,不处于session的缓存中。

n持久化对象(persistent):已经被持久化,加入到session的缓存中。

n游离状态(detached):已经被持久化,但不再处于session的缓存中

PO状态转换

Session session = sf.getCurrentSession();

Transaction tx = session.beginTransaction();

Customer cus = new Customer();//临时状态

cus.setName("Tony");

session.save(cus);//持久化状态

tx.commit();

session.close();

//修改游离态的Customer对象

cus.setName("ModTonyName");

Session session2 = sf.getCurrentSession();

Transaction txb = session2.beginTransaction();

session2.update(cus);//关联游离态的对象

txb.commit();//保存更新

session2.close();

 

nHibernate对于PO及集合属性的数据采用延迟加载的策略。

n对于PO初始化时并不加载属性,只有在访问时才加载数据。

n对于set集合,只有当访问集合元素时才执行加载。

n注意:只有持久化状态下的对象才可以执行延迟加载。

 

n优点

¨由应用程序决定需要加载那些对象,可以以避免执行多余的select语句,避免加载应用程序不需要的访问对象。因此能提高检索性能,并能节省内存空间。

n缺点

¨应用程序如果希望访问游离的代理类实例,必需保证它在持久化状态时已被初始化。

 

 

 

 

 

 

 

 

 

 

 

 

 

阅读(971) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~