hibernate get/load/saveOrUpdate/statistics

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 实现的某个实例,其中包括:

  1.    “assigned” 主键由外部程序负责生成,在 save() 之前指定一个。
  2.    “hilo” 通过hi/lo 算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。
  3.    “seqhilo”与hilo 类似,通过hi/lo 算法实现的主键生成机制,需要数据库中的 Sequence, 适用于支持 Sequence 的数据库,如Oracle。
  4.    “increment”主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值, 之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。
  5.    “identity”采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制。
  6.    “sequence”采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence。
  7.    “native”由 Hibernate 根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式。
  8.    “uuid.hex”由 Hibernate 基于128 位 UUID 算法 生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
  9.    “uuid.string”与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据库中。
  10.    “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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值