Hibernate Lazy属性

标签: hibernate lazy 属性 | 发表时间:2013-06-11 11:21 | 作者:无可奈何SOS
出处:http://www.cnblogs.com/

1 延迟加载策略


  Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术。这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录。通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销。Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、关联实体,这就是代理模式应用带来的优势。


  但是,延迟加载也是项目开发中特别常见的一个错误。如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它。如果在游离状态时才初始化它,就会产生延迟初始化错误。所以,在开发独立的DAO数据访问层时应该格外小心这个问题。


  如果在获取对象的时候使用的是session.get()是不会延迟加载的,只有在使用load、hql时候才会延迟加载。


       Hibernate中允许使用延迟加载的地方主要有以下几个地方:


<hibernate-mapping default-lazy=(true|false)”true”>:设置全局的延迟加载策略。


<class lazy=(true|false)>:DTD没设置默认值,推理默认值为true


<property lazy=(true|false)>:设置字段延迟加载,默认为false


<component lazy=(true|false):默认为false


<subclass lazy=(true|false)>:默认设置为true


<join-subclass lazy=(true|false)>:默认设置为true


<union-subclass lazy=(true|false)>:默认设置为true


<many-to-one lazy=(proxy|no-proxy|false)>:默认为proxy


<one-to-one lazy=(proxy|no-proxy|false)>:默认为proxy


<map lazy=(true|extra|false)>:默认为true


<set lazy=(true|extra|false)>:默认为true


<bag lazy=(true|extra|false)>:默认为true


<ibag lazy=(true|extra|false)>:默认为true


<list lazy=(true|extra|false)>:默认为true


 


2 对象加载<class>


2.1 延迟加载策略(默认)


  如果想对实体对象使用延迟加载,必须要在实体的映射配置文件中进行相应的配置


  <class name= "Person" table= "PERSON" lazy= "true">



1     tx = session.beginTransaction();   
2 Person p=(Person) session.load(Person.class, "001");//(1)
3 System.out.println("0: "+p.getPersonId());//(2)
4 System.out.println("0: "+p.getName());//(3)
5 tx.commit();
6 session.close();


  执行到(1)并没有出现sql语句,并没有从数据库中抓取数据。这个时候查看内存对象p如下:



图2.1 person对象load时的内存快照


  观察person对象,我们可发现是Person$$EnhancerBy..的类型的对象。这里所返回的对象类型就是Person对象的代理对象,在hibernate中通过使用CGLB来先动态构造一个目标对象的代理类对象,并且在代理对象中包含目标对象的所有属性和方法。所以,对于客户端而言是否为代理类是无关紧要的,对他来说是透明的。这个对象中,仅仅设置了id属性(即personId的值),这是为了便于后面根据这个Id从数据库中来获取数据。


   运行到(2)处,输出为001,但是仍然没有从数据库里面读取数据。这个时候代理类的作用就体现出来了,客户端觉得person类已经实现了(事实上并未创建)。但是,如果这个会后session关闭,再使用person对象就会出错了。


   调试运行到(3)处,要用到name属性,但是这个值在数据库中。所以hibernate从数据库里面抓取了数据,sql语句如下所示:



Hibernate:    
select
person0_.PERSONID as PERSONID3_0_,
person0_.NAME as NAME3_0_
from
PERSON person0_
where
person0_.PERSONID=?


  这时候,我们查看内存里面的对象如下:



图2.2 class延迟加载时内存对象


  真正的Person对象放在CGLIB$CALLBACK_0对象中的target属性里。


  这样,通过一个中间代理对象,Hibernate实现了实体的延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。所以实体的延迟加载是用通过中间代理类完成的,所以只有session.load()方法才会利用实体延迟加载,因为只有session.load()方法才会返回实体类的代理类对象。


2.2 非延迟加载策略


  Hibernate默认的策略便是非延迟加载的,所以设置lazy=false


  



1     tx = session.beginTransaction();   
2 Person p=(Person) session.load(Person.class, "001");//(1)
3 System.out.println("0: "+p.getPersonId());//(2)
4 System.out.println("0: "+p.getName());//(3)
5 tx.commit();
6 session.close();


  调试运行到(1)处时,hibernate直接执行如下sql语句:



