hibernate中get和load的区别:
(1)load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,在用到对象中的
其他属性数据时才查询数据库,但是万一数据库中不存在该记录,只能抛ObjectNotFoundEcception异常
,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这
个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下
session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有
对应记录存在就可以使用load方法来实现延迟加载。
(2)get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓
存中查找,还没有就查数据库,数据库中没有就返回null。
动态改变数据的加载:
在配置文件里面可以用lazy=true,在程序里面可以用强制加载的方法Hibernate.initialize(Object
proxy) 方法强制加载这样就相当于动态改变为lazy=false。
需要注意的一点是:其中的proxy是持久对象的关联对象属性,比如A实体,你要把A的关
联实体B也检出,则要写Hibernate.initialize(a.b)。
附: Hibernate synchronizer映射oracle时,驱动及URL,用户名,密码都已填写好了,在Refresh时,出来的表是系统中所有的表,而不是用户所在表空间的用户表,在Schema Pattern里写上大写的用户名,来实现过滤。
关于Hibernate通过MyEclipse 建立oracle数据库连接时,报出下面的错误.
java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-12705: invalid or unknown NLS parameter value specified
是驱动问题。
hibernate.hbm2ddl.auto
validate 加载hibernate时,验证创建数据库表结构
create 每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
create-drop 加载hibernate时创建,退出是删除表结构
update 加载hibernate自动更新数据库结构
Hibernate 的saveOrUpdate方法
hibernate提供了saveOrUpdate的方法来进行数据库的操作。hibernate会根据对象的状态决定是insert还是update,其根本是通过xml文件中unsaved-value来确定的(默认为null)。如果设置null,系统会根据传入的对象的id的值判断,如果是null,则表示对象不存在,那么insert;如果不是Null,则表示已经存在,那么update.如果设置为none,那么表示对象不存在,会始终调用insert;如果设置为any,那么表示对象始终存在,会始终调用update。
说明:默认unsaved-value="null" ,这时有所不同,hibernate会根据主键产生一个select,来判断此对象是否已被持久化,已被持久化则update,未被持久化则save。当主键生成策略为assigned时,如果ID重复了,不会报错,会将已有数据更新。
数据库表主键
Generator 为每个 POJO 的实例提供唯一标识。一般情况,我们使用“native”。class 表示采用由生成器接口net.sf.hibernate.id.IdentifierGenerator 实现的某个实例,其中包括:
- “assigned” 主键由外部程序负责生成,在 save() 之前指定一个。
- “hilo” 通过hi/lo 算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。
- “seqhilo”与hilo 类似,通过hi/lo 算法实现的主键生成机制,需要数据库中的 Sequence, 适用于支持 Sequence 的数据库,如Oracle。
- “increment”主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值, 之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。
- “identity”采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制。
- “sequence”采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence。
- “native”由 Hibernate 根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式。
- “uuid.hex”由 Hibernate 基于128 位 UUID 算法 生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
- “uuid.string”与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据库中。
- “foreign”使用另外一个相关联的对象的标识符作为主键。
Hibernate统计函数
从Hibernate 3.0.x/3.1.x升级到最新的3.2版之后,3.2版的很多sql函数如count(), sum()的唯一返回值已经从Integer变为Long,如果不升级代码,会得到一个ClassCastException。
这个变化主要是为了兼容JPA,可以在hibernate.org的最新文档中找到说明。如:
count = ((Integer)iter.next()).intValue(); 这样会报ClassCastException。改为这样就可以了,count = ((Number)iter.next()).intValue()。
public int getTotalCount(String hql) {
int count=0;
String countStr = "select count(*) "+ hql;
List list = findHelper(countStr);
Iterator iter = list.iterator();
if(iter.hasNext()){
count = ((Number)iter.next()).intValue();
}
return count;
}
附:在org.hibernate包中有下面三个对很有用的接口:
1、Interface ScrollableResults
这个接口类似JDBC中的ResultSet一样,提供了对返回结果集合的遍历和字段访问方法,如:
public boolean next() 游标后移
public boolean previous() 游标前移
public boolean scroll(int i) 游标移动到指定未知
public void beforeFirst() 游标在首记录前
public void afterLast() 游标在末记录后
public Object[] get() 将当前记录的字段值以Object对象数组形式返回
public Object get(int i) 将当前记录的特定字段值以Object对象形式返回
public Integer getInteger(int col) 将当前记录的特定字段值以Integer对象返回
public Long getLong(int col) 将当前记录的特定字段值以Long对象返回
public String getText(int col) 将当前记录的特定字段值以Text对象返回
public String getString(int col) 将当前记录的特定字段值以String对象返回
...
2、Interface Query
Query接口封装了对数据库的查询等操作,在这里,我们使用到它的原因是在于它的scroll()方法可以返回一个ScrollableResults实例:
public ScrollableResults scroll() 将查询结果以ScrollableResults实例返回,但需要注意的是查询返回的结果其实只是一些id,当需要的时候(比如我们使用ScrollableResults.next()方法后移游标时)这条需要用到的记录才会被真正初始化。
3、Interface Session
Session是Hibernate的核心中的核心,通过Session的createQuery()方法,我们能生成一个Query实例:
public
Query createQuery(String queryString) 用给出的HQL查询串创建一个Query实例。
例子:
public List statTotalCharge(Date statTimeBegin, Date statTimeEnd) throws DaoException{
List res = new Vector();//将用于存放保存的结果集合
Session session = null;
ScrollableResults srs = null;
try{
session = HibernateSessionFactory.openSession();//得到一个Hibernate Session
//下面创建一个匿名Query实例并调用他的scroll()方法返回以ScrollableResults形式组织的查询结果
srs = session.createQuery(“select b.name, count(a.fee) mix(a.chargeBeginTime) max(a.chargeEndTime) from charge a, customer b where a.idCustomer = b.idCustomer and a.chargeBeginTime >= ? and a.chargeEndTime < ? gourp by a.idCustomer“).setDate(0, statTimeBegin).setDate(1, statTimeEnd).scroll();
//将查询结果放入List保存
while(srs.next()){
res.add(new TotalCharge(srs.getString(0), srs,getDouble(1), srs.getDate(2), srs.getDate(3)));
}
}catch(HibernateException he){
if(srs!=null){
try{
srs.close();
}catch(Exception e){
;
}
}
}finally{
try{
session.close();
}catch(Exception e){
;
}
}
return res;
}