关于hibernate的理解及用法  我想听听大家 是如何学习这个的  说下大家的见解  应该怎么去理解和学习呢  

解决方案 »

  1.   

    如果连 JDBC 都用不熟的话,不建议去看 Hibernate 什么的。
      

  2.   

    hibernate 入门就容易...想精通就难了...
      

  3.   

    首先要有JDBC的基础才行~然后先看看视频,做做实例,然后再去看看相关的书。
      

  4.   

    有数据库基础的学起来就好一些,Hibernate入门简单,想搞清楚到底是为什么那么配置的要下点功夫,建议先看书,再做一些小练习
      

  5.   


    HIBERNATE  //冬眠
      

  6.   

    Hibernate是一个Java持久化解决方案,对象-关系映射工具。
    要学找一本在下一个和书上所说的工具
    慢慢的就应该会拉(数据库要回,Jdbc要回)。
      

  7.   

    ORM 对象关系模型将数据库中的表映射为对象  并提供了 对对象的持久化 
    缓存等基本的功能提高效率
    另外 Hibernate 是jdbc的进一步封装 
    并提供了hbm2java hmb2ddl java2hbm 等基本的工具供开发者使用
      

  8.   

    想用大腿想想为什么要连接数据库、应该怎样连数据库???
    然后你再去看看hibernate就明白了。不要动不动就使命的翻书。关键在于思维
      

  9.   

    hibernate是一个持久层的ORM框架,主要是对象关系模型。。LZ最好是先对jdbc操作熟练了再去学习hibernate...  看看视频,到网上查些关于hibernate的资料,,了解hibernate里面的关联关系(一对多,多对多,一对一),掌握几个重点的接口  session query  Transaction Critira  还有一点要学习的是hql语言,hibernate查询语言。
      

  10.   

    最好还是先了解JDBC是如何工作的,再去学习Hibernate
      

  11.   

    这时我的总结:O/R映射框架  反射技术  优点:   1.提高生产力,不用再写sql语句,不用遍历结果集,代码量减少,
               2.使开发更对象化了,只要操纵session对象save方法就保存数据了
               3.移植性好,也就是方言的配置,适配器的配置,
               4.支持透明持久化,实体没有侵入性,可以复用,
       试用hibernate先建立对象模型,也就是领域模型,再建立映射关系,都是一对象为中心
       
    注意:这里是斜杠啊<mapping resource="com/landy/hibernate/User.hbm.xml"/>
       
     hibernate的映射工具:
               1.Configuration(根启动) cfg=new Configuration.configure();------>读取hibernate的配置文件hibernate.cfg.xml,加入内存
               2.SessionFactory factory=cfg.bulidSessionFactory();存储sql语句和映射源数据(连接池) ,SessionFactory适合数据库绑定的,一个数据库对应一个Sessionfactory,他是重量级的对象,就是创建比较耗时,消耗资源,最好只创建一次,他是线程安全的,可以对个线程用它,SessionFactory和二级缓存相关,
               3.Session  存放当前工作单元所加载的对象,他不同于Connection,是有SessionFactory创建出来的,他对Connection进行了封装,Session他管理了缓存,对实体对象生命周期管理,一般是一个业务对应一个Session, Session用完后必须关闭,是非线程安全的,Session和一级缓存相关
               
       
     hibernate核心接口:
               1.JNDI Java名称和目录接口,统一管理,不依赖具体实现,解决了耦合
               2.JDBC Java数据库连接,它处理本地事务,单一数据库,能保证原子性,但是跨数据库,跨资源,JDBC就不能保证了,
               3.JTA  Java事务API,保证跨数据库,跨资源的事务处理,他是两阶段数据处理,先是日志再更新,JTA是个容器,
               4.Query 查询接口,支持hql和sql
               5.Interceptor 拦截器,没有浸入性,他能将我们对实体类进行保存,删除前后的事件能侦听到,
               6.UserType 转换器的概念,用户可自定义类,
     持久化对象的生命周期:Transient(瞬时的),Persistent(持久的),Detached(离线的)
               
               1.Transient  *在数据库中没有与之匹配的数据
                            *没有纳入Session的管理
                            
               2.Persistent *在数据库中有与之匹配的数据
                            *纳入了Session的管理
                            *在清理缓存(脏数据检查)的时候,会和数据库同步
                            
               3.Detached   *在数据库中有与之匹配的数据---------->只有数据库中有了才能update处理 
                            *没有纳入Session管理
       
     Session的load()方法 实现了lazy,懒加载或延迟加载,按OID检索,只有正真使用这个对象时才加载(发出sql语句),hibernate延迟加载实现原理是代理方式,
                  正真使用时对象就是persistent状态了,hibernate会自动和数据库同步,采用load在加载数据时,如果数据库中没有相应的数据,那么抛ObectNotFoundException异常, Session的get()方法 在加载时马上发出sql语句,加载对象,不会有延迟,当查询数据不存在的数据时,返回null,并不抛出异常
      
     一般是先加载在修改,删除,也就是不要手动构造detached状态,  有许多的批量的处理就不太试用hibernate
    域对象之间的关系
               1.关联:类之间的引用关系,以属性申明体现 ------>一对一,一对多,多对一,多对多
               2.依赖:类之间访问关系,类中的方法
               3.聚集:生命周期(逻辑上的约束)
               4.一般化(泛化)继承
               主键生成策略:             
       assigned  自然主键:手动赋值
       native 动态的选择合适的标示符生成器,OREACL用到的序列hibernate_sequence
       sequence  
       identity SQLServer,MYSQL
       hilo 加一取走
       increment:拿来加一
     
     
       access=“property|filed”(访问级别,默认property)
       
       
     
     inverse  让缓存忽略set集合的变化,只关心one方,在双向关联时通常都会更新两次,inverse=true
              在映射一对多的双向关联关系时,应该在one方把inverse属性设为true,one方有集合,这可以提高性能。在建立两个对象的关联时,
              应该同时修改关联两端的相应属性:
                      Customer.getOrders().add(order);
                      Order.setCustomer(customer);这样才会使程序更加健壮,提高业务逻辑层的独立性,使业务逻辑层的程序代码不受Hibernate实现类的影响。
              同理,当删除双向关联的关系时,也应该修改关联两端的对象的相应属性:
                      Customer.getOrders().remove(order);
                      Order.setCustomer(null);
           
       
     级联关系  cascade="save-update" 关联关系的级联程度,主体改变后客体按照级联程度也进行保存更新,
              双向关联时两方同时进行,防止数据的不一致,关联关系的维护hibernate自动做了,所以在进行保存更新时只保存一方就行了,而和她关联的hibernate
              机动保存更新了,这就是级联,级联操作在开发中慎用,
              级联删除,利用jdbc删除有外键约束,利用程序删除就会被级联一起删除(更新),hibernate执行update语句将外键置为null来解除关联,
              如想删除不再关联的对象,就将cascade="all-delete-orphan"
            
     父子关系:cascade="all-delete-orphan" 子代不能删除父代,只能删除和父代关联的子代;更强的约束,将非法数据删除,关联关系的级别就不是更新了,就直接删除操作
    就是没有对应的客户的订单也删除,对应的是删除操作,但原来是null的,他不会删除
             
            
     
     多对一关联关系:
               1.cascade属性为save-update的话,可实现自动持久化所关联的对象。
               2.<many-to-one>
               
               
     一对多关联关系:
               1.<set name=“orders”  cascade=“save-update”>
                      <key column=“CUSTOMER_ID” />
                      <one-to-many class=“..Order” />
                 </set>
                 name:设定待映射持久化类的属性名。
                 cascade:设定级联操作的程度。
                 key子属性:设定与所关联的持久化类对应的标的外键。one-to-many子属性:设定所关联的持久化类。
      

  12.   

    hibernate数据操作,面向对象:
              1.插入 save()
                       对象加入缓存,成为持久化对象
              2.更新 update() 将游离对象转变为持久化对象。不论对象属性是否发生变化,该方法都会执行update操作。如果希望仅当属性变化时才执行update语句的话可进行如下配置:(还要看具体业务了,不一定打开就好)
                         <class name=“…” 
                                 table=“…” 
                                   select-before-update=“true”> ----------------------更新之前先查询,只更新改变了的,
                    Session的update操作方法盲目的激活触发器, 如果游离状态的对象的属性和数据库一致,则更新操作是多余的。为避免这种情况:
    <class name=“” table=“” select-before-update=“true”>
                                  ……
    </class>          3.查询 load(Class,id)
                     根据OID在缓存中查询,类型,OID          4.删除 delete()
                      如果参数是持久化对象,就执行一个delete语句,若为游离对象,先使游离对象被session关联,使他变为持久化对象,然后计划执行一个delete语句。          5.批量删除 **hibernate 3.0支持批量删除
                    //只是创建除了删除条件,还没有执行
                Query c=s.createQuery("delete from Customer c where c.id < 4");-------->用到Hql
                //执行
                c.executeUpdate();
              
               6. Transaction.commit(); //提交 先清理缓存,然后向数据库提交事务, 在提交前Session有个清理缓存的模式setFluseMode(FlushMode.AUTO/COMMIT/NEVER),
                              模式设置为NEVER时,只有再调用flush()方法时才会提交到数据库中,           7. Session.flush();      //清理 缓存,让数据库和缓存同步,将缓存的变化反应到数据库中,但不提交,不提交就可以回滚,           8. Session.refresh();    //刷新 缓存,让缓存和数据库同步,取数据库中变化来更新缓存,执行查询操作,           9. Session.clear()       //清空 缓存,将缓存中的引用全销毁,但引用的对象不一定被销毁,要看对象是否还有其他的引用, 
    10. Session.delete(d):将对象从Session中和记录中删除,将对象变为临时态,
    11. Session.evict(c):将持久态对象转变成游离的状态,将对象单纯的从缓存中删除,并不对应删除记录的操作,
    12. Session.saveOrUpdate():调用此方法时oid为null时肯定是save操作,如果oid类型定义为基本数据类型,那默认值为0,就不能是save操作,那怎么让oid是基本数据类的数据有插入操作,在配置文件中将id有个属性unsaved-value=“0”,这样就将oid为基本数据类型的记录调用saveOrUpdate方法时可以是save操作。
                     Session的save,update,saveOrUpdate方法都是将非持久化对象与Session关联让他们变成持久化对象, 缓存里的对象根据快照来查看数据是否有变化,只有来自数据库时才做快照(load),触发器:在服务器执行,(数据库中执行)
    Session.save(c);
    Session.flush();   //执行后,进行更新数据库操作,触发了触发器,在application端并不知道,
    Session.refresh(c);  //缓存与数据库同步
    触发器的行为导致缓存与数据库中的数据不一致。解决办法是执行完操作后,立即调用session的flush方法和refresh方法,迫使缓存与数据库同步。Session的update操作方法盲目的激活触发器,如果游离状态的对象的属性和数据库一致,则更新操作是多余的。为避免这种情况:
    <class name=“” table=“” select-before-update=“true”>
                          ……
    </class>select-before-update的作用   1.更新没有修改的数据
    2.盲目更新激活触发器映射组成关系:<compont name=“homeaddress” class=“mypack.Address”> 他是值类型, component可以嵌套, 
     
                  持久化类的属性分为两种:值(value)类型和实体类型(entity)类型。值类型没有OID,不能被单独持久化,他的生命周期依赖于所属的持久化类的对象的生命周期,组件类型就是一种值类型;实体类型有OID,可单独持久化。 在组合类型中save时没有赋值,在数据库中将会存入null,当查询时就会报空指针异常,因此要判断如果null就new一个然后添加上 
    类级别的检索:当查询对象的时候hibernate什么时候查询对象所对应的表,load受影响
          立即检索:查询表,也就是在缓存里没有,他马上就查询库      延迟检索:只有正真访问对象,在内存里创建代理对象, 他先检查缓存里,缓存里没有,他并不立即查询库
                     <class name="cn.itcast.hibernate.domain.Customer" table="hib_customers" lazy="true">      代理类是用反射技术动态生成的一个新类,他继承了客户类,代理对象他能够监控Session是否关闭,在Session关闭之前你访问代理对象的有效属性时,就会触发代理对象去访问数据库的事件,进行查询操作,将结果赋给代理对象的属性,这个过程就是初始化代理对象,只有延迟检索才会有代理对象的概念,
    代理对象在Session持久化时并没有赋初值,Session关闭后再去初始化,去查库,然而连接已关闭了,报 延迟初始化异常,可以通过下面方法进行初始化:
      

  13.   

    两边都是外连接,理论是打印出一条里面有两次外连接的语句,这在2.0是符合的,但这样会降低性能,但在3.0打印出两条语句,目的优化,忽略了第二次迫切左外连接检索,采用和lazy保持一致的检索,lazy=flase就立即,lazy=true就延迟。
    Hql语句忽略了迫切左外检索,他与lazy保持一致
    set批量立即检索  批量的检索用batch-size,和lazy来设置,Hql语句忽略了迫切左外检索,他与lazy保持一致,降低和数据库的交互次数:<set   batch-size=“ 条数”>设置一次检索的条数,一般在3-10之间批量延迟检索: 用Hql语句查询,只要将lazy=true,就是延迟检索了
    Many-to-one的批量检索,orders集合对应几个客户,一次查一个客户,要查询多次,设置一次可以查询多个客户,应该在orders对端(客户)的类级别进行设置:
     
    One-to-one:  外键关联
    一端:用多对一模拟一对多, 一对一要加上unique=“true”属性
    另一端:  property-ref属性的参考,参考对端类的映射属性
    主键关联:
    一端:
     
                     另一端:
     Many-to-many:;  两边关系对等,映射多对多关联关系时一定要将一端的inverse属性打开,避免都对关联表进行维护,只有一方来维护:inverse=TRUE
                 
        解除关系  
     
       Hibernate.properties配置文件
     access:设置hibernate访问级别,默认是propertyhibernate访问机制:
     代理主键,
    increment 从数据库中拿开加一;因此在多进程,集群环境下就不能使用increment
    hilo 在数据库加一带走,
    Oracle:hibernate¬_sequence(native) ;自然主键:class=“assigned”; 联合主键: 可以定义一个联合主键类  
     
     
    Cascade=”delete”  :级联删除 ,当只打开inverse时就会让缓存忽略集合的变化,
     
                         
     
    delete方法,将持久对象,将对象的引用从Session缓存中删除,并且对应sql删除语句将db中的记录也删除,让对象成为临时态evict方法,将Session缓存中的对象清除,但没有将DB中的数据删除的sql语句,是对象进入游离态 
    已经在Session中的记录就没有意义调用save,updat。Saveorupda方法
     HQL和QBC
     
     
    排序  分页
       
     
     
    父类 子类 继承关系,可以将子类存入一个表中,这样要有区分符
      乐观所
    在javabean中设置一个version的字段,配置文件配置如下:
     悲观锁
    二级缓:
     
    配置二级缓存,一般在hibernate.cfg.xml中配置,可以为每个配置
     使用二级缓存插件EHCache
     

    ehcache.xml配置:
     
      

  14.   

    找个青蛙研究,问它是怎么hibernate的
      

  15.   

    只有搞清楚了JDBC,才知道HIBERNATE的好处,建议楼主从JDBC开始,这样才能更好的理解Hibernate.
      

  16.   

    什么事都是一步一步来 ,我刚开始学JDBC的时候,觉得挺好的 ,已至于转到Hibernate觉得不如JDBC,后来用多了Hibernate,觉得它太强大了,一般都是只学HQL,只对实体对象进行操作,而不用理会数据库。配置好就OK了!加油 
      

  17.   

    hibernate,用什么就学了什么。。