Hibernate:    
select
person0_.PERSONID as PERSONID3_0_,
person0_.NAME as NAME3_0_
from
PERSON person0_
where
person0_.PERSONID=?


  我们在查看内存快照如下:



      这个时候就不是一个代理类了,而是Person对象本身了。里面的属性也已经全部 普通属性也全部被加载。这里说普通属性是因为addresses这个集合对象并没有被加载,因为set自己本身也可以设置lazy属性。所以,这里也反映出class对象的lazy并不能控制关联或集合的加载策略。


2.3 总结


  Hibernate中<class lazy=””>默认为true。如果,在load的时候只会返回一个代理类,并不会正在从数据库中读取数据。第一次用到时,会将所有 普通属性(set这种就不是)全部加载进来。如果第一次使用到时,session已经关闭将发生错误。


  如果显式是设置lazy=false,load的时候即会把所有 普通属性全部读取进来。而且,返回的将是一个真正的该类型的对象(如Person),而不是代理类。


3 字段加载(property)


  在Hibernate3中,引入了一种新的特性——属性的延迟加载,这个机制又为获取高性能查询提供了有力的工具。在大数据对象读取时,如Person对象中有一个School字段,该字段是一个java.sql.Clob类型,包含了用户的简历信息,当我们加载该对象时,我们不得不每一次都要加载这个字段,而不论我们是否真的需要它,而且这种大数据对象的读取本身会带来很大的性能开销。


3.1 延迟加载


1、   <class lazy=”false”>


  配置如下



1     tx = session.beginTransaction();   
2 Person p=(Person) session.load(Person.class, "001");//(1)
3 System.out.println("");//(2)
4 System.out.println("0: "+p.getPersonId());//(3)
5 System.out.println("0: "+p.getName());//(4)
6 System.out.println("0: "+p.getSchool());//(5)
7 tx.commit();



1         <property name="name" type="java.lang.String">   
2 <column name="NAME" />
3 </property>
4 <property name="school" type="java.lang.String" lazy="true">
5 <column name="SCHOOL"></column>
6 </property>


       当运行到p的时候,全部加载了,执行语句如下:



Hibernate:    
select
person0_.PERSONID as PERSONID3_0_,
person0_.NAME as NAME3_0_,
person0_.SCHOOL as SCHOOL3_0_
from
PERSON person0_
where
person0_.PERSONID=?


  所有普通属性都均已加载。


2 、<class lazy=”true”>


  School的lazy属性自然还是true。当程序运行到(4)时,也同样加载了全部属性,执行了如下sql:



Hibernate:    
select
person0_.PERSONID as PERSONID3_0_,
person0_.NAME as NAME3_0_,
person0_.SCHOOL as SCHOOL3_0_
from
PERSON person0_
where
person0_.PERSONID=?


  结果就是无效,不管采用何种策略都是无效的,和我们想想的有较大出路。下面是一段来自hibernate官方文档的话。


  Lazy property loading requires buildtime bytecode instrumentation. If your persistent classes are not enhanced, Hibernate will ignore lazy property settings and return to immediate fetching.


  应该是因为,我们并未用到 编译时字节码增强技术的原因。如果只对部分property进行延迟加载的话,hibernate还提供了另外的方式,也是更为推荐的方式,即HQL或者条件查询。


   A different way of avoiding unnecessary column reads, at least for read-only transactions, is to use the projection features of HQL or Criteria queries. This avoids the need for buildtime bytecode processing and is certainly a preferred solution.


4 集合无关联


Person类



1 public class Person {   
2 private String name;
3 private String sex;
4 private Set<String> addresses;
5 }


Person.hbm.xml



 1 <class name="com.hbm.hibernate.Person" table="PERSON">   
2 <id name="name" type="java.lang.String">
3 <column name="NAME"/>
4 <generator class="assigned"/>
5 </id>
6 <property name="sex" type="java.lang.String">
7 <column name="SEX"/>
8 </property>
9 <set name="addresses" table="ADDRESSES" inverse="false" lazy="true" fetch="join">
10 <key column="NAME"/>
11 <element column="ADDRESS" type="java.lang.String"></element>
12 </set>
13 </class>


4.1 非延迟加载策略


  映射文件的配置<set lazy=”false”>。



