精通Hibernae读书笔记2

来源:互联网 发布:python编程语言排行榜 编辑:程序博客网 时间:2024/04/29 04:32

 第二章 java对象持久化技术概述

本章介绍对象持久化的集中模式

1.在业务逻辑层直接通过JDBCAPI来持久化实体域对象,业务逻辑和数据访问耦合。

2.主动域对象模式

3.ORM模式

4.JDO模式

5.CMP模式

2.1通过JDBC API来持久化实体域对象 

Java应用访问数据库的最直接的方式就是直接访问JDBC APIJDBCJava Database Connectivity的缩写。

java.sql包提供了JDBC API。在java.sql包中常用的接口和类包括:

DriverManager:驱动程序管理器,负责创建数据库连接。

Connection:代表数据库连接。

Statement:负责执行SQL语句。

PreparedStatement:负责执行SQL语句,具有预定义SQL语句的功能。

ResultSet:代表SQL查询语句的查询结果集

JDBC驱动程序

Java应用必须通过JDBC驱动程序来和特定的数据库系统连接。 

JDBC驱动程序由数据库厂商或第三方提供。

负责持久化Customer对象的BusinessService

saveCustomer():把Customer域对象永久保存到数据库中。

updateCustomer():更新数据库中Customer域对象的状态。

deleteCustomer():从数据库中删除一个Customer域对象。

loadCustomer():根据特定的OID,把一个Customer域对象从数据库加载到内存中。

findCustomerByName():根据特定的客户姓名,把符合查询条件的Customer域对象从数据库加载到内存中。

业务逻辑代码与数据访问代码耦合的saveCustomer()方法

  con=getConnection(); //获得数据库连接

      //开始一个数据库事务

      con.setAutoCommit(false);

      //以下是业务逻辑代码,检查客户姓名是否为空

      if(customer.getName()==null)

        throw new BusinessException("客户姓名不允许为空");

      //以下是数据访问代码,持久化Customer对象

      //为新的CUSTOMERS记录分配惟一的ID

      long customerId=getNextId(con,"CUSTOMERS");

      //Customer对象映射为面向关系的SQL语句

      stmt=con.prepareStatement("insert into CUSTOMERS(ID,NAME,AGE) values(?,?,?)");

      stmt.setLong(1,customerId);

      stmt.setString(2,customer.getName());

      stmt.setInt(3,customer.getAge());

      stmt.execute();

业务逻辑代码与数据访问代码耦合的saveCustomer()方法

      Iterator iterator =customer.getOrders().iterator();

      while (iterator.hasNext() ) {

        //以下是业务逻辑代码,检查订单编号是否为空

        Order order=(Order)iterator.next();

        if(order.getOrderNumber()==null)

          throw new BusinessException("订单编号不允许为空");

        //以下是数据访问代码,级联持久化Order对象

        //为新的ORDERS记录分配惟一的ID

        long orderId=getNextId(con,"ORDERS");

        //Order对象映射为面向关系的SQL语句

        stmt=con.prepareStatement("insert into ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID)values(?,?,?,?)");

        stmt.setLong(1,orderId);

        stmt.setString(2,order.getOrderNumber());

        stmt.setDouble(3,order.getPrice());

        stmt.setLong(4,customerId);

        stmt.execute();

      }

      //提交数据库事务

      con.commit();

JDBC编程的缺点

实现业务逻辑的代码和数据库访问代码掺杂在一起,使程序结构不清晰,可读性差。

在程序代码中嵌入面向关系的SQL语句,使开发人员不能完全运用面向对象的思维来编写程序。

业务逻辑和关系数据模型绑定,如果关系数据模型发生变化,例如修改了CUSTOMERS表的结构,那么必须手工修改程序代码中所有相关的SQL语句,这增加了维护软件的难度。

如果程序代码中的SQL语句包含语法错误,在编译时不能检查这种错误,只有在运行时才能发现这种错误,这增加了调试程序的难度。

数据访问模式

业务逻辑和数据访问耦合

