1、Hibernate 5教程,Hello Hibernate,什么是 Hibernate ?,一个框架 一个 Java 领域的持久化框架 一个 ORM 框架,对象的持久化,狭义的理解,“持久化”仅仅指把对象永久保存到数据库中 广义的理解,“持久化”包括和数据库相关的各种操作: 保存:把对象永久保存到数据库中。 更新:更新数据库中对象(记录)的状态。 删除:从数据库中删除一个对象。 查询:根据特定的查询条件,把符合查询条件的一个或多个对象从数据库加载到内存中。 加载:根据特定的OID,把一个对象从数据库加载到内存中。,为了在系统中能够找到所需对象,需要为每一个对象分配一个唯一的标识号。在关系数据库
2、中称之为主键,而在对象术语中,则叫做对象标识(Object identifier-OID).,ORM,ORM(Object/Relation Mapping): 对象/关系映射 ORM 主要解决对象-关系的映射ORM的思想:将关系数据库中表中的记录映射成为对象,以对象的形式展现,程序员可以把对数据库的操作转化为对对象的操作。 ORM 采用元数据来描述对象-关系映射细节, 元数据通常采用 XML 格式, 并且存放在专门的对象-关系映射文件中.,ORM,流行的ORM框架,Hibernate: 非常优秀、成熟的 ORM 框架。 完成对象的持久化操作 Hibernate 允许开发者采用面向对象的方式来
3、操作关系数据库。 消除那些针对特定数据库厂商的 SQL 代码 MyBatis: 相比 Hibernate 灵活高,运行速度快 开发速度慢,不支持纯粹的面向对象操作,需熟悉sql语句,并且熟练使用sql语句优化功能 TopLink OJB,Hibernate与Jdbc代码对比,Hibernate 实现,JDBC 实现,Eclipse安装 hibernate 插件,安装方法说明: URL:http:/hibernate.org/tools/,Eclipse安装 hibernate 插件,从页面上可以看到,工具分为两种,一种是完整版本的Eclipse插件(左),一种是只支持Jboss社区版的Ecli
4、pse插件(只有插件)(右),我们下载右边的,它已经足够使用了。点击Download:,Eclipse安装 hibernate 插件,JBoss已经告诉我们下载插件的地址了: URL:http:/download.jboss.org/jbosstools/neon/stable/updates/,Eclipse安装 hibernate 插件,点击Help Install New Software.,Eclipse安装 hibernate 插件,点击Add.,Eclipse安装 hibernate 插件,在Add Site对话框中, 输入name的值为Jboss Tools,location的值
5、为http:/download.jboss.org/jbosstools/neon/stable/updates/ 点击OK按钮,Eclipse安装 hibernate 插件,耐心等待,直到出现提示,选择所有与Hibernate有关的,其余不装。去掉Contact all update sites during install to find required software.上面的勾(一定要去掉,否则安装会很慢),点击next,Eclipse安装 hibernate 插件,Eclipse安装 hibernate 插件,点击accept所在的单选按钮,接受协议,点击next,Eclipse安
6、装 hibernate 插件,等待安装结束,Eclipse安装 hibernate 插件,弹出提示信息,点击OK,Eclipse安装 hibernate 插件,提示我们Eclipse需要重启以完成安装,点击OK,Eclipse安装 hibernate 插件,判断安装是否成功的标准是如果Eclipse的new选项里面有Hibernate配置文件的相关选项,就说明安装是成功的。,准备 Hibernate 环境,导入 Hibernate 必须的 jar 包:加入数据库驱动的 jar 包:,Hibernate开发步骤,2. 创建持久化类,3. 创建对象-关系映射文件,4. 通过 Hibernate A
7、PI 编写访问数据库的代码,1. 创建 Hibernate 配置文件,1. 创建持久化 Java 类,提供一个无参的构造器:使Hibernate可以使用Constructor.newInstance() 来实例化持久化类 提供一个标识属性(identifier property): 通常映射为数据库表的主键字段. 如果没有该属性,一些功能将不起作用,如:Session.saveOrUpdate() 为类的持久化类字段声明访问方法(get/set): Hibernate对JavaBeans 风格的属性实行持久化。 使用非 final 类: 在运行时生成代理是 Hibernate 的一个重要的功能
8、. 如果持久化类没有实现任何接口, Hibnernate 使用 CGLIB 生成代理. 如果使用的是 final 类, 则无法生成 CGLIB 代理. 重写 eqauls 和 hashCode 方法: 如果需要把持久化类的实例放到 Set 中(当需要进行关联映射时), 则应该重写这两个方法,1. 创建持久化 Java 类,Hibernate 不要求持久化类继承任何父类或实现接口,这可以保证代码不被污染。这就是Hibernate被称为低侵入式设计的原因,2. 创建对象-关系映射文件,Hibernate 采用 XML 格式的文件来指定对象和关系数据之间的映射. 在运行时 Hibernate 将根据
9、这个映射文件来生成各种 SQL 语句 映射文件的扩展名为 .hbm.xml,指定类和表的映射,指定持久化类的OID 和表的主键的映射,映射类的属性和表的字段,指定对象标识符生成器, 负责为 OID 生成唯一标识符,3. 创建 Hibernate 配置文件,Hibernate 从其配置文件中读取和数据库连接的有关信息, 这个文件应该位于应用的 classpath 下.,指定连接数据库的基本属性信息,指定数据库所使用的 SQL 方言,指定程序运行时是否在控制台输出 SQL 语句,指定程序运行时是否在数据库自动生成数据表,指定程序需要关联的映射文件,指定是否对输出 SQL 语句进行格式化,4. 通过
10、Hibernate API编写访问数据库的代码,测试代码(Hibernate 5.2.5),/1. 创建一个 SessionFactory 对象 StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure(“hibernate.cfg.xml“).build(); Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder().build(); SessionFactoryBuild
11、er sessionFactoryBuilder = metadata.getSessionFactoryBuilder(); SessionFactory sessionFactory = sessionFactoryBuilder.build(); /2. 创建一个 Session 对象 Session session = sessionFactory.openSession(); /3. 开启事务 Transaction transaction = session.beginTransaction(); /4. 执行保存操作 News news = new News(“Java12345
12、“, “ATGUIGU“, new Date(new java.util.Date().getTime(); session.save(news); /5. 提交事务 mit(); /6. 关闭 Session session.close(); /7. 关闭 SessionFactory 对象 sessionFactory.close();,4. 通过Hibernate API编写访问数据库的代码,运行效果:控制台打印输出SQL语句,4. 通过Hibernate API编写访问数据库的代码,运行效果:数据库增加一张表,表中插入一条字段,Helloworld,使用 Hibernate 进行数据持
13、久化操作,通常有如下步骤: 编写持久化类: POJO + 映射文件 获取 Configuration 对象 获取 SessionFactory 对象 获取 Session,打开事务 用面向对象的方式操作数据库 关闭事务,关闭 Session,Configuration 类,Configuration 类负责管理 Hibernate 的配置信息。包括如下内容: Hibernate 运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数据库Dialect,数据库连接池等(对应 hibernate.cfg.xml 文件)。 持久化类与数据表的映射关系(*.hbm.xml 文件) 创建 Co
14、nfiguration 的两种方式 属性文件(hibernate.properties): Configuration cfg = new Configuration(); Xml文件(hibernate.cfg.xml) Configuration cfg = new Configuration().configure(); Configuration 的 configure 方法还支持带参数的访问: File file = new File(“simpleit.xml”); Configuration cfg = new Configuration().configure(file);,S
15、essionFactory 接口,针对单个数据库映射关系经过编译后的内存镜像,是线程安全的。 SessionFactory 对象一旦构造完毕,即被赋予特定的配置信息 SessionFactory是生成Session的工厂 构造 SessionFactory 很消耗资源,一般情况下一个应用中只初始化一个 SessionFactory 对象。 Hibernate5 使用StandardServiceRegistry来获取SessionFactory Hibernate5 中创建 SessionFactory 的步骤,Session 接口,Session 是应用程序与数据库之间交互操作的一个单线程对
16、象,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。此对象的生命周期很短。Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久层操作的数据都缓存在 session 对象处。相当于 JDBC 中的 Connection。,Session 接口,持久化类与 Session 关联起来后就具有了持久化的能力。 Session 类的方法: 取得持久化对象的方法: get() load() 持久化对象都得保存,更新和删除:save(),update(),saveOrUpdate(),delete() 开启事务: beginTra
17、nsaction(). 管理 Session 的方法:isOpen(),flush(), clear(), evict(), close()等,Transaction(事务),代表一次原子操作,它具有数据库事务的概念。所有持久层都应该在事务管理下进行,即使是只读操作。 Transaction tx = session.beginTransaction(); 常用方法: commit():提交相关联的session实例 rollback():撤销事务操作 wasCommitted():检查事务是否提交,Hibernate 配置文件的两个配置项,hbm2ddl.auto:该属性可帮助程序员实现正向
18、工程, 即由 java 代码生成数据库脚本, 进而生成具体的表结构. 。取值 create | update | create-drop | validate create : 会根据 .hbm.xml 文件来生成数据表, 但是每次运行都会删除上一次的表 ,重新生成表, 哪怕二次没有任何改变 create-drop : 会根据 .hbm.xml 文件生成表,但是SessionFactory一关闭, 表就自动删除 update : 最常用的属性值,也会根据 .hbm.xml 文件生成表, 但若 .hbm.xml 文件和数据库中对应的数据表的表结构不同, Hiberante 将更新数据表结构,但不
19、会删除已有的行和列 validate : 会和数据库中的表进行比较, 若 .hbm.xml 文件中的列在数据表中不存在,则抛出异常 format_sql:是否将 SQL 转化为格式良好的 SQL . 取值 true | false,通过 Session 操纵对象,Session 概述,Session 接口是 Hibernate 向应用程序提供的操纵数据库的最主要的接口, 它提供了基本的保存, 更新, 删除和加载 Java 对象的方法. Session 具有一个缓存, 位于缓存中的对象称为持久化对象, 它和数据库中的相关记录对应. Session 能够在某些时间点, 按照缓存中对象的变化来执行相
20、关的 SQL 语句, 来同步更新数据库, 这一过程被称为刷新缓存(flush) 站在持久化的角度, Hibernate 把对象分为 4 种状态: 持久化状态, 临时状态, 游离状态, 删除状态. Session 的特定方法能使对象从一个状态转换到另一个状态.,Session 缓存,在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存. 只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期 Session 缓存可减少 Hibernate 应用程序访问数据库的频率。,会向数据库发送几条 S
21、QL ?,News 对象,引用变量 news,引用变量 new2,Session 缓存,操作 Session 缓存,Session 缓存,数据库,News 对象,news 记录,flush(),News 对象,Session 缓存,Session 缓存,clear(),reflesh(),flush 缓存,flush:Session 按照缓存中对象的属性变化来同步更新数据库 默认情况下 Session 在以下时间点刷新缓存: 显式调用 Session 的 flush() 方法 当应用程序调用 Transaction 的 commit()方法的时, 该方法先 flush ,然后在向数据库提交事务
22、 当应用程序执行一些查询(HQL, Criteria)操作时,如果缓存中持久化对象的属性已经发生了变化,会先 flush 缓存,以保证查询结果能够反映持久化对象的最新状态 flush 缓存的例外情况: 如果对象使用 native 生成器生成 OID, 那么当调用 Session 的 save() 方法保存对象时, 会立即执行向数据库插入该实体的 insert 语句. commit() 和 flush() 方法的区别:flush 执行一系列 sql 语句,但不提交事务;commit 方法先调用flush() 方法,然后提交事务. 意味着提交事务意味着对数据库操作永久保存下来。,Hibernate
23、 主键生成策略,设定刷新缓存的时间点,若希望改变 flush 的默认时间点, 可以通过 Session 的 setFlushMode() 方法显式设定 flush 的时间点,数据库的隔离级别,对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题: 脏读: 对于两个事物 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段. 之后, 若 T2 回滚, T1读取的内容就是临时且无效的. 不可重复读: 对于两个事物 T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同
24、了. 幻读: 对于两个事物 T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行. 数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题. 一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱,数据库的隔离级别,数据库提供的 4 种事务隔离级别:Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE. O
25、racle 默认的事务隔离级别为: READ COMMITED Mysql 支持 4 种事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ,在 MySql 中设置隔离级别,每启动一个 Mysql 程序, 就会获得一个单独的数据库连接. 每个数据库连接都有一个全局变量 tx_isolation, 表示当前的事务隔离级别. MySQL 默认的隔离级别为 Repeatable Read 查看当前的隔离级别: SELECT tx_isolation; 设置当前 MySQL 连接的隔离级别: set transaction isolation level read com
26、mitted; 设置数据库系统的全局的隔离级别:set global transaction isolation level read committed;,在Hibernate中设置隔离级别,JDBC 数据库连接使用数据库系统默认的隔离级别. 在 Hibernate 的配置文件中可以显式的设置隔离级别. 每一个隔离级别都对应一个整数: 1. READ UNCOMMITED 2. READ COMMITED 4. REPEATABLE READ 8. SERIALIZEABLE Hibernate 通过为 Hibernate 映射文件指定 hibernate.connection.isolat
27、ion 属性来设置事务的隔离级别,持久化对象的状态,站在持久化的角度, Hibernate 把对象分为 4 种状态: 持久化状态, 临时状态, 游离状态, 删除状态. Session 的特定方法能使对象从一个状态转换到另一个状态.,持久化对象的状态,临时对象(Transient): 在使用代理主键的情况下, OID 通常为 null 不处于 Session 的缓存中 在数据库中没有对应的记录 持久化对象(也叫”托管”)(Persist): OID 不为 null 位于 Session 缓存中 若在数据库中已经有和其对应的记录, 持久化对象和数据库中的相关记录对应 Session 在 flush
28、 缓存时, 会根据持久化对象的属性变化, 来同步更新数据库 在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象,持久化对象的状态,删除对象(Removed) 在数据库中没有和其 OID 对应的记录 不再处于 Session 缓存中 一般情况下, 应用程序不该再使用被删除的对象 游离对象(也叫”脱管”) (Detached): OID 不为 null 不再处于 Session 缓存中 一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录,对象的状态转换图,是否在 Session 缓存中 在数据表中是否有对应的记录,Sessi
29、on 的 save() 方法,Session的save()方法使一个临时对象转变为持久化对象 Session的save() 方法完成以下操作: 把News对象加入到 Session 缓存中, 使它进入持久化状态 选用映射文件指定的标识符生成器, 为持久化对象分配唯一的 OID. 在使用代理主键的情况下, setId()方法为对象设置OID是无效的.执行save()方法之前,修改对象id的操作是无效的。 计划执行一条insert语句:在flush缓存的时候 Hibernate通过持久化对象的OID来维持它和数据库相关记录的对应关系. 当News对象处于持久化状态时,不允许程序随意修改它的ID p
30、ersist()和save()区别: 当对一个OID不为Null的对象执行save()方法时,会把该对象以一个新的oid保存到数据库中;但执行persist()方法时会抛出一个异常.,Session 的 save() 方法,Session的get()和load()方法,都可以根据跟定的 OID 从数据库中加载一个持久化对象 区别: 当数据库中不存在与 OID 对应的记录时Session没有关闭且同时需要使用对象时, load() 方法抛出 ObjectNotFoundException 异常, 而 get() 方法返回 null 两者采用不同的延迟检索策略:load 方法支持延迟加载策略(返回
31、的是代理对象)。而 get 不支持。 load方法存在懒加载异常问题:由于load使用的是延迟加载策略,返回的是代理对象。在使用对象之前提前关闭了session会发生懒加载异常。get方法不存在这个问题。,Session的get()和load()方法,load()方法:懒加载异常,发生异常的原因:在需要初始化代理对象之前已经关闭了 Session,load方法返回的是代理对象,Session 的 update() 方法,Session 的 update() 方法使一个游离对象转变为持久化对象, 并且计划执行一条 update 语句. 若希望 Session 仅当修改了 News 对象的属性时,
32、 才执行 update() 语句, 可以把映射文件中 元素的 select-before-update 设为 true. 该属性的默认值为 false 当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常 当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常.,Session 的 update() 方法,需要注意的: 1. 无论要更新的游离对象和数据表的记录是否一致, 都会发送 UPDATE 语句.(如果为更新操作设置了触发器则盲目发送的update语句会使得触发器被错误的执行
33、多次) 如果想让 update 方法不再盲目的出发 update 语句,需要在 .hbm.xml 文件的 class 节点设置select-before-update=true (默认为 false). 但通常不需要设置该属性. 2. 若数据表中没有对应的记录, 但还调用了 update 方法, 会抛出异常 3. 当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常. 因为在 Session 缓存中不能有两个 OID 相同的对象!,设置select-before-update=true后的显示效果,OID不存在时执行u
34、pdate()方法的异常,Session 的 saveOrUpdate() 方法,Session 的 saveOrUpdate() 方法,Session 的 saveOrUpdate() 方法同时包含了 save() 与 update() 方法的功能,News 对象,游离对象,临时对象,update(),save(),判定对象为临时对象的标准 Java 对象的 OID 为 null 映射文件中为 设置了 unsaved-value 属性, 并且 Java 对象的 OID 取值与这个 unsaved-value 属性值匹配,Session 的 saveOrUpdate() 方法,注意: 若 OI
35、D 不为 null, 但数据表中还没有和其对应的记录. 会抛出一个异常.2. 了解: OID 值等于 id 的 unsaved-value 属性值的对象, 也被认为是一个游离对象,Session 的 merge() 方法,Session 的 merge() 方法,news1 的状态,Session缓存中 是否存在OID为1的News 持久化对象,数据库中是否存 在id为1的记录,从数据库加载id为1的News持久化对象,把new1对象的属性拷贝到New持久化对象中,计划执行一条update语句,游离对象,存在,不存在,创建一个新的News对象,把new1对象的属性拷贝到新建的News对象中,持
36、久化这个News对象,计划执行一条insert语句,返回News持久化对象的引用,存在,临时对象,不存在,Session 的 delete() 方法,Session 的 delete() 方法既可以删除一个游离对象, 也可以删除一个持久化对象 Session 的 delete() 方法处理过程 计划执行一条 delete 语句 把对象从 Session 缓存中删除, 该对象进入删除状态. Hibernate 的 cfg.xml 配置文件中有一个 hibernate.use_identifier_rollback 属性, 其默认值为 false, 若把它设为 true, 将改变 delete()
37、 方法的运行行为: delete() 方法会把持久化对象或游离对象的 OID 设置为 null, 使它们变为临时对象,Session 的 delete() 方法,Session 的 delete() 方法,若OID在数据表中没有记录则抛出异常,Session 的 evict() 方法,从 session 缓存中把指定的持久化对象移除,对象从持久化状态变为脱管状态。,通过 Hibernate 调用存储过程,Work 接口: 直接通过 JDBC API 来访问数据库的操作,通过 Hibernate 调用存储过程,Session 的 doWork(Work) 方法用于执行 Work 对象指定的操作,
38、 即调用 Work 对象的 execute() 方法. Session 会把当前使用的数据库连接传递给 execute() 方法.,Hibernate 与触发器协同工作,Hibernate 与数据库中的触发器协同工作时, 会造成两类问题 触发器使Session的缓存中的持久化对象与数据库中对应的数据不一致:触发器运行在数据库中,它执行的操作对Session是透明的 Session的update()方法盲目地激发触发器: 无论游离对象的属性是否发生变化, 都会执行update语句,而update语句会激发数据库中相应的触发器 解决方案: 在执行完Session的相关操作后, 立即调用Sessio
39、n的flush()和refresh() 方法, 迫使Session 的缓存与数据库同步(refresh() 方法重新从数据库中加载对象)在映射文件的的 元素中设置 select-before-update 属性: 当 Session 的 update 或 saveOrUpdate() 方法更新一个游离对象时, 会先执行 Select 语句, 获得当前游离对象在数据库中的最新数据, 只有在不一致的情况下才会执行 update 语句,内存,数据库,News 对象,news 记录,flush(),reflesh(),Hibernate 的配置文件,Hibernate配置文件概述,Hibernate
40、配置文件主要用于配置数据库连接和 Hibernate 运行时所需的各种属性 每个 Hibernate 配置文件对应一个 Configuration 对象 Hibernate配置文件可以有两种格式: hibernate.properties hibernate.cfg.xml,JDBC 连接属性,JDBC 连接属性 connection.url:数据库URL connection.username:数据库用户名 connection.password:数据库用户密码 connection.driver_class:数据库JDBC驱动 dialect:配置数据库的方言,根据底层的数据库不同产生不同
41、的 sql 语句,Hibernate 会针对数据库的特性在访问时进行优化,导入C3P0 jar包,导入C3P0 jar包 位置:hibernate-release-5.2.5.Finalliboptionalc3p0*.jar,C3P0 数据库连接池属性,C3P0 数据库连接池属性 hibernate.c3p0.max_size: 数据库连接池的最大连接数 hibernate.c3p0.min_size: 数据库连接池的最小连接数 hibernate.c3p0.timeout: 数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁 hibernate.c3p0.max_statement
42、s: 缓存 Statement 对象的数量 hibernate.c3p0.idle_test_period: 表示连接池检测线程多长时间检测一次池内的所有链接对象是否超时. 连接池本身不会把自己从连接池中移除,而是专门有一个线程按照一定的时间间隔来做这件事,这个线程通过比较连接对象最后一次被使用时间和当前时间的时间差来和 timeout 做对比,进而决定是否销毁这个连接对象。 hibernate.c3p0.acquire_increment: 当数据库连接池中的连接耗尽时, 同一时刻获取多少个数据库连接,hibernate.cfg.xml的常用属性,其他 show_sql:是否将运行期生成的S
43、QL输出到日志以供调试。取值 true | false format_sql:是否将 SQL 转化为格式良好的 SQL . 取值 true | false hbm2ddl.auto:在启动和停止时自动地创建,更新或删除数据库模式。取值 create | update | create-drop | validate hibernate.jdbc.fetch_size hibernate.jdbc.batch_size,jdbc.fetch_size 和 jdbc.batch_size,hibernate.jdbc.fetch_size:实质是调用 Statement.setFetchSize(
44、) 方法设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数。 例如一次查询1万条记录,对于Oracle的JDBC驱动来说,是不会 1 次性把1万条取出来的,而只会取出 fetchSize 条数,当结果集遍历完了这些记录以后,再去数据库取 fetchSize 条数据。因此大大节省了无谓的内存消耗。Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。Oracle数据库的JDBC驱动默认的Fetch Size = 10,是一个保守的设定,根据测试,当Fetch Size=50时,性能会提升1倍之多,当 f
45、etchSize=100,性能还能继续提升20%,Fetch Size继续增大,性能提升的就不显著了。并不是所有的数据库都支持Fetch Size特性,例如MySQL就不支持 hibernate.jdbc.batch_size:设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,类似于设置缓冲区大小的意思。batchSize 越大,批量操作时向数据库发送sql的次数越少,速度就越快。 测试结果是当Batch Size=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,Batch Size = 50的时候,删除仅仅需要5秒!Oracle数据库 batchSi
46、ze=30 的时候比较合适。,对象关系映射文件,POJO 类和数据库的映射文件*.hbm.xml,POJO 类和关系数据库之间的映射可以用一个XML文档来定义。 通过 POJO 类的数据库映射文件,Hibernate可以理解持久化类和数据表之间的对应关系,也可以理解持久化类属性与数据库表列之间的对应关系 在运行时 Hibernate 将根据这个映射文件来生成各种 SQL 语句 映射文件的扩展名为 .hbm.xml,Hiberrnate-mapping,映射文件说明,hibernate-mapping 类层次:class 主键:id 基本类型:property 实体引用类: many-to-on
47、e | one-to-one 集合:set | list | map | array one-to-many many-to-many 子类:subclass | joined-subclass 其它:component | any 等 查询语句:query(用来放置查询语句,便于对数据库查询的统一管理和优化) 每个Hibernate-mapping中可以同时定义多个类. 但更推荐为每个类都创建一个单独的映射文件,hibernate-mapping,hibernate-mapping 是 hibernate 映射文件的根元素 schema: 指定所映射的数据库schema的名称。若指定该属性,
48、 则表明会自动添加该 schema 前缀 catalog:指定所映射的数据库catalog的名称。 default-cascade(默认为 none): 设置hibernate默认的级联风格. 若配置 Java 属性, 集合映射时没有指定 cascade 属性, 则 Hibernate 将采用此处指定的级联风格. default-access (默认为 property): 指定 Hibernate 的默认的属性访问策略。默认值为 property, 即使用 getter, setter 方法来访问属性. 若指定 access, 则 Hibernate 会忽略 getter/setter 方法
49、, 而通过反射访问成员变量. default-lazy(默认为 true): 设置 Hibernat morning的延迟加载策略. 该属性的默认值为 true, 即启用延迟加载策略. 若配置 Java 属性映射, 集合映射时没有指定 lazy 属性, 则 Hibernate 将采用此处指定的延迟加载策略 auto-import (默认为 true): 指定是否可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。 package (可选): 指定一个包前缀,如果在映射文档中没有指定全限定的类名, 就使用这个作为包名。,详细取值参看:http:/ 元素用于指定类和表的映射 name:指
50、定该持久化类映射的持久化类的类名 table:指定该持久化类映射的表名, Hibernate 默认以持久化类的类名作为表名 dynamic-insert: 若设置为 true, 表示当保存一个对象时, 会动态生成 insert 语句, insert 语句中仅包含所有取值不为 null 的字段. 默认值为 false dynamic-update: 若设置为 true, 表示当更新一个对象时, 会动态生成 update 语句, update 语句中仅包含所有取值需要更新的字段. 默认值为 false select-before-update:设置 Hibernate 在更新某个持久化对象之前是否需要先执行一次查询. 默认值为 false batch-size:指定根据 OID 来抓取实例时每批抓取的实例数. lazy: 指定是否使用延迟加载. mutable: 若设置为 true, 等价于所有的 元素的 update 属性为 false, 表示整个实例不能被更新. 默认为 true. discriminator-value: 指定区分不同子类的值. 当使用 元素来定义持久化类的继承关系时需要使用该属性,