hibernate in action 笔记

第一章 耦合与解耦合

1.目标

   应用逻辑和数据访问相分离:sql语句和业务分离

   数据库变化,不需要修改业务逻辑

2.DAO模式

   dataaccsessor:封装对数据库的访问

   activedomain object: 对象bean,被业务逻辑调用

   objectbean ——data accessor——数据表

3.持久层设计和资源管理模式

   连接池:数据库连接,如DBCPproxool

   decorator模式

   statementpool:缓存statement,一般情况statement是在connection创建后得到,当connection关闭,则statement对象也释放,但如果使用连接池,则需要对statement也缓存。

4.持久层设计和ORM

   iBatis:可控制更多的数据库细节

   hibernate:对持久层进行彻底封装,从而将底层细节与上层架构完全分离

第二章 hibernate

1.优点

   lazy-loading  新的事件处理模型   uncheckedhibernateException

2.日志配置

   logger.propertieslog4j.net.sf.hibernate=error定义级别

3.操作流程

   1)初始化配置管理类Configuration

   2)创建sessionFactory

   3)通过sessionFactory得到session   

   4)使用session.save()session.flush()完成数据保存

第三章hibernate基础

1.一个应用针对一个数据库共享一个SessionFactory实例。一个session只能由一个线程调用

2.CRUD的实现

    插入:session.save(obj)

   更新、删除 Queryquery=session.createQuery(hql)   query.executeUpdate()

4.OR映射

   hibernate有丰富的类型(CLOB BLOB   currency),也可自定义类型

   实体映射:主键映射(建议主键和业务逻辑无关)

         <idname="类中id" column="数据表的id"type=""  generator class="native 主键生成方式"/>   classnativehibernate决定),assigned(应用逻辑产生的),identity(数据库提供的主键生成机制),uuid.hexhibernate产生的唯一的16进制数,如逻辑允许则采用),foreign(外部表字段)

         映射类实现seriable接口,且不使用final修饰,无参数构造函数

5.自定义数据类型

   基于设计上的考虑,如List<File>到数据表String如何自动转换  

6.复合主键映射

   复合主键的引入,在很大程度上标明业务逻辑已经入侵数据库存储逻辑,在新系统中应该避免,通过composite-id定义

7.blog  clob字段映射

   blob用于存储二进制、clob存储大量文本数据

   此两种格式,不同的数据库有不同的映射,可使用自定义数据类型封装这些差异

8.实体映射策略

   1)实体粒度设计

       对于数据库中一个复杂表,在hbm.xml中使用component将其转换为多个对象,这些对象间是包含、组成关系

   2)性能粒度设计

       对于clobblob字段,使用hibernate的延迟加载功能,则只有在调用getImagegetText才加载

   3)实体层次设计

       java的继承类在数据库中如何表示

       方案1:tableper subclass。有一个基类表,每个子类也有表。如基类表TItem,子类表Tbook的外键是TItem的主键。适合子类的扩展。

       方案2tableper class hierachy.  所有类在一张表中,好处是查询效率高,坏处是扩展需修改原有表,并且子类种类太多,表字段会很庞大。

9.数据关联

   一对一(主键相同),如公民user和护照passport使用同一主键,user使用Oneto one 配置,passport使用oneto one foreign

   一对多(外键约束),使用<many-to-one>,多在1类中常为collection类型,如一个用户有多个地址

   双向一对多:在user中配置一对多,在address中配置多对一,好处是保存对象时只执行一个SQL语句,映射到类中时address类包含一个User对象。

   多对多:在两个java类中都会保存对方,性能不佳,在设计中避免大量使用。可使用延迟加载提高性能

10.数据检索

   1)使用DetachedCriteria,当session失效时,仍可使用,从而实现重用

   2HQL  

       参数动态绑定: ?(顺位占位符)  :变量名(引用占位符,可读性更强)

   3)可在配置文件中制定sql-insert sql-updae  sql-delete方式

   4)可在配置文件中<query>配置hql语句,再通过sessiongetNamedQuery调用hql,例如"foruser inner join fetch user.addresses" 完成useraddress的内连接,其中fetch表示address读出后立即填充到user对象,fetch只对innerjoinleftjoin有效。

11.数据加载

    1)即使加载:立刻加载其关联数据

    2)延迟加载:对集合类型(一对多、多对一、多对多关系中尽量使用延迟加载); 可通过批量提交多个查询条件,一次完成多个数据的读取;可设置<classbatch-size>打开批量加载功能《10

    3)预先加载:可通过一条sql语句完成实体和关联数据的读取,使用outer-join方式实现,对一对多和多对多的collection属性不推荐,而即时读取需要两条。

    4)批量加载:将同类型待加载的hql批量提交,如whereid=1 or id=2

12.对象识别

   1)判断两个对象相等,先调用hascode方法,若相同再调用equals方法

   2)判断两实体对象相等,在hibernate重视会用ID


13.Lifecyclehevalidatable

   当执行CRUD时,捕获并执行相应处理,类似于触发器,可用于对关键信息提供日志记录

