查看“Hibernate笔记 3:核心API”的源代码
←
Hibernate笔记 3:核心API
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Hibernate]] == Configuration 接口 == Configuration 接口的作用是:对 Hibernate 进行配置、并启动 Hibernate 和连接数据库系统。 Configuration 仅仅是作为一个初始化时的对象,一个 Configeration 实例代表 Hibernate 所有 Java 类到 Sql 数据库映射的集合。 在 Hibernate 的启动过程中,Configuration 类的实例首先定位缺省 XML 配置文件(hibernate.cfg.xml),并读取关的配置项目,然后创建出一个 SessionFactory 对象。 使用: # 根据默认的 XML 配置文件:(位置:src/hibernate.cfg.xml) #: <syntaxhighlight lang="Java" highlight=""> Configuration cfg = new Configuration().configure(); </syntaxhighlight> # 根据自定义的 XML 配置文件:(少用) #: <syntaxhighlight lang="Java" highlight=""> Configuration cfg = new Configuration().configure("cn/config/hibernate2.cfg.xml"); </syntaxhighlight> # 加载“映射配置文件”:(如果使用“hibernate.properties”作为核心配置文件,则无法在其中配置“映射配置文件”,需要使用 Configuration 对象加载) #: <syntaxhighlight lang="Java" highlight=""> Configuration cfg = new Configuration().configure(); cfg.addResource("com/eijux/domain/Customer.hbm.xml"); </syntaxhighlight> == SessionFactory 接口 == SessionFactory 接口负责 Hibernate 的初始化和建立 Session 对象。 它在 Hibernate 中起到一个缓冲区作用,Hibernate 可以将自动生成的 SQL 语句、映射数据以及某些可重复利用的的数据放在这个缓冲区中。同时它还保存了对数据库配置的所有映射关系,维护了当前的<span style="color: blue; font-size: 120%">'''二级缓存'''</span>。 SessionFactory 的主要作用是:产生和管理 Session。 根据 Configuration 对象创建一个 SessionFactory 对象: # 在 Hibernate 4 之前: #: <syntaxhighlight lang="Java" highlight=""> Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); </syntaxhighlight> # 在 Hibernate 4 之后:【???】 #: <syntaxhighlight lang="Java" highlight=""> Configuration cfg = new Configuration().configure(); ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry(); SessionFactory sessionFactory = cfg.buildSessionFactory(sr); </syntaxhighlight> SessionFactory 具有以下特点: 1、线程安全,同一个实例能够供多个线程共享。 2、重量级,不能随意的创建和销毁它的实例。 所以,通常情况下每一个应用只需要一个 SessionFactory,当需要操作多个数据库时,可以为每个数据库指定一个 SessionFactory。 即:'''“一个 SessionFactory 实例”对应“一个数据存储源”'''。——【'''重量级,整个应用中共享'''】 因此,在实际项目使用中,通常会抽取一个 '''HibernateUtils''' 的工具类,用于提供 Session 对象: : <syntaxhighlight lang="Java" highlight=""> public class HibernateUtils { private static final Configuration configuration; private static final SessionFactory sessionFactory; Static{ configuration = new Configuration().configure(); sessionFactory = configuration.buildSessionFactory(); } /** * 提供获得 session 的方法: */ public static Session openSession() { return sessionFactory.openSession(); } } </syntaxhighlight> SessionFactory 可以通过两种方法产生 Session。 生成 Sessin: # '''openSession()''':每次打开都是新的 Session,并且需要人为的调用 '''close''' 方法关闭 Session。 #: <syntaxhighlight lang="Java" highlight=""> Session session = sessionFactory.openSession(); </syntaxhighlight> # '''getCurrentSession()''':从当前上下文中获取 Session 并且会绑定到当前线程: #: 第一次调用会自动创建一个 Session 实例,如果未手动关闭多次获取的是同一个 Session,事物提交或者回滚时会'''自动关闭''' Session。 #: <syntaxhighlight lang="Java" highlight=""> Session session = sessionFactory.getCurrentSession(); </syntaxhighlight> #* 需要在配置文件(hibernate.cfg.xml)中添加如下配置:【否则会报错“org.hibernate.HinerbateException: No CurrentSessionContext configured!”】 #*# 如果使用的是'''本地事务'''(JDBC 事务): #*#: <syntaxhighlight lang="xml" highlight=""> <property name="current_session_context_class">thread</property> </syntaxhighlight> #*# 如果使用的是'''全局事务'''(JTA 事务): #*#: <syntaxhighlight lang="xml" highlight=""> <property name="current_session_context_class">jta</property> </syntaxhighlight> '''全局事务''':资源管理器管理和协调的事务,可以跨越多个数据库和进程。资源管理器一般使用 XA 二阶段提交协议与“企业信息系统”(EIS)或数据库进行交互。 '''本地事务''':在单个 EIS 或数据库的本地并且限制在单个进程内的事务。本地事务不涉及多个数据来源。 === 连接池 === SessionFactory 内部还维护了一个连接池,如果需要使用第三方连接池(如:C3PO),则需要手动进行配置。 步骤: # 引入 C3PO 相关 JAR 包: #* c3p0-0.9.2.1.jar #* hibernate-c3p0-5.0.7.Final.jar #* mchange-commons-java-0.2.3.4.jar # 配置 C3PO 连接池(hibernate.cfg.xml 中): #: <syntaxhighlight lang="xml" highlight=""> <!-- 配置C3PO连接池 --> <property name= "connection.provider_c1ass">org.hibernate.connection.C3POConnectionProvider</property> <!-- 连接池中可用数据库连接的最少数目 --> <property name= "c3p0.min_size">5</property> <!-- 连接池中所有数据库连接的最大数目 --> <property name= "c3p0.max_size">20</property> <!-- 数据库连接的过期时间(单位:秒): 如果池中某个连接处于空闲状态的时间超过了 timeout 时间,就会从连接池中消除 --> <property name= "c3p0.timeout">120</property> <!-- 检查连接池中的空闲连接的时间间隔(单位:秒)--> <property name= "c3p0.idle_test_period ">3000</property> </syntaxhighlight> == Session == Session 用于管理一个数据库的任务单元(增、删、改、查),它是 Java 应用和 Hibernate 之间主要运行接口,是抽象持久性服务概念的主要 API。 【类似于 JDBC 中的连接(“connection”)】 Session 对象是'''非线程安全'''的,因此最好是一个线程只创建一个Session对象(将它设计为局部对象)。 ——【'''轻量级,不共享''':“一请求”>>“一线程”>>“一session”>>“一事务”】 === 生命周期 === Session 的生命周期是以一个逻辑事物的开始和结束为边界,Session 的主要功能是提供创建、读取和删除映射的实体类的操作。 实体可能存在于三种状态: # '''瞬时状态'''(transient):实体对象在内存是自由存在的(即为普通的 Java 对象),即:“该实体从未与任何持久化上下文关联过,它没有持久化标识”。 #* 与“Session对象”:无关联; #* 与“数据库记录”:无关联; # '''持久状态'''(persistent):实体对象处于 Hibernate 框架所管理的状态,即:“该实体在数据库中有对应的记录,并拥有一个持久化标识”。 #* 与“Session对象”:有关联; #* 与“数据库记录”:有关联; #* Hibernate 会:依据 persistent 状态的实体对象的属性变化,而改变数据库中相对应的记录; #**在一个 Session 中,对持久对象的改变不会马上对数据库进行变更,而是发生在 Transaction 终止,执行 commit 之后。 # '''游离状态'''(detached):与持久状态的对象关联的 Session 被关闭后,该对象就变成游离状态,即:“游离态是由持久态实体对象转变(关联的 Session 被关闭)而来的”。 #* 与“Session对象”:无关联; #* 与“数据库记录”:无直接关联;(可能有相关数据,但未关联) #* 此状态下对游离对象的引用依然有效,也可以继续被修改; #** 但,对其所做的任何修改将不会影响到到数据库中的数据。 * 三种状态可以互相转换: *: [[File:Hibernate 生命周期图.png|600px]] === Session 缓存 === Session 中有一个缓存,被称为“Hibernate 的<span style="color: blue; font-size: 120%">'''一级缓存'''</span>”。 Session 缓存,用于存放被当前工作单元加载的对象,这块缓存中有一个 '''map'''。 1、在执行 '''save()''' 方法后,会生成一个 '''id'''(<span style="color: blue">'''OID'''</span>),这个 id 会保存在 map 的 '''key''' 中; 2、与之对应的 '''value''' 值就是该是该对象的引用,执行 '''commit()''' 方法后,数据库就有对应这条数据了,此时该实体处于“持久状态”; 3、当执行完 Session.'''close()'''后,处于“游离状态”。 区分实体的三种状态: :{| class="wikitable" ! 实体状态 !! OID !! Session缓存 !! 数据库 |- | 瞬时状态 || null || 不存在 || 无记录 |- | 持久状态 || 非null || 存在 || 有记录 |- | 托管状态 || 非null || 不存在 || (可能)有记录 |} <span style="color: blue; font-size: 150%;">'''OID'''</span>(object identifier),即:“对象标识符”,是 hibernate 用于区分两个对象是否是同一个对象的标识的方法。 OID 在对象持久化之前是 '''null''',持久化的时候 hibernate 或者我们手动指定一个 id('''被插入到数据库当做主键,在 session中 当做索引'''),所以,需要保证 OID 与主键的一致性,比如:类型、长度等。 OID 类型: # '''自然主键''':带有业务含义的主键(比如:学号,工作编号)。 #* 需要手动的指定主键(合成或者拼接);如果不指定主键就提交缓存进行更新,则会报错! #* 主键生成策略: #*# <span style="color: blue">'''assinged'''</span>:Hibernate不维护主键,开发人员需要手动设置主键; # '''代理主键''':通过编码自动生成的,无业务含义的主键。 #* 主键生成策略: #*# <span style="color: blue">'''increment'''</span>:(由 Hibernate 提供的)'''自动增长'''。 #*#* 适用于:short、int、long 类型的主键; #*#* 不适用:与并发访问数据库; #*# <span style="color: blue">'''identity'''</span>:(由数据库提供的)'''自动增长'''。 #*#* 适用于:short、int、long 类型的主键; #*#* 不适用:不支持自动增长的数据库(如:Oracle); #*# <span style="color: blue">'''sequence'''</span>:(由数据库提供的)'''序列'''。 #*#* 适用于:short、int、long 类型的主键; #*#* 适用于:支持序列的方式的数据库(如:Oracle、db2、sap、db、postgresql); #*# <span style="color: blue">'''native'''</span>:本地策略,根据底层的数据库不同,'''自动选择'''使用 identity 还是 sequence。 #*#* 适用于:short、int、long 类型的主键; #*# <span style="color: blue">'''uuid'''</span>:随机字符串。 #*#* 适用于:字符串类型的主键。 Session 缓存是由一系列的 Java 集合构成的: 当一个对象被加入到 Session 缓存中,这个对象的引用就加入到了 Java 的集合中,即使以后应用程序中的引用变量不再引用该对象,只要 Session 缓存不被清空,这个对象一直处于生命周期中。 作用: # 减少访问数据库的频率。 # 保证缓存中的对象与数据库中的相关记录保持同步。 Session 清理缓存的时机: # 提交前:当调用 Transaction 的 commit() 方法时,commit() 方法先清理缓存(前提是:FlushMode.COMMIT/AUTO),然后再向数据库提交事务。 # 查询前:当应用程序调用 Session 的 find() 或者 iterate() 时,如果缓存中的持久化对象的属性发生了变化,就会先清理缓存,以保证查询结果能反映持久化对象的最新状态。 # flush:当应用程序显示调用 Session 的 flush() 方法的时候。 : 如下图: :{| class="wikitable" ! FlashMode !! Session.find()/iterate() !! Session.commit() !! Session.flush() |- | FlashMode.AUTO || ✔ || ✔ || ✔ |- | FlashMode.COMMIT || ✘ || ✔ || ✔ |- | FlashMode.NEVER || ✘ || ✘ || ✔ |} :* 清理(✔),不清理(✘) === 常用方法 === Session 的所有方法,见博客:[https://www.cnblogs.com/lukun/archive/2011/03/31/1968937.html Hibernate session的方法全集] 常见方法: # '''save()''':向数据库中'''保存'''(持久化)实体。 #: 示例: #: <syntaxhighlight lang="Java" highlight=""> session.save(Object); </syntaxhighlight> # '''delete()''':从数据库中'''删除'''实体。 #* 对象删除后,其状态为“Transistent”; #* 对象需要有 ID; #: 示例: #: <syntaxhighlight lang="Java" highlight=""> session.delete(Object); </syntaxhighlight> # '''load()''':从数据库中'''加载'''实体。 #: <syntaxhighlight lang="Java" highlight=""> Session.load(Class arg0, Serializable arg1) throws HibernateException </syntaxhighlight> ## 参数: ##*“arg0”:需要加载对象的类,例如:User.class; ##*“arg1”:查询条件(实现了序列化接口的对象),例如:"4028818a245fdd0301245fdd06380001" 字符串已经实现了序列化接口; ##** 如果是数值类类型,则 hibernate 会自动使用包装类。 ## 返回: ##* 此方法返回类型为 Object,但返回的是“'''代理对象'''”(并非实际可用的对象,因为“延迟加载”)。【第一次使用对象时,session 不能关闭】 ##* 如果数据库中没有相应的记录,则会抛出异常“找不到对象”('''org.hibernate.ObjectNotFoundException''')。【记录不存在时抛出异常】 ## 执行:因为 load 方法实现了“'''延迟加载'''”(懒加载,“lazy load”),所以,只有在使用返回的对象时,它才发出查询 SQL 语句,加载对象。 ##* 其延迟加载实现原理是代理方式。【???】 #: 示例: #: <syntaxhighlight lang="Java" highlight=""> try { session = sf.openSession(); session.beginTransaction(); User user = (User)session.load(User.class,1); // 在使用对象时,才发出查询SQL语句,加载对象 System.out.println("user.name=" + user.getName()); // 此时 user 为 persistent 状态 user.setName("eijux"); session.getTransaction().commit(); } catch (HibernateException e) { e.printStackTrace(); session.getTransaction().rollback(); } finally{ if (session != null){ if (session.isOpen()) session.close(); } </syntaxhighlight> # '''get()''':从数据库中'''加载'''实体。 #: <syntaxhighlight lang="Java" highlight=""> Session.get(Class arg0, Serializable arg1) </syntaxhighlight> ## 参数: ##*“arg0”:需要加载对象的类,例如:User.class; ##*“arg1”:查询条件(实现了序列化接口的对象),例如:"4028818a245fdd0301245fdd06380001" 字符串已经实现了序列化接口; ##** 如果是数值类类型,则 hibernate 会自动使用包装类。 ## 返回: ##* 此方法返回类型为 Object,然后我们再强行转换为需要加载的对象就可以了。【返回值需要强制类型转换???】 ##* 如果数据库中没有相应的记录,则返回 '''null'''。【不会抛出异常】 ## 执行:该方法会'''立即发出查询''' SQL 语句,加载对象。 #: 示例: #: <syntaxhighlight lang="Java" highlight=""> try { session = sf.openSession(); session.beginTransaction(); // 方法返回类型为Object,需要再强行转换为需要加载的对象 // 方法会立即发出查询语句 User user = (User)session.get(User.class, 1); // 数据加载完后的状态为 persistent 状态。数据将与数据库同步 System.out.println("user.name=" + user.getName()); // 此时 user 为 persistent 状态 user.setName("eijux"); session.getTransaction().commit(); } catch (HibernateException e) { e.printStackTrace(); session.getTransaction().rollback(); } finally{ if (session != null){ if (session.isOpen()){ session.close(); } } </syntaxhighlight> # '''update()''':向数据库中'''更新'''实体。 #* 用于更新“'''detached'''”对象,更新完成后转为为“persistent”状态;【默认更新全部字段】 #* 更新“transient”对象(没有 ID)会报错; #** 更新自己设定 ID 的“transient”对象则可以。 #* “persistent”状态的对象,只要设定字段不同的值,在 session 提交时,会自动更新(默认更新全部字段)。 #* 如果需要更新部分字段,有两种方法: #*# '''update / updatable 属性''':用于设置'''参与更新的字段'''。【适合 xml、注解 方式】【较少用,不灵活】 #*## xml 方式:(映射关系配置文件中)设置“<property>”标签的“update”属性,以设置在更新时是否参与更新。 #*##* false:不参与更新;true(默认):参与更新。 #*##: 示例: #*##: <syntaxhighlight lang="xml" highlight=""> <property name="name" update="false"/> </syntaxhighlight> #*## annotation 方式:(映射关系类中)设定“@Column”的“updatable”属性值,以设置在更新时是否参与更新。 #*##: 示例: #*##: <syntaxhighlight lang="Java" highlight=""> @Column(updatable=false) public String getTitle() {return title;} </syntaxhighlight> #*# '''dynamic-update 属性''':用于设置'''仅更新变更的字段'''。【只适合 xml 方式,JAP1.0 annotation 没有对应属性】 #*#: 在实体类的映射文件(映射关系配置文件)中的“<class>”标签中,设置“dynamic-update”属性:true,表示修改了哪个字段就更新哪个字段,其它字段不更新。 #*#* 但要求是同一个 session(不能跨 session),如果跨了 session 同样会更新所有的字段内容。 #*#: 示例: #*#: <syntaxhighlight lang="xml" highlight=""> ... <class name="com.bjsxt.Student" dynamic-update="true"> ... </syntaxhighlight> #*#: <syntaxhighlight lang="Java" highlight=""> @Test public void testUpdate() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Student s = (Student)session.get(Student.class, 1); s.setName("zhangsan"); // 提交时,会只更新 name 字段,因为此时的 s 为 persistent 状态 session.getTransaction().commit(); s.setName("zhangsi"); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); // 更新时,会更新所有的字段,因为此时的 s 不是 persistent 状态 session2.update(s); session2.getTransaction().commit(); } </syntaxhighlight> #*#* 如果需要跨 session 实现更新修改的部分字段,需要使用 session.merget() 方法,合并字段内容: #*#*: 示例: #*#*: <syntaxhighlight lang="Java" highlight=""> @Test public void testUpdate() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Student s = (Student)session.get(Student.class, 1); s.setName("zhangsan"); // 提交时,会只更新 name 字段,因为此时的 s 为 persistent 状态 session.getTransaction().commit(); s.setName("zhangsi"); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); // 使用s ession.merget() 方法,合并字段内容 session2.merge(s); // 提交时,会只更新 name 字段 session2.getTransaction().commit() } </syntaxhighlight> #*#*: 如上,虽然可以实现部分字段更新,但这样会多出一条 select 语句,因为在字段数据合并时,需要比较字段内容是否已变化,就需要从数据库中取出这条记录进行比较。 #*#*: 所以,'''跨 Session 更新部分字段''',建议使用 '''HQL'''(EJBQL)面向对象的查询语言: #*#*: 示例: #*#*: <syntaxhighlight lang="Java" highlight=""> @Test public void testUpdate7() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Query q = session.createQuery("update Student s set s.name='z5' where s.id = 1"); q.executeUpdate(); session.getTransaction().commit(); } </syntaxhighlight> # '''saveOrUpdate()''':向数据库中'''保存/更新'''实体。 #* 在执行的时候 hibernate 会检查,如果对象在数据库中已经有对应的记录(存在同样主键的记录),则会更新(update),否则会添加数据(save)。 # '''clear()''':'''清除 session 缓存'''。 #* 无论是 load 还是 get,都会首先查找缓存('''一级缓存''',也叫“'''session 缓存'''”),如果没有,才会去数据库查找,调用 clear() 方法可以强制清除 session 缓存。 #: 示例: #: <syntaxhighlight lang="Java" highlight=""> // 使用 getCurrentSession,所以不需要手动关闭 Session Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 1); System.out.println(t.getName()); session.clear(); Teacher t2 = (Teacher)session.load(Teacher.class, 1); System.out.println(t2.getName()); session.getTransaction().commit(); </syntaxhighlight> #: 如上,两个 load 方法均会发送查询到数据库。如果注释掉 clear,则第二次 load 不发送查询到数据库,而是直接使用第一次 load 的缓存(两次 load 的是同一个记录)。 # '''flush()''':'''强制同步数据(从内存到数据库)'''。 #* 在默认的情况下 session.commit() 之前时,其实执行了一个 flush 命令。 #* 只有部分 SQL 语句(update、insert、delete),才需要 flush。 #** 对于“session.save()”方法: #**: 如果主键生成策略是“由数据库生成”(native),则 session.save 的同时就发出 SQL 语句(insert)。否则(uuid),session.save 不会发出 SQL 语句。【???】 #* 可以通过 <syntaxhighlight lang="Java" inline>session.setFlushMode(FlushMode);</syntaxhighlight> 来设置“'''刷新模式'''”: #*: FlushMode 的枚举值: #*#“FlushMode.ALWAYS”:任务一条SQL语句,都会 flush 一次; #*#“FlushMode.AUTO”:自动 flush(默认); #*#“FlushMode.COMMIT”:只有在 commit 时才 flush; #*#“FlushMode.MANUAL”:手动 flush; #*#“FlushMode.NEVER”:永远不 flush。(此选项在性能优化时可能用,比如 session 取数据为只读时用,这样就不需要与数据库同步了) #** 设置 flush 模式(FlushMode),应该在 session 开启事务之前。 # '''evict()''':'''从 session 缓存(EntityEntries属性)中逐出该对象'''。 #* 与 commit 同时使用,会抛出异常。【???】 #*: 示例: #*: <syntaxhighlight lang="Java" highlight=""> session = HibernateUtils.getSession(); tx = session.beginTransaction(); User1 user = new User1(); user.setName("李四"); user.setPassword("123"); user.setCreateTime(new Date()); user.setExpireTime(new Date()); /* 利用 Hibernate 将实体类对象保存到数据库中。 因为 user 主键生成策略采用的是 uuid,所以调用完成 save 后,只是将 user 纳入 session 的管理,不会发出 insert 语句,但是 id 已经生成,session 中的 existsInDatabase 状态为 false */ session.save(user); // 从session缓存(EntityEntries属性)中逐出该对象 session.evict(user); /* 无法成功提交。 因为 hibernate 在清理缓存时,在 session 的临时集合(insertions)中取出 user 对象进行 insert 操作后,需要更新 entityEntries 属性中的 existsInDatabase 为 true,而我们采用 evict 已经将 user 从 session 中逐出了,所以找不到相关数据,无法更新,抛出异常。 */ tx.commit(); </syntaxhighlight> #** 解决在逐出 session 缓存中的对象不抛出异常的方法:在 session.evict() 之前进行显示的调用 session.flush() 方法就可以了。【???】 #**: 示例: #**: <syntaxhighlight lang="Java" highlight=""> session.save(user); /* flush 后 hibernate 会清理缓存,会将 user 对象保存到数据库中,将 session 中的 insertions 中的 user 对象清除,并且会设置 session 中的 existsInDatabase 状态为 false */ session.flush(); // 从session缓存(EntityEntries属性)中逐出该对象 session.evict(user); /* 可以成功提交。 因为 hibernate 在清理缓存时,在 Session 的 insertions 中集合中无法找到 user 对象所以不会发出 insert 语句,也不会更新 session 中 existsInDatabase 的状态。 */ tx.commit(); </syntaxhighlight> # '''persist()''':做一个瞬态的实例持久化。 #* 在事务里执行 session.persist(),不会向数据库插数据,事务 commit 了才会插入数据。 load() 与 get(): 1、不存在对应记录时: load 抛出异常。 get 返回 null。 2、返回对象: load 返回的是代理对象,等到真正使用对象的内容时才发出 sql 语句,这样就要求在第一次使用对象时,要求 session 处于 open 状态,否则出错。 get 返回的对象即为 Object。(需要进行强制类型转换,来得到需要的对象类型) 3、加载时机: load 进行延迟加载。 get 进行立即加载。 此外,get() 和 load() '''只根据主键查询''',不能根据其它字段查询,如果想根据非主键查询,可以使用 '''HQL'''。 == Transaction == Hibernate 的 Transaction 是底层的 '''JDBC Transaction''' 或者 '''JTA Transaction''' 的封装,具体取决于在 hibernate.properties(hibernate.cfg.xml 中 property “current_session_context_class”) 的配置。 配置事务管理器(hibernate.cfg.xml 中): # 使用 JDBC Transaction: #: <syntaxhighlight lang="xml" highlight=""> <property name="current_session_context_class">thread</property> </syntaxhighlight> # 使用 JTA Transaction: #: <syntaxhighlight lang="xml" highlight=""> <property name="current_session_context_class">jta</property> </syntaxhighlight> Hibernate 进行持久化操作时(CRUD)必须进行事务控制。 示例: : <syntaxhighlight lang="Java" highlight=""> Transaction tx = null; try{ tx = session.beginTransaction(); session.save(obj); tx.commit(); }catch(HibernateException e){ if(tx != null){ tx.rollback(); } throw e; }finally{ if(session != null){ session.close(); } } </syntaxhighlight>
返回至“
Hibernate笔记 3:核心API
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息