ORM模式:在单个组件中负责所有实体域对象的持久化,封装数据访问细节。 

主动域对象模式:由实体域对象本身负责管理自己的持久化

JDO模式: SUN公司制定的描述对象持久化语义的标准API 

CMP模式:由容器负责管理持久化

2.2ORM简介

对象-关系映射(Object-Relation Mapping)模式是指在单个组件中负责所有实体域对象的持久化,封转数据访问细节。

2.2.1对象-关系映射(Object-Relation Mapping)的概念

ORM解决的主要问题就是对象-关系的映射。域模型和关系模型都分别建立在概念模型的基础上。域模型是面向对象的,而关系数据模型是面向关系的.

一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录。

域模型与关系模型之间存在许多不匹配之处:

域模型中有继承关系,关系模型不能直接表示继承关系

域模型中有多对多关联关系,关系模型通过连接表来表示多对多关联关系

域模型中有双向关联关系,关系模型只有单向参照关系,而且总是many方参照one方。

域模型提倡精粒度模型,而关系模型提倡粗粒度模型

域模型与关系模型之间的不匹配举例

2.2.3 ORM中间件的使用方法

   ORM中间件采用元数据来描述对象-关系映射文件细节,元数据采用XML格式,而且保存在专门的对象-关系映射文件中。

在图中Session接口向业务逻辑提供了读写和删除域对象的方法,他不公开任何数据访问细节,SessionImpl实现这个接口。SessionFactroy负责创建Session实例。Hibernate在初始阶段把对象-关系映射文件的映射元数据读入到SessionFactory中。

Public void deleteCustomer(Customer customer)

{

   Session sesion=getSession();

   Session.delete(customer);

}

Sessiondelete()方法执行以下步骤:

1>运用Java反射机制,获得customer对象的类型为Customer.class

2>参考对象-关系映射元数据,了解到和Customer类对应的表为CUSTOMERS表,此外Customers类和Order类关联,Order类和ORDER表对应,ORDERS表的外键CUSTOMER_ID参照CUSTOMER表的ID主键

3>根据以上映射信息,生成SQL语句

   Delete from ORDERS where CUSTOMER_ID=

   Delete from CUSTOMERS where ID=

4>通过JDBC API来执行以上SQL语句

2.2.3 常用的ORM中间件

ORM软件

URL

Hibernate

http://www.hiberante.org

TopLink

http://otn.oracle.com/products/ias/toplink/content.html

Torque

http://jakarta.apache.org/turbine/torque/index.html

ObjectRelatinalBridge

http://db.apacche.org/ojb/

FrontierSuite

http://www.objectfrontier.com

Castor

http://castor.exolab.org

FreeFORM

http://www.chimu.com/projects/form/

Expresso

http://www.jcorporate.com

JRelationalFframework

http://jrf.sourrceforge.net

VBSF

http://www.objectmatter.com

Jgrinder

http://sourceforge.net/projects/jgrinder/

JPA

直接对轻量级的基于JavaBean形式的实体域进行持久化

2.3实体域对象的其他持久化模式

2.3.1主动域对象模式

  主动域是实体域对象的一种形式,在它的实现中封装了关系数据模型和数据访问细节。

EJB中分实体Bean分为:由EJB本身管理持久化,即BMP是主动域对象模型的一个例子,BMP表示有实体EJB本身管理数据访问细节。

主动域对象模式的优点:

A>在实体域对象中封装自身的数据访问细节,过程域对象完全负责业务逻辑,是程序结构清晰

B>如果关系数据模型发生冲突,只需改变主动域对象的代码,不需要修改过程域对象的业务方法。

主动域对象模式的缺点:

A>在实体域对象的实现中仍然包含sql语句

B>每个实体域对象都负责自身的数据访问实现。

2.3.2JDO模式

Java Data Objects(JDO)sun制定的描述对象持久化语义的标准API

采用JDO模式的应用的分层结构

JDO支持关系数据库。面向对象的数据库.基于XML的数据库和其他专用存储系统