1        tx = session.beginTransaction();   
2 Person person=(Person) session.load(Person.class, "XiJinping");//(1)
3 System.out.println("");//(2)
4 System.out.println("0: "+person.getName());//(3)
5 System.out.println("1: "+person.getSex());//(4)
6 System.out.println("2: "+person.getAddresses());//(5)
7    tx.commit();


  运行到(4)处时,加载了全部属性,执行了如下sql语句。



 1 Hibernate:    
2 /* load com.hbm.hibernate.Person */ select
3 person0_.NAME as NAME0_0_,
4 person0_.SEX as SEX0_0_
5 from
6 PERSON person0_
7 where
8 person0_.NAME=?
9 Hibernate:
10 /* load collection com.hbm.hibernate.Person.addresses */ select
11 addresses0_.NAME as NAME0_,
12 addresses0_.ADDRESS as ADDRESS0_
13 from
14 ADDRESSES addresses0_
15 where
16 addresses0_.NAME=?


  fetch策略的配合使用,当<set lazy=”false” fetch=”join”>时,执行的sql语句如下。这个是有,将不再采用两条select语句的方式,而是采用左连接的方式进行,有利于提高效率。



Hibernate:    
/* load com.hbm.hibernate.Person */ select
person0_.NAME as NAME0_0_,
person0_.SEX as SEX0_0_,
addresses1_.NAME as NAME2_,
addresses1_.ADDRESS as ADDRESS2_
from
PERSON person0_
left outer join
ADDRESSES addresses1_
on person0_.NAME=addresses1_.NAME
where
person0_.NAME=?


4.2 延迟加载策略


  映射文件的配置<set lazy=”true”>。


  当程序运行到(4),hibernate加载了Person对象的其他全部属性,执行了如下sql语句。



Hibernate:    
/* load com.hbm.hibernate.Person */ select
person0_.NAME as NAME0_0_,
person0_.SEX as SEX0_0_
from
PERSON person0_
where
person0_.NAME=?


  当程序运行到(5)时,hibernate加载了所有的address对象,执行如下sql语句。



1 Hibernate:    
2 /* load collection com.hbm.hibernate.Person.addresses */ select
3 addresses0_.NAME as NAME0_,
4 addresses0_.ADDRESS as ADDRESS0_
5 from
6 ADDRESSES addresses0_
7 where
8 addresses0_.NAME=?


4.2 延迟加载extra


   It can also be used to enable "extra-lazy" fetching where most operations do not initialize the collection. This is suitable for large collections.


  大部分操作的时候并不会加载集合,适用于大的集合。extra其实是一种比较智能的延迟加载,即调用集合的size/contains等方法的时候,hibernate并不会去加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据。


       映射文件配置映射文件的配置<set lazy=”extra”>


  



 1 public int getNum(){   
2 return addresses.size();
3 }
4
5 tx = session.beginTransaction();
6 Person person=(Person) session.load(Person.class, "XiJinping");//(1)
7 System.out.println("");//(2)
8 System.out.println("0: "+person.getName());//(3)
9 System.out.println("1: "+person.getSex());//(4)
10 System.out.println("2: "+person.getNum());//(5)
11 System.out.println("3: "+person.getAddresses());//(6)
12 tx.commit();


  当程序运行到(4)时,进行了第一次的加载,加载了person对象的所有普通属性,执行sql如下:



Hibernate:    
/* load com.hbm.hibernate.Person */ select
person0_.NAME as NAME0_0_,
person0_.SEX as SEX0_0_
from
PERSON person0_
where
person0_.NAME=?


  当程序运行到(5)时,进行了第二次加载,这个时候并没有去加载set集合中的所有属性,hibernate智能的用sql语句获取了集合中的数量,执行的sql语句如下:



Hibernate:    
select
count(ADDRESS)
from
ADDRESSES
where
NAME =?


  当程序运行到(6)时,进行了第三次加载,将集合中的所有对象均加载进来了,执行的sql语句如下:



Hibernate:    
/* load collection com.hbm.hibernate.Person.addresses */ select
addresses0_.NAME as NAME0_,
addresses0_.ADDRESS as ADDRESS0_
from
ADDRESSES addresses0_
where
addresses0_.NAME=?


