传智播客hibernate李勇经典

上传人:t****d 文档编号:243401546 上传时间:2024-09-22 格式:PPT 页数:50 大小:623.50KB
返回 下载 相关 举报
传智播客hibernate李勇经典_第1页
第1页 / 共50页
传智播客hibernate李勇经典_第2页
第2页 / 共50页
传智播客hibernate李勇经典_第3页
第3页 / 共50页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,高级软件人才实作培训专家!,Hibernate原理与应用,讲师:,1,主要内容,引入,安装配置,基本概念和,CURD,HQL,和,Criteria,关联映射,继承映射,集合映射,懒加载,缓存,事务,其他,Hibernate,不适合的场景,与,JPA,的集成,(annotation,方式,),最佳实践,2,引入,模型不匹配,(,阻抗不匹配,),Java,面向对象语言,对象模型,其主要概念有:继承、关联、多态等;数据库是关系模型,其主要概念有:表、主键、外键等。,解决办法,1,使用,JDBC,手工转换。,2,使用,ORM(Object Relation Mapping,对象关系映射,),框架来解决,主流的,ORM,框架有,Hibernate,、,TopLink,、,OJB,。,3,安装配置,下载地址,http:/,,本教程使用,3.2.5,。,将下载目录,/hibernate3.jar,和,/lib,下的,hibernate,运行时必须的包加入,classpath,中:,antlr.jar,cglib.jar,asm.jar,commons-collections.jar,commons-logging.jar,jta.jar,dom4j.jar,4,安装配置,配置文件,hibernate.cfg.xml,和,hibernate.properties,,,XML,和,properties,两种,这两个文件的作用一样,提供一个即可,推荐,XML,格式,下载目录,/etc,下是示例配置文件。,可以在配置文件指定:,数据库的,URL,、用户名、密码、,JDBC,驱动类、方言等。,启动时,Hibernate,会在,CLASSPATH,里找这个配置文件。,映射文件,(hbm.xml,,对象模型和关系模型的映射,),。在,/eg,目录下有完整的,hibernate,示例。,快速开始小例子,5,基本概念和CURD,开发流程,1由Domain object - mapping-db。(官方推荐),2由DB开始,用工具生成mapping和Domain object。(使用较多),3由映射文件开始。,6,基本概念和CURD,Domain Object限制,1.默认的构造方法(必须的)。,2有无意义的标示符id(主键)(可选),3非final的,对懒加载有影响(可选),Domain Java Object(User),public,class,User ,private,int,id;,private,String name;,private,Date birthDay;,/getter setter,7,基本概念和CURD,1.hbm.xml,主键生成器,参考文档P65 5.1.4,2.详细信息见参考文档P62,8,基本概念和CURD,Java代码,1.初始化代码(只做一次),Configuration cfg = new Configuration();,cfg.configure(“config.cfg.xml”);,也可以通过cfg.setProperty设置属性。,SessionFactory sessionFactory = cfg.buildSessionFactory();,2.模板代码,Session session = null;Transaction tx = null;,try,session = sessionFactory.openSession();,tx = session.beginTransaction();,/你的代码save,delete,update,get,mit();,catch(Exception e),if(tx !=null)tx.rollback();throw e;,finally,if(session != null)session.close();,9,基本概念和CURD,Session,的几个主要方法,1.save,persist,保存数据,,persist,在事务外不会产生,insert,语句。,2.delete,删除对象,3.update,更新对象,如果数据库中没有记录,会出现异常。,4.get,根据,ID,查,会立刻访问数据库。,5.Load,,根据,ID,查,,(,返回的是代理,不会立即访问数据库,),。,6.saveOrUpdate,merge(,根据,ID,和,version,的值来确定是,save,或,update),调用,merge,你的对象还是托管的。,7.lock(,把对象变成持久对象,但不会同步对象的状态,),。,10,对象状态,瞬时,(transient),:数据库中没有数据与之对应,超过作用域会被,JVM,垃圾回收器回收,一般是,new,出来且与,session,没有关联的对象。,持久,(persistent),:数据库中有数据与之对应,当前与,session,有关联,并且相关联的,session,没有关闭,事务没有提交;,持久对象状态发生改变,在事务提交时会影响到数据库,(hibernate,能检测到,),。,脱管,(detached),:数据库中有数据与之对应,但当前没有,session,与之关联;托管对象状态发生改变,,hibernate,不能检测到。,11,对象状态,12,HQL和Criteria,HQL(Hibernate Query Language),面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写);HQL中查的是对象而不是和表,并且支持多态;HQL主要通过Query来操作,Query的创建方式:,Query q = session.createQuery(hql);,from Person,from,User,user,where,=:name,from,User user,where,=:name and,user.birthday,32,集合映射,集合映射(set, list, array,bag, map),!表中有单独的整型列表示list-index,!表中有单独的整型列表示list-index ,33,集合映射,集合映射(set, list, array,bag, map),34,集合映射,集合映射(set, list, array,bag, map),这些集合类都是,Hibernate,实现的类和,JAVA,中的集合类不完全一样,,set,list,map,分别和,JAVA,中的,Set,List,Map,接口对应,,bag,映射成,JAVA,的,List,;这些集合的使用和,JAVA,集合中对应的接口基本一致;,在,JAVA,的实体类中集合只能定义成接口不能定义成具体类,, 因为集合会在运行时被替换成,Hibernate,的实现。,集合的简单使用原则:,大部分情况下用,set,,需要保证集合中的顺序用,list,,想用,java.util.List,又不需要保证顺序用,bag,。,35,集合映射,cascade和inverse,(Employee Department),Casade,用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的,cascade:,none,all,save-update ,delete, lock,refresh,evict,replicate,persist,merge,delete-orphan(one-to-many),。一般对,many-to-one,many-to-many,不设置级联,在,和,中设置级联。,inverse,表“,是否放弃维护关联关系,”,(,在,Java,里两个对象产生关联时,对数据库表的影响,),,在,one-to-many,和,many-to-many,的集合定义中使用,,inverse=”true”,表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成,false,(注意,hibernate,的缺省值是,false,)。,one-to-many,维护关联关系就是更新外键。,many-to-many,维护关联关系就是在中间表增减记录。,注,:,配置成,one-to-one,的对象不维护关联关系,36,懒加载,通过asm和cglib二个包实现;Domain是非final的。,1.session.load懒加载。,2.one-to-one(元素)懒加载:,必需同时满足下面三个条件时才能实现懒加载,(主表不能有constrained=true,所以主表没有懒加载),lazy!=false 2)constrained=true 3)fetch=select,3.one-to-many (元素)懒加载:1)lazy!=false 2)fetch=select,4.many-to-one (元素) :1)lazy!=false 2)fetch=select,5.many-to-many (元素) :1)lazy!=false 2)fetch=select,6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。,37,缓存,缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。,一级缓存,Session级共享。,save,update,saveOrUpdate,load,get,list,iterate,lock这些方法都会将对象放在一级缓存中,一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict,clear方法清除缓存中的内容。,38,缓存,二级缓存,SessionFactory级共享。,实现为可插拔,通过修改,cache.provider_class,参数来改变,;,hibernate,内置了对,EhCache,OSCache,TreeCache,SwarmCache,的支持,可以通过实现,CacheProvider,和,Cache,接口来加入,Hibernate,不支持的缓存实现。,在,hibernate.cfg.xml,中加入,:,或在映射文件的,class,元素加入子元素,:,其中,usage:read-only,read-write,nonstrict-read-write,transactional,Session,的,:save(,这个方法不适合,native,生成方式的主键,),update,saveOrUpdate,list,iterator,get,load,以及,Query,Criteria,都会填充二级缓存,但只有,(,没打开查询缓存时,)Session,的,iterator,get,load,会从二级缓存中取数据,(,iterator,可能存在,N+1,次查询,),。,Query,Criteria,(,查询缓存,),由于命中率较低,所以,hibernate,缺省是关闭;修改,e_query_cache,为,true,打开对查询的缓存,并且调用,query.setCacheable(true,),或,criteria.setCacheable(true,),。,SessionFactory,中提供了,evictXXX,(),方法用来清除缓存中的内容。,统计信息打开,generate_statistics,,用,sessionFactory.getSatistics,(),获取统计信息。,39,缓存,分布式缓存和中央缓存。,使用缓存的条件,1.,读取大于修改。,2.,数据量不能超过内存容量。,3.,对数据要有独享的控制。,4.,可以容忍出现无效数据。,40,事务,JDBCTransaction,单个数据库(一个SesisonFactory对应一个数据库),由JDBC实现。,Session session = null;,Transaction tx =null;,try ,session = sessionFactory.openSession();,tx = session.beginTransaction();,/process,mit();, catch(HibernateException e),if(tx != null)tx.rollback();throw e;,finally ,if (session != null)session.close();,connection.setAutoCommit(false);,mit();conn.rollback();,41,事务,JTATransaction,可以简单的理解成跨数据库的事物,由应用JTA 容器实现;使用JTATransaction需要配置hibernate.transaction.factory_class参数,该参数缺省值是org.hibernate.transaction. JDBCTransactionFactory,当使用JTATransaction时需要将该参数改成org.hibernate.transaction.JTATransactionFactory,并配置erTransaction参数JNDI名(Hibernate在启动JTATransaction时要用该值到JNDI的上下文Context中去找erTransaction)。,erTransactin tx = context.lookup(“jndiName”);,try,tx.begin();,/多个数据库的session操作;,/session1.,/session2.,mit();,catch(Exception e),tx.rollback(); throw e;,42,事务,session context,和事务边界,用,current_session_context_class,属性来定义,context,(用,sessionFactory.getCurrentSession,(),来获得,session,),其值为:,1.thread,:,ThreadLocal,来管理,Session,实现多个操作共享一个,Session,,避免反复获取,Session,,并控制事务边界,此时,session,不能调用,close,当,commit,或,rollback,的时候,session,会自动关闭,(,connection.release_mode:after_transaction,),。,Open session in view,:在生成(渲染)页面时保持,session,打开。,2.jta,:由,JTA,事务管理器来管理事务,(,connection.release_mode:after_statement,),。,悲观锁和乐观锁,悲观锁由数据库来实现;乐观锁,hibernate,用,version,和,timestamp,来实现,43,其他问题,hibernate.cfg.xml,和,hbm.xml,内容解释,数据类型,1.,type,可以是,hibernate,、,java,类型或者你自己的类型,(,需要实现,hibernate,的一个接口,),。,2.,基本类型一般不需要在映射文件,(,hbm.xml,),中说明,只有在一个,JAVA,类型和多个数据库数据类型相对应时并且你想要的和,hibernate,缺省映射不一致时,需要在映射文件中指明类型,(,如,:,java.util.Date,数据库,DATE,TIME,DATATIME,TIMESTAMP,,,hibernate,缺省会把,java.util.Date,映射成,DATATIME,型,而如果你想映射成,TIME,,则你必须在映射文件中指定类型,),。,3.,数据类型的对应关系见参考文档,5.2.2,Session,是非线程安全的,生命周期较短,代表一个和数据库的连接,在,B/S,系统中一般不会超过一个请求;内部维护一级缓存和数据库连接,如果,session,长时间打开,会长时间占用内存和数据库连接。,SessionFactory,是线程安全的,一个数据库对应一个,SessionFactory,,生命周期长,一般在整个系统生命周期内有效;,SessionFactory,保存着和数据库连接的相关信息(,user,,,password,,,url,)和映射信息,以及,Hibernate,运行时要用到的一些信息。,44,其他问题,flush,时将一级缓存与数据库同步,大批处理,大量操作数据时可能造成内存溢出,解决办法如下:,1.,清除,session,中的数据,for(int,i=0;i100000;i+)session.save(obj);,for(int,i=0;i100000;i+),session.save(obj,);,if(i,% 50 = 0)session.flush();,session.clear,();,2.,用,StatelessSession,接口:它不和一级缓存、二级缓存交互,也不触发任何事件、监听器、拦截器,通过该接口的操作会立刻发送给数据库,与,JDBC,的功能一样。,StatelessSession,s =,sessionFactory.openStatelessSession,();,该接口的方法与,Session,类似。,3.Query.executeUpdate(),执行批量更新,会清除相关联的类二级缓存,(,sessionFactory.evict(class,),,也可能会造成级联,和乐观锁定出现问题,45,其他问题,HQL,1,查询多个对象,select art, user from Article art, User,user,where,art.author.id,=,user.id,and,art.id,=:id,这种方式返回的是,Object,,,Object0:article,Object1:user,。,2,分页,query.setFirstResult,query.setMaxResults,.,查询记录总数,query.iterate(“select,count(*) from,Person”).next,(),3,批量更新,query.executeUpdate,(),可能造成二级缓存有实效数据。,Criteria,1,排序,Criteria.addOrder(Order.desc(propertyName,);,2,关联查询,criteria.setFetchMode(“propertyName,”,FetchMode.SELECT,),与映射文件中关联关系的,fetch,作用一致。,3,投影,Projections.rowCount(),max(propertyName,),avg,groupProperty,4,分页,Projections.rowCount(),criteria.setFirstResult(),criteria.setMaxResults,(),5DetachedCriteria,可在,session,外创建(在其他层创建比如在,Service,中创建)然后用,getExecutableCriteria(session,),方法创建,Criteria,对象来完成查询。,6Example,查询,Example.create(obj);criteria.add(example,),。,46,其他问题,N+1,次查询和懒加载,1.,用,Query.iterator,可能会有,N+1,次查询。,2.,懒加载时获取关联对象。,3.,如果打开对查询的缓存即使用,list,也可能有,N+1,次查询。,拦截器与事件,拦截器与事件都是,hibernate,的扩展机制,,Interceptor,接口是老的实现机制,现在改成事件监听机制;他们都是,hibernate,的回调接口,,hibernate,在,save,delete,update,等会回调这些类。,SQL,和命名查询,用,Map,代替,Domain,对象;将对象转化为,XML,。,47,Hibernate不适合的场景,不适合,OLAP(On,-Line Analytical Processing,联机分析处理,),,以查询分析数据为主的系统;适合,OLTP,(,on-line transaction processing,联机事务处理)。,对于些关系模型设计不合理的老系统,也不能发挥,hibernate,优势。,数据量巨大,性能要求苛刻的系统,,hibernate,也很难达到要求,批量操作数据的效率也不高。,48,与JPA的集成(annotation方式),需要添加的包,ejb3-persistence.jar, hibernate-,entitymanager.jar, hibernate-,annotations.jar, hibernate-commons-,annotations.jar,jboss-archive-browsing.jar,javassist.jar,配置文件,%CLASSPATH%/META-INF/,persistence.xml,JAVA,代码:,EntityManagerFactory,emf,=,Persistence.createEntityManagerFactory(name,);,/(Name:,在,persistence.xml,中指定。,),EntityManager,em,=,emf.createEntityManager,();,EntityTransaction,tx,=,em.getTransaction,();,Tx.begin,();,Em.persist(entity);/remove,merge,find,Tmit,();,Em.close,();,Emf.close,();,49,最佳实践,见,hibernate,参考文档,50,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!