14.分页

   query.setFirstResultsetFetchSize实现分页

15.session管理

   filterservlet调用前执行,在servlet调用后结束,所以在filter中管理session很正常

16.数据层功能的扩展

   1)延迟决策:不要实现一个大而全的基类,把功能推迟到子类中实现

   2)子类方法实现不同,属性相同,则引入一标识属性type:hibernatemap中通过subclassdiscriminator-value='value'区分

   3)子类有新的属性,则引入一新表解决,新表只包含这种类型专有的数据,再通过joined-class到基类

   4)在需要时保持冗余,即把joined-class转化为subclass,在业务系统中,一些大表如上10万条数据,每次实现一个子类就要增加一个新表,就会造成过度jon,这会造成数据库无谓的开销

17.优化策略

   1)缓存策略:根据每个表实际情况,指定匹配的缓存模式

   2session管理:实现thread级别的重用

   3)尽量使用延迟加载

   4)合适的batch-size参数

   5)使用UUID作为主键生成器

   6)若可能,选用基于version的乐观锁代替悲观锁

   7)开发中,打开sql日志输出(hibernate_show_sql)

18.开发流程

   1)详细设计+ER

   2)生成java类——》生成ddlhbm.xml文件

   3)容器、session、事务

第四章hibernate可用工具

1.基础代码生成流程

   基础代码包括java类、DDLhbm.xml

   ER工具——》数据库定义——》hbm.xmlMiddleGen)——》java类(hbm2java

   java类——》hbm.xmlxdoclet)——》ddlschemaexporthibernatesynchronizer

   初期使用middlegen根据数据库定义,在重构中使用schemaExport

2. hibernate extension

   hbm2javahbm.xml生成java文件

   class2hbmclass文件生成hbm.xml

   ddl2hbm: ddl生成hbm.xml


    

第五章hibernate的高级特性

1.hibernate持久化实现

   1)对象状态:POVO看是否纳入hibernate管理中

   2)脏数据检查:通过dynamicproxysetter进行拦截,当其被调用,将其标记为待更新; 数据版本对比,当数据提交时,将提交版本与最近读取版本比较

2.数据缓存

   1)缓存策略: 

       事务级缓存:在session生命周期内

      应用级缓存:在多个事务间共享,由sessionFactory实现,所有sessionFactory创建的session实例共享此缓存

       分布式缓存:在多个应用实例、多个JVM间共享缓存模式

   2hibernate中分为事务级和应用级两类。通过id加载数据,延迟加载时起作用

3.事务管理

    指定hibernate.transaction.factory-class属性 有默认值

   默认使用Jdbc实现

   可使用optimistic-lock对表加入乐观锁,表和类有一version字段。乐观锁使用版本控制方式,当A提交修改时版本+1,如av>服务器v,则先修改并更新版本号。

4.持久层操作

   1)数据加载

       load/get都实现通过主键加载对象,优先考虑load

       查询性能 find/iteratorfind无法利用缓存,其对缓存只写不读,而iterator充分利用缓存,对频繁读取比较有利。对于大批量数据通过sql或存储过程实现。

       querycache:解决完全相同的多次查询,满足条件表没有变+sql相同。在hibernate.cfg.xml中打开cache.user_query_cache选项,并query.setCacheable(true)

   2)数据保存

       saveOrUpdate:对参数object判断数据库中id是否存在,否则保存,有则更新

   3)数据批量操作

       批量导入:在JDBC中,对批量导入使用PreparedStatement.executeBatch完成,在hibernate中,设置jdbc.batch_size指定一次提交的sql数量,mysql的批量导入在hibernate不支持,需配合commit和循环指定每次提交的sql数量

       批量删除:bulkdelete/update 无法保证缓存数据的一致有效性,则进行批量更新、删除时,使用迭代比较保险

5. collection

   无序集:set(不允许重复)、bag(允许重复元素,使用idbag解决删除时不能唯一标识的问题)、map(键值对应)

   有序集:list(保持表中数据的顺序,要求表有对应字段保存次序信息)

6.结果集排序——在hbm.xml

   JVM排序,制定sort

   order-by  xml中指定

7.拦截器

   可以实现interceptor接口或继承EmptyInterceptor,实现对insertupdate delete load query之前的处理

8.性能检测

   P6SPY(针对数据库访问操作)

    SQLProfiler 使用图形界面监控:sql语句查询次数、执行时间、优化建议、statement实时刷新信息

第十章IBatis介绍

   iBatis关注ORpojosql间的映射,并不会在运行时自动生成sql,具体的sql由程序员编写,然后通过映射文件将sql所需的参数及返回值映射到POJO,用于解决:

   1)客户只对开发团队提供几条selectsql或存储过程,具体表结构不公开

   2)所有涉及业务逻辑部分的数据库操作由存储过程完成

   3)熊数据量大,性能要求极为苛刻,使用高度优化的sql语句


你可能感兴趣的:(hibernate in action 笔记)