4.4 总结


  在集合的3中延迟加载中,我觉得最有的配置应该是extra。但是,默认配置false和extra均不适用于,session会话之外的情况。


  Hibernate中集合属性的延迟加载应该来说是最为重要的,因为如果集合属性里面包含十万百万记录,在初始化持久实体的同时,完成所有集合属性的抓取,将导致性能急剧下降。


5 集合有关联


Person类



1 public class Person {   
2 private String personId;
3 private String name;
4 private Set addresses;
5 public int getNum(){
6 return addresses.size();
7 }
8 }


Address类



1 public class Address {   
2 private String addressId;
3 private String addressDetail;
4 private Set people;
5 }


Person.hbm.xml



<class name="com.hbm.hibernate.Person" table="PERSON">   
………
<set name="addresses" table="PERSON_ADDRESS" cascade="all">
<key>
<column name="PERSONID" />
</key>
<many-to-many class="com.hbm.hibernate.Address" column="ADDRESSID"></many-to-many>
</set>
</class>


5.1 非延迟加载


  映射文件配置<set lazy=”false”>



1 tx = session.beginTransaction();   
2 Person person=(Person) session.load(Person.class, "001");//(1)
3 System.out.println("");//(2)
4 System.out.println("0: "+person.getPersonId());//(3)
5 System.out.println("1: "+person.getName());//(4)
6 System.out.println("2: "+person.getNum());//(5)
7 System.out.println("3: "+person.getAddresses());//(6)
8 tx.commit();


  当程序运行到(4)时,hibernate加载了所有属性,执行的sql语句如下:



Hibernate:    
select
person0_.PERSONID as PERSONID2_0_,
person0_.NAME as NAME2_0_
from
PERSON person0_
where
person0_.PERSONID=?
Hibernate:
select
addresses0_.PERSONID as PERSONID1_,
addresses0_.ADDRESSID as ADDRESSID1_,
address1_.ADDRESSID as ADDRESSID0_0_,
address1_.ADDRESSDETAIL as ADDRESSD2_0_0_
from
PERSON_ADDRESS addresses0_
left outer join
ADDRESS address1_
on addresses0_.ADDRESSID=address1_.ADDRESSID
where
addresses0_.PERSONID=?


5.2 延迟加载与extra策略


  与无关联关系时一致,不再累述。


6 1-1和N-1延迟加载策略


LineItem类



public class LineItem {   
private int lineNumber;
private int amount;
private double price;
private Product product;
}


Product类



public class Product {   
private String id;
private String name;
private double listprice;
}


LineItem.hbm.xml



    <class name="com.hbm.hibernate.LineItem" table="LINEITEM">   
<id name="lineNumber" type="int">
<column name="LINENUMBER" />
<generator class="assigned" />
</id>
<property name="amount" type="int">
<column name="AMOUNT" />
</property>
<property name="price" type="double">
<column name="PRICE" />
</property>
<join table="LINE_PRODUCT">
<key column="LINENUMBER"/>
<many-to-one name="product" unique="true" lazy="false" not-null="true" column="PRODUCTID"/>
</join>
</class>


6.1 非延迟加载


  映射文件配置<many-to-one lazy=”false”>



1 tx = session.beginTransaction();   
2 LineItem l=(LineItem) session.load(LineItem.class, 2);//(1)
3 System.out.println("");//(2)
4 System.out.println("0: "+l.getLineNumber());//(3)
5 System.out.println("1: "+l.getAmount());//(4)
6 System.out.println("2: "+l.getProduct());//(5)
7 tx.commit();


  程序运行到(4)处时,hibernate加载了所有属性,执行了如下sql语句:



Hibernate:    
select
lineitem0_.LINENUMBER as LINENUMBER1_0_,
lineitem0_.AMOUNT as AMOUNT1_0_,
lineitem0_.PRICE as PRICE1_0_,
lineitem0_1_.PRODUCTID as PRODUCTID2_0_
from
LINEITEM lineitem0_
inner join
LINE_PRODUCT lineitem0_1_
on lineitem0_.LINENUMBER=lineitem0_1_.LINENUMBER
where
lineitem0_.LINENUMBER=?
Hibernate:
select
product0_.PRODUCTID as PRODUCTID0_0_,
product0_.NAME as NAME0_0_,
product0_.LISTPRICE as LISTPRICE0_0_
from
PRODUCT product0_
where
product0_.PRODUCTID=?


  在这个时候,去查看内存中的LineItem类型对象,我们发现也是一个代理类。而回调函数中,tagert属性中的Prdouct是一个真正的Product类型对象。