2.3.3 CMP模式

CMP模式表示由EJB容器来管理实体EJB持久化,EJB容器封装了对象-关系的映射及数据访问细节。

2.4HibernateAPI简介

1.提供访问数据库的操作(如保存.跟新.删除和查询对象)的接口。包括Session.TransacctionQuery接口。

2.用于配置Hibernate的接口。包括Configuration

3.使应用程序拦截Hibernate内部发生事件,并做出相关的反应。这些接口:Interceptor.LoadEventListenerSaveEventListener

4.用于扩展Hibernate的功能接口。如UserType.CompositeUserTypeIdentifierGenerator接口。

Hibernate内部封装了JDBCJTA(JAVA Naming and Directory Interface).JDBC提供底层的数据访问操作,只要用户提供相应的JDBC驱动程序,Hibernate可以访问任何数据库。JNDIJTA使Hibernate能够和j2ee应用服务器集成。

2.4.1hibernate的核心接口

1.Configuration接口是配置Hibernate并且根启动Hibernate,创建SessionFactory对象。Hiberante应用通过Configuration实例来获得对象-关系映射文件中文件的元数据,以及动态配置Hibernate的属性,然后创建sessionFactory的实例

2.SessionFactory接口:初始化hiberante,充当数据存储源的代理,创建Session对象。一个SessionFactory实例对应一个数据存储源,应用以SessionFctory中获取Session实例。

SessionFctory的特点:

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

  2.它是重量级,这意味着不能随意的创建或者销毁它的实例。访问一个数据库创建一个SessionFactory,访问多个就创建多个。(被称为重量级的是因为:1。它需要很大的缓存存放预定义的SQL语句及映射元数据等。还可以配置SessionFactory的缓存插件,被称为Hibernate的二次缓存,用来存放被工作单元读过的数据,将来其他工作单元会重用这些数据,因此这个缓存中的数据能够被所有工作单元共享,一个工作单元对应一个数据库事务。)

3.Session接口:负责保存.更新.加载和查询对象,被称为持久化管理器

  特点:1。不是线程安全的

        2.。是轻量级的,是指创建和销毁不需要消耗太多的资源

  注意:Session有一个缓存,被称为Hibernate的一级缓存,它用来存放当前工作单元加载的对象。每个session实例都有自己的缓存,这个session实例的缓存只能被当前工作单元锁使用

4.Transaction:管理事务。是hibernate的数据库事务接口,它对底层的事务接口做了封装,这些递呈的事务接口包括:

   1JDBCAPI

   2JTA(Java Transaction API)

   3.CORBA(Common Object Requet Broker Architecture)API

5.QueryCriteria:执行数据库查询.Qurey包装了一个HQl查询语句,Criteria接口封装了基于字符串形式的查询语句,擅长执行动态的查询

                Hibernte核心接口的类框图

2.4.2时间处理接口

   当程序通过hibernate来加载.保存.跟新和删除对象时,会触发Hibernate的拦截器及事件监听器做出的恶性一处理:

1.事件及事件监听接口:在HibernateAPI,针对每一种事件都有相应的事件监听器,如加载对象会触发org.hibernate.event.LoadEven事件,该事件有org.hibernate.event.LoadeventListener监听器处理。保存对象触发org.hibernate.event.SaveEvent事件,该事件由org.hibernate.event.SaveEventListener监听器处理

2.org.hibernate.Interceptor接口:应用程序可以定义实现Interceptor接口的类,Interceptor实现类负责响应持久化类的实例被加载.保存更新或者删除的事件。

2.4.3映射类型接口

org.hibernate.type.Type接口表示Hibernate映射类型,用于把域对象映射为数据库的关系数据。HiberanteType接口提供了各种实现类:

1.PrimitiveType类型:映射java的基本类型:ByteTypeshortTypeIntegerTypeLongType

FloatTypeDoubleTypecharacterTypeBooleanType这八个类

2.DateType:映射Java日期类型

3.BinaryType:硬塞Byte[]

 

原创粉丝点击