• 1. Hibernate技术讲座作者:孙卫琴 linda_j2ee@yahoo.com.cn 参考教材: <<精通Hibernate:Java对象持久化技术详解>> 技术支持网址:www.javathinker.org 讲座融合了孙卫琴老师在复旦、交大等高校以及诸多Java培训机构进行Hibernate教学的经验。在《精通Hibernate:Java对象持久化技术详解》的第2版的附赠光盘中包含本讲座的内容。 点击此喇叭收听语音讲解
  • 2. 本课程简介面向学员 熟悉Java编程语言 了解SQL以及JDBC编程 参考授课时间 2-3天(包括学员上机时间) 课程内容 Java对象持久化技术概述 创建Hibernate应用 映射一对多关联关系 域对象在持久化层的状态 Hibernate检索策略 Hibernate检索方式 数据库事务与并发 映射组成关系
  • 3. Java对象持久化技术概述应用程序的分层体系结构 Java应用的持久化层 软件的模型 概念模型 关系数据模型 域模型 域对象 域对象之间的关系 域对象的持久化概念 直接通过JDBC API来持久化实体域对象 ORM简介 实体域对象的其他持久化模式 主动域对象模式 JDO模式 CMP模式
  • 4. 应用程序的分层体系结构发展双层应用 应用程序层 数据库层 三层应用 表述层 业务逻辑层 数据库层 四层应用 表述层 业务逻辑层 持久化层 数据库层 N层应用
  • 5. 应用程序的分层体系结构发展
  • 6. 软件层的特征 层与层之间存在自上而下的依赖关系,即上层组件会访问下层组件的API,而下层组件不应该依赖上层组件。例如:表述层依赖于业务逻辑层,而业务逻辑层依赖于数据库层。 每个层对上层公开API,但具体的实现细节对外透明。当某一层的实现发生变化,只要它的API不变,不会影响其他层的实现。
  • 7. 软件分层的优点 1.伸缩性 伸缩性指应用程序是否能支持更多的用户。应用的层越少,可以增加资源(如CPU和内存)的地方就越少。层数越多,可以将每层分布在不同的机器上 2.可维护性 可维护性指的是当发生需求变化,只需修改软件的某一部分,不会影响其他部分的代码。 3.可扩展性 可扩展性指的是在现有系统中增加新功能的难易程度。层数越多,就可以在每个层中提供扩展点,不会打破应用的整体框架。 4.可重用性 可重用性指的是程序代码没有冗余,同一个程序能满足多种需求。例如,业务逻辑层可以被多种表述层共享。 5.可管理性 可管理性指的是管理系统的难易程度。将应用程序分为多层后,可以将工作分解给不同的开发小组,从而便于管理。应用越复杂,规模越大,需要的层就越多。
  • 8. Java应用的持久化层 封装JDBC API
  • 9. MVC设计模式与四层应用结构的对应关系
  • 10. Hibernate是持久化层的一种实现方式Hibernate不和特定的业务领域相关,能够把任意一个Java应用与数据库系统连接,它是一种中间件。
  • 11. 软件的模型在软件开发领域,模型用来表示真实世界的实体。 在软件开发的不同阶段,需要为目标系统创建不同类型的模型: 在分析阶段,需要创建概念模型。 在设计阶段,需要创建域模型和数据模型。
  • 12. 模型之间的关系
  • 13. 概念模型概念模型用来模拟问题域中的真实实体。 概念模型描述了每个实体的概念和属性,以及实体之间的关系。 概念模型并不描述实体的行为。 不管是技术人员还是非技术人员都能看得懂概念模型,他们可以很容易的提出模型中存在的问题,帮助系统分析人员及早对模型进行修改。
  • 14. 购物网站应用的概念模型
  • 15. 实体与实体之间存在三种关系 Customer和Order实体: 一对多。一个客户有多个订单,而一个订单只能属于一个客户。 Category和Item实体:多对多。一个商品类别包含多个商品,而一个商品可以属于多个商品类别。 Order和Item实体:多对多。一个订单包含多个商品,而一个商品可以属于多个订单。 Customer和ShoppingCart实体:一对多。一个客户有多个购物车,而一个购物车只能属于一个客户 ShoppingCart和Item实体:多对多。一个购物车包含多个商品,而一个商品可以属于多个购物车。
  • 16. 关系数据模型关系数据模型是在概念模型的基础上建立起来的,用于描述这些关系数据的静态结构,它由以下内容组成: 一个或多个表 表的所有索引 视图 触发器 表与表之间的参照完整性
  • 17. 表的主键在关系数据库表中,用主键来识别记录并保证每条记录的惟一性。作为主键的字段必须满足以下条件: 不允许为null。 每条记录具有惟一的主键值,不允许主键值重复。 每条记录的主键值永远不会改变。 使用代理主键机制,代理主键不具有业务含义,不会被改变。create table CUSTOMER(ID bigint auto_increment primary key, NAME varchar(30)); insert into CUSTOMERS(NAME) values('Tom'); insert into CUSTOMERS(NAME) values('Jack'); select * from CUSTOMER; 查询结果 +----+------+ | ID | NAME | +----+------+ | 1 | Tom | | 2 | Jack | +----+------+
  • 18. 表与表之间的参照完整性 用连接表表示多对多关系
  • 19. 域模型 域模型是面向对象的。在面向对象术语中,域模型也可称为设计模型。域模型由以下内容组成: 具有状态和行为的域对象 域对象之间的关系 关联 依赖 聚集 一般化
  • 20. 域对象域对象可以代表业务领域中的人、地点、事物或概念。域对象分为以下几种: 实体域对象:业务领域的名词 过程域对象:业务领域的动词 事件域对象:业务领域中的事件
  • 21. 实体域对象实体对象可以代表人、地点、事物或概念。例如客户、订单、商品等作为实体域对象。 在Java EE应用中,这些名词可以作为实体EJB。 对于普通的Java应用,这些名词可以作为包含状态和行为的JavaBean。采用JavaBean形式的实体域对象也称为POJO(Plain Old Java Object)。 为了使实体域对象与关系数据库表中记录对应,可以为每个实体域对象分配惟一的OID(Object Identifier,即对象标识符),OID是关系数据库表中的主键(通常为代理主键)在实体域对象中的等价物。
  • 22. 过程域对象过程域对象代表应用中的业务逻辑或流程。它们通常依赖于实体域对象。 可以把业务领域中的动词,例如客户发出订单、登入应用等作为过程域对象。 在Java EE应用中,它们通常作为会话EJB或者消息驱动EJB。 在非Java EE应用中,它们可作为常规的JavaBean,具有管理和控制应用的行为。 过程域对象也可以拥有状态,例如在J2EE应用中,会话EJB可分为有状态和无状态两种类型。
  • 23. 事件域对象事件域对象代表应用中的一些事件(如异常、警告或超时)。这些事件通常由系统中的某种行为触发。 例如在多用户环境中,当一个客户端程序更新了某种实时数据,服务器端程序会创建一个事件域对象,其他正在浏览相同数据的客户端程序能够接受到这一事件域对象,随即同步刷新客户界面。
  • 24. 域对象之间的关系关联(Association) 依赖(Dependency) 聚集(Aggregation) 一般化(Generalization)
  • 25. 关联关系private Customer customer; public Customer getCustomer(); public void setCustomer(Customer c);private Customer customer; public Customer getCustomer(); public void setCustomer(Customer c);private Set orders; public Set getOrders(); public void setOrders(Set o);private Set orders; public Set getOrders(); public void setOrders(Set o);
  • 26. 依赖关系在BusinessService类中访问Customer类的方法,并且构造Customer类的实例
  • 27. 聚集关系聚集指的是整体与部分之间的关系,在实体域对象之间很常见。
  • 28. 一般化关系一般化指的是类之间的继承关系。
  • 29. 域对象的持久化概念
  • 30. 域对象的持久化概念狭义的理解,“持久化”仅仅指把域对象永久保存到数据库中 广义的理解,“持久化”包括和数据库相关的各种操作: 保存:把域对象永久保存到数据库中。 更新:更新数据库中域对象的状态。 删除:从数据库中删除一个域对象。 加载:根据特定的OID,把一个域对象从数据库加载到内存中。 查询:根据特定的查询条件,把符合查询条件的一个或多个域对象从数据库加载到内存中。
  • 31. 通过JDBC API来持久化实体域对象 Java应用访问数据库的最直接的方式就是直接访问JDBC API,JDBC是Java Database Connectivity的缩写。 java.sql包提供了JDBC API。在java.sql包中常用的接口和类包括: DriverManager:驱动程序管理器,负责创建数据库连接。 Connection:代表数据库连接。 Statement:负责执行SQL语句。 PreparedStatement:负责执行SQL语句,具有预定义SQL语句的功能。 ResultSet:代表SQL查询语句的查询结果集。
  • 32. JDBC驱动程序Java应用必须通过JDBC驱动程序来和特定的数据库系统连接。 JDBC驱动程序由数据库厂商或第三方提供。
  • 33. JDBC API
  • 34. 负责持久化Customer对象的BusinessServicesaveCustomer():把Customer域对象永久保存到数据库中。 updateCustomer():更新数据库中Customer域对象的状态。 deleteCustomer():从数据库中删除一个Customer域对象。 loadCustomer():根据特定的OID,把一个Customer域对象从数据库加载到内存中。 findCustomerByName():根据特定的客户姓名,把符合查询条件的Customer域对象从数据库加载到内存中。 本范例位于sourcecode/01目录下
  • 35. 业务逻辑代码与数据访问代码耦合的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();
  • 36. 业务逻辑代码与数据访问代码耦合的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();
  • 37. JDBC编程的缺点实现业务逻辑的代码和数据库访问代码掺杂在一起,使程序结构不清晰,可读性差。 在程序代码中嵌入面向关系的SQL语句,使开发人员不能完全运用面向对象的思维来编写程序。 业务逻辑和关系数据模型绑定,如果关系数据模型发生变化,例如修改了CUSTOMERS表的结构,那么必须手工修改程序代码中所有相关的SQL语句,这增加了维护软件的难度。 如果程序代码中的SQL语句包含语法错误,在编译时不能检查这种错误,只有在运行时才能发现这种错误,这增加了调试程序的难度。
  • 38. 数据访问模式业务逻辑和数据访问耦合 ORM模式:在单个组件中负责所有实体域对象的持久化,封装数据访问细节。 主动域对象模式:由实体域对象本身负责管理自己的持久化 JDO模式: SUN公司制定的描述对象持久化语义的标准API CMP模式:由容器负责管理持久化
  • 39. ORM模式
  • 40. 对象-关系映射(Object-Relation Mapping)的概念 ORM解决的主要问题就是对象-关系的映射。域模型和关系模型都分别建立在概念模型的基础上。域模型是面向对象的,而关系数据模型是面向关系的. 一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录。 域模型与关系模型之间存在许多不匹配之处。
  • 41. 域模型与关系模型之间存在许多不匹配之处域模型中有继承关系,关系模型不能直接表示继承关系 域模型中有多对多关联关系,关系模型通过连接表来表示多对多关联关系 域模型中有双向关联关系,关系模型只有单向参照关系,而且总是many方参照one方。 域模型提倡精粒度模型,而关系模型提倡粗粒度模型 Category类Item类
  • 42. 域模型与关系模型之间的不匹配举例如果类的粒度比较大,不利于代码的可重用.Customer类homeProvince homeCity homeStreet homeZipcode comProvice comCity comStreet comZipcodeEmployee类homeProvince homeCity homeStreet homeZipcode comProvice comCity comStreet comZipcode增加Room信息Customer类… homeRoom comRoomEmployee类… homeRoom comRoom
  • 43. 域模型与关系模型之间的不匹配举例精粒度域模型和粗粒度关系模型 private Address homeAddress; private Address comAddress;
  • 44. 作者简介孙卫琴,知名IT作家,Java系列畅销书的作者。1997年毕业于上海交通大学,随后从事基于Java的软件开发工作,还从事Java方面的培训和咨询工作。2002年开始Java技术领域的创作,其作品深受读者欢迎。代表著作有 : <<精通Hibernate:Java对象持久化技术详解第2版>> 2010 <> 2009 <> 2007 <> 2006 <<精通Hibernate: Java对象持久化技术详解>> 2005 <<精通Struts: 基于MVC的Java Web设计与开发>> 2004 <> 2004 <> 2002