6.2 延迟加载proxy


   映射文件设置<many-to-one lazy=”proxy”>


       当程序运行到(4)时,进行了第一次的加载,执行的sql语句如下:



Hibernate:    
select
lineitem0_.LINENUMBER as LINENUMBER1_0_,
lineitem0_.AMOUNT as AMOUNT1_0_,
lineitem0_.PRICE as PRICE1_0_,
lineitem0_1_.PRODUCTID as PRODUCTID2_0_
from
LINEITEM lineitem0_
inner join
LINE_PRODUCT lineitem0_1_
on lineitem0_.LINENUMBER=lineitem0_1_.LINENUMBER
where
lineitem0_.LINENUMBER=?


  当程序运行到(5)时,进行了第二次的加载,执行的sql语句如下:



Hibernate:    
select
product0_.PRODUCTID as PRODUCTID0_0_,
product0_.NAME as NAME0_0_,
product0_.LISTPRICE as LISTPRICE0_0_
from
PRODUCT product0_
where
product0_.PRODUCTID=?


  这个时候,我们去参看内存,发现target中的product属性便是个代理类,如下图所示:



6.3 总结


  默认情况下,Hibernate 也会采用延迟加载来加载关联实体,不管是一对多关联、还是一对一关联、多对多关联,Hibernate 默认都会采用延迟加载。


  对于关联实体,可以将其分为两种情况:


  关联实体是多个实体时(包括一对多、多对多):此时关联实体将以集合的形式存在,Hibernate 将使用 PersistentSet、PersistentList、PersistentMap、PersistentSortedMap、PersistentSortedSet 等集合来管理延迟加载的实体。这就是前面所介绍的情形。


  关联实体是单个实体时(包括一对一、多对一):当 Hibernate 加载某个实体时,延迟的关联实体将是一个动态生成代理对象。


  当关联实体是单个实体时,也就是使用 <many-to-one.../> 或 <one-to-one.../> 映射关联实体的情形,这两个元素也可通过 lazy 属性来指定延迟加载。


7 继承(subclass为例)


Payment类



1 public class Payment {   
2 private long id;
3 private long amount;
4 }


CreditCardPayment类



public class CreditCardPayment extends Payment {   
private long creditId;
private String cardType;
}


creditCardPayment.hbm.xml



    <subclass name="com.hbm.hibernate.CreditCardPayment" discriminator-value="CREDIT"   
extends="com.hbm.hibernate.Payment" lazy="false">
<property name="creditId" column="CREDITID" type="long"></property>
<property name="cardType" column="CARDTYPE" type="java.lang.String"></property>
</subclass>


8.1 非延迟加载


  映射文件配置<subclass lazy=”false”>。


  



1 tx = session.beginTransaction();   
2 CreditCardPayment ccp=(CreditCardPayment) session.load(CreditCardPayment.class,new Long(8889));//(1)
3 System.out.println("");//(2)
4 System.out.println("0: "+ccp.getId());//(3)
5 System.out.println("1: "+ccp.getAmount());//(4)
6 System.out.println("2: "+ccp.getCardType());//(5)
7 tx.commit();


  程序运行到(1)时,加载全部属性,执行的sql语句如下:



Hibernate:    
select
creditcard0_.ID as ID0_0_,
creditcard0_.AMOUNT as AMOUNT0_0_,
creditcard0_.CREDITID as CREDITID0_0_,
creditcard0_.CARDTYPE as CARDTYPE0_0_
from
PAYMENT creditcard0_
where
creditcard0_.ID=?
and creditcard0_.PAYMENT_TYPE='CREDIT'


7.2 延迟加载


  映射文件配置<subclass lazy=”true”>



Hibernate:    
select
creditcard0_.ID as ID0_0_,
creditcard0_.AMOUNT as AMOUNT0_0_,
creditcard0_.CREDITID as CREDITID0_0_,
creditcard0_.CARDTYPE as CARDTYPE0_0_
from
PAYMENT creditcard0_
where
creditcard0_.ID=?
and creditcard0_.PAYMENT_TYPE='CREDIT'


  程序执行到(4)时,第一次加载全部属性,执行的sql语句如上。


7.3 总结


  继承方式的延迟加载,set等在true或false时并未显著差别,在这里不再累述。


 


参考文献


1、http://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html_single/


2、http://blog.163.com/xi_zh_qi/blog/static/8501594200812695053939/


3、http://blog.csdn.net/linxinghui/article/details/3862324


4、http://www.ibm.com/developerworks/cn/java/j-lo-hibernatelazy/

本文链接

相关 [hibernate lazy 属性] 推荐:

Hibernate Lazy属性

- - 博客园_首页
  Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术. 这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录. 通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销. Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、关联实体,这就是代理模式应用带来的优势.

Hibernate面试题

- - ITeye博客
什么是Hibernate的并发机制. Hibernate并发机制:. a、Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个的工作单元(即单个事务,单个线程),它通常只使用一次,. 如果一个Session 实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用.

Hibernate 缓存

- - ITeye博客
1数据缓存:(date caching) 是一种将数据暂时存于内存缓存去中的技术,缓存通常是影响系统性能的关键因素. 2.ORM的数据缓存策略有3中.   1.事务级缓存:  分为 数据库事务和 应用级事务,是基于Session的生命周期的实现,每个session都会在内部维持一个数据缓存, 随session的创建和消亡.

hibernate优化

- - 开源软件 - ITeye博客
原文 http://developer.51cto.com/art/200906/129539.htm. 文章分为十三个小块儿对Hibernate性能优化技巧进行总结性分析,分析如下:. 一、在处理大数据量时,会有大量的数据缓冲保存在Session的一级缓存中,这缓存大太时会严重显示性能,所以在使用Hibernate处理大数据量的,可以使用session.

JPA & Hibernate 注解

- - CSDN博客编程语言推荐文章
必须,name为可选,对应数据库中一的个表 . 可选,通常和@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息 . name:可选,表示表的名称.默认地,表名和实体名称一致,只有在不一致的情况下才需要指定表名 . catalog:可选,表示Catalog名称,默认为Catalog(""). .

延迟加载图片的 jQuery 插件:Lazy Load

- - 我爱水煮鱼
网站的速度非常重要,现在有很多网站优化的工具,如 Google 的 Page Speed,Yahoo 的 YSlow,对于网页图片,Yahoo 还提供 Smush.it 这个工具对图片进行批量压缩,但是对于图片非常多的网站,载入网页还是需要比较长的时间,这个时候我们可以使用 Lazy Load 这个 jQuery 插件来延迟加载图片.

hibernate 大对象类型的hibernate映射

- - CSDN博客推荐文章
在 Java 中, java.lang.String 可用于表示长字符串(长度超过 255), 字节数组 byte[] 可用于存放图片或文件的二进制数据. 此外, 在 JDBC API 中还提供了 java.sql.Clob 和 java.sql.Blob 类型, 它们分别和标准 SQL 中的 CLOB 和 BLOB 类型对应.

JBoss发布Hibernate 4.0

- - InfoQ cn
近日, JBoss发布了流行的对象/关系(O/R)映射框架 Hibernate. Hibernate 4主要的新特性如下所示:. 引入了“Services”API. 提供了更棒的日志,支持 i18n与消息编码(通过JBoss Logging而非 slf4j). 为 OSGi支持做好了准备.

快速上手Hibernate

- - CSDN博客推荐文章
在前面我们已经对Hibernate有所了解,并知道了使用Hibernate的好处,下面就给大家展示一下如何快速使用Hibernate:. 1.下载Hibernate,并解压缩(下载地址: http://www.hibernate.org/downloads). 2.创建一个新的Java项目.   加入数据库驱动(以mysql示例).

Hibernate 二级缓存

- - CSDN博客推荐文章
很多人对二级缓存都不太了解,或者是有错误的认识,我一直想写一篇文章介绍一下hibernate的二级缓存的,今天终于忍不住了. 我的经验主要来自hibernate2.1版本,基本原理和3.0、3.1是一样的,请原谅我的顽固不化. hibernate的session提供了一级缓存,每个session,对同一个id进行两次load,不会发送两条sql给数据库,但是session关闭的时候,一级缓存就失效了.