hibernat基础教程-第三讲 Hibernate框架.ppt_第1页
hibernat基础教程-第三讲 Hibernate框架.ppt_第2页
hibernat基础教程-第三讲 Hibernate框架.ppt_第3页
hibernat基础教程-第三讲 Hibernate框架.ppt_第4页
hibernat基础教程-第三讲 Hibernate框架.ppt_第5页
已阅读5页,还剩173页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Hibernate-对象/关系映射,第三讲Hibernate框架,要求:熟悉Java、SQL、JDBC,掌握面向对象的开发方法。课程目标:理解O/RMapping原理,掌握Hibernate开发的相关知识,并能使用Hibernate进行实际项目开发。,一、要求与目标,模型不匹配(阻抗不匹配)Java面向对象语言,对象模型,其主要概念有:继承、关联、多态等;数据库是关系模型,其主要概念有:表、主键、外键等。解决办法1、使用JDBC手工转换。2、使用ORM(ObjectRelationMapping对象关系映射)框架来解决,主流的ORM框架有Hibernate、TopLink、OJB。,二、引入,三、O/RMapping介绍,ORM的全称是Object/RelationMapping,即对象/关系映射。ORM也可理解是一种规范,具体的ORM框架可作为应用程序和数据库的桥梁。面向对象程序设计语言与关系数据库发展不同步时,需要一种中间解决方案,ORM框架就是这样的解决方案。ORM并不是一种具体的产品,而是一类框架的总称,它概述了这类框架的基本特征:完成面向对象的程序设计语言到关系数据库的映射。基于ORM框架完成映射后,既可利用面向对象程序设计语言的简单易用性,又可利用关系数据库的技术优势。目前ORM的产品非常多,比如Apache组织下的OJB,Oracle的TopLink,JDO,JPA等等。,对象-关系映射是一门非常实用的工程技术,它实现了Java应用中的对象到关系数据库中的表的自动的(和透明的)持久化,使用元数据(metadata)描述对象与数据库间的映射。,O/RMapping的优点提高生产效率可维护性更好性能厂商独立性,四、O/RMapping的优点,五、目前流行的ORM持久层可选方案,六、为什么要选择Hibernate,Hibernate能在众多的ORM框架中脱颖而出,因为Hibernate与其他ORM框架对比具有如下优势:1、开源和免费的License,方便需要时研究源代码、改写源代码、进行功能定制。2、轻量级封装,避免引入过多复杂的问题,调试容易,可减轻程序员负担。3、具有可扩展性,API开放。功能不够用时,可自己编码进行扩展。4、开发者活跃,产品有稳定的发展保障。Hibernate的工作方式灵巧的设计,出色的性能表现,七、Hibernate概述,Hibernate是一个免费的开源Java包,是目前最流行的ORM框架,它是一个面向Java环境的对象/关系数据库映射工具。也是一个轻量级的O/RMapping框架,它问世的时间并不长,但已经成为目前最流行的持久层解决方案。它使得程序与数据库的交互变得十分容易,更加符合面向对象的设计思想,像数据库中包含普通Java对象一样,而不必考虑如何把它们从数据库表中取出。使开发者可以专注于应用程序的对象和功能,而不必关心如何保存它们或查找这些对象。甚至在对SQL语句完全不了解的情况下,使用hibernate仍然可以开发出优秀的包含数据库访问的应用程序。,八、持久化层含义,基于B/S的典型三层架构,访问数据库代码(Dao)与业务逻辑(Service)混杂在一起带来了很多问题,这样的程序设计严重限制了程序的可扩展性和适应性,所以有必要要把涉及数据库操作的代码分离出来与业务逻辑分离。就形成了所谓“持久化层”的概念。持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。,八、持久化层含义,九、ORM工具实现持久化示意图,如何进行对象关系数据库的匹配,publicclassUserprivateStringname;privateStringpassword;privateStringaddress;createtablet_user(namevarchar(255)notnull,passwordvarchar(255),.primarykey(name),如何进行对象关系数据库的匹配?,十、Hibernate入门,Hibernate概述Hibernate是非常优秀、成熟的O/RMapping框架。它提供了强大的对象和关系数据库映射以及查询功能。Hibernate优势开源(LGPL)成熟流行自定义API提高开发者工作效率,十一、下载Hibernate,下载地址,本教程使用3.2.5。将下载目录/hibernate3.jar和/lib下的hibernate运行时必须的包加入classpath中:antlr.jar,cglib.jar,asm.jar,commons-collections.jar,commons-logging.jar,jta.jar,dom4j.jar,十二、Hibernate工作原理,1.读取并解析配置文件2.读取并解析映射信息,创建SessionFactory3.打开Sesssion4.创建事务Transation5.持久化操作6.提交事务7.关闭Session8.关闭SesstionFactory,启动Hibernate构建Configuration实例,初始化该实例中的所有变量Configurationcfg=newConfiguration().configure();加载hibernate.cfg.xml文件至该实例内存通过hibernate.xfg.xml文件中的mapping节点配置,加载hbm.xml文件至该实例内存利用上面创建的Configuration实例构建一个SessionFactory实例SessionFactorysf=cfg.buildSessionFactory();由上面得到的SessionFactory实例创建连接Sessions=sf.openSession();由上面得到的Session实例创建事务操作接口Transaction的一个实例txTransactiontx=s.beginTransaction();通过Session接口提供的各种方法操作数据库的访问提交数据库的操作结果mit();关闭Session链接s.close();,十二、Hibernate工作原理,开始,启动hibernate,构建configuration实例,初始化该实例中的所有变量,加载hibernate.cfg.xml文件至该实例(内存),通过hibernate.cfg.xml文件中的mapping节点配置加载*.hbm.xml至该实例(内存),利用configuration实例创建一个工厂类SessionFactory实例,SessionFactory类创建连接,SessionFactory实例创建事务接口,通过session接口提供的各种方法操纵数据库,提交数据库事务,关闭session,十二、Hibernate工作原理,十三、Hibernate开发步骤,一、持久化类的设计二、持久化类和关系数据库的映射三、应用的开发,十四、持久化Java类必须遵循的原则,1、为类的持久化类字段申明访问方法(get/set)。Hibernate对JavaBeans风格的属性实行持久化。2、实现一个默认的构造方法(constructor)。这样的话Hibernate就可以使用Constructor.newInstance()来实例化它们。3、如果是集合类型的属性,它的类型必须定义为集合的接口。例如:List、Set。4、提供一个标识属性(identifierproperty)。如果没有该属性,一些功能不起作用,比如:级联更新(Cascadedupdates)Session.saveOrUpdate()。,一、建立数据库和表数据库名main表名和结构如下:表名:stuIntid;varcharxm;varcharsex;Datesr;,十五、Hibernate简单实例,二、导入hibernate包导入数据库包,十五、Hibernate简单实例,十五、Hibernate简单实例,三、建立持久化类,;importjava.util.Date;publicclassStuprivateIntegerid;privateStringxm;privateStringsex;privateDatesr;publicIntegergetId()returnid;publicvoidsetId(Integerid)this.id=id;publicStringgetXm()returnxm;,publicvoidsetXm(Stringxm)this.xm=xm;publicStringgetSex()returnsex;publicvoidsetSex(Stringsex)this.sex=sex;publicDategetSr()returnsr;publicvoidsetSr(Datesr)this.sr=sr;,十五、Hibernate简单实例,四、建立持久化类映射文件*.hbm.xml如Stu.hbm.xml,五、在SRC目录下配置hibernate.cfg.xml文件,十五、Hibernate简单实例,org.hibernate.dialect.MySQLDialectjdbc:mysql:/localhost:3306/testrootrootcom.mysql.jdbc.Driversunli,jdbc:mysql:/localhost:3306/main?useUnicode=truecharacterEncoding=gbk,乱码的解决,六、建立操作类StuDao.java,;importjava.util.List;importorg.hibernate.Hibernate;importorg.hibernate.Query;importorg.hibernate.Session;importorg.hibernate.SessionFactory;importorg.hibernate.Transaction;importorg.hibernate.cfg.Configuration;publicclassStuDAOpublicvoidadd(Stuu)Configurationcfg=newConfiguration();cfg.configure();SessionFactorysf=cfg.buildSessionFactory();Sessions=sf.openSession();Transactiontx=s.beginTransaction();s.save(u);mit();,十五、Hibernate简单实例,七、调用实例化类操作数据库,二十一、综合举例,9、页面中调用实现类findbyid.htm,请输入你要查找学生的学号,二十一、综合举例,9、页面中调用实现类findbyid.jsp,二十一、综合举例,9、页面中修改记录update1.jsp(步骤一),修改);out.print();%,二十一、综合举例,9、页面中修改记录update2.jsp(步骤二),二十一、综合举例,学号:readonly/姓名:/性别:/学号:/,9、页面中修改记录update3.jsp(步骤三),二十一、综合举例,二十二、缓存,缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。一级缓存,Session级共享save,update,saveOrUpdate,load,get,list,iterate,lock这些方法都会将对象放在一级缓存中,一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict,clear方法清除缓存中的内容。,二级缓存,SessionFactory级共享实现为可插拔,可以通过实现CacheProvider和Cache接口来加入Hibernate不支持的缓存实现。,二十二、缓存,使用EhCache配置二级缓存1、加入ehcache-1.2.3.jar(已在hibernate包中)到当前项目的lib下。2、在hibernate.cfg.xml文件中加入EhCache缓存插件的提供类。3、拷贝Hibernate安装目录的etc下ehcache.xml文件到src目录中。,true*指定二级缓存产品的提供商;org.hibernate.cache.ehcacheprovider,二十三、Hibernate中对象的状态,瞬时对象(TransientObjects)(临时状态):使用new操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的状态将会丢失,并由垃圾回收机制回收。持久对象(PersistObjects):持久实例是任何具有数据库标识的实例。它由持久化管理器Session统一管理,持久实例是在事务中进行操作的它们的状态在事务结束时会和数据库进行同步。当事务提交时,通过执行SQL的INSERT、UPDATE和DELETE语句把内存中的状态同步到数据库中。离线对象(DetachedObjects)(脱管状态):Session关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,它们不再受Hibernate管理。,实例的状态,一个持久化类的实例可能处于三种不同状态中的某一种。这三种状态的定义则与所谓的持久化上下文(persistencecontext)有关。Hibernate的Session对象就是这个所谓的持久化上下文:临时状态:不曾进行持久化,未与任何Session相关联持久化状态:仅与一个Session相关联游离状态:已经进行过持久化,但当前未与任何Session相关联,二十四、Hibernate查询,概述:数据查询与检索是Hibernate中的一个亮点。相对其他ORM实现而言,Hibernate提供了灵活多样的查询机制。1、HQL(HibernateQueryLanguage)使用session.createQuery(hql)面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写);HQL中查的是对象而不是和表,并且支持多态;HQL主要通过Query来操作,Query的创建方式:Queryq=session.createQuery(hql);fromPersonfromU=:namefromU=:nameanduser.birthday=、!=、like等。逻辑运算符and、or、not等。in、notin、between、isnull、isnotnull、isempty、isnotempty、memberof和notmemberof等。,用orderby子句排序,查询返回的列表(list)可以根据类或组件属性的任何属性进行排序,例如:fromP,p.age还可使用asc或desc关键字指定升序或降序的排序规则,例如:fromPasc,p.agedesc如果没有指定排序规则,默认采用升序规则。即是否使用asc关键字是没有区别的,加asc是升序排序,不加asc也是升序排序。,用groupby子句分组,返回聚集值的查询可以对持久化类或组件属性的属性进行分组,分组所使用的groupby子句。看下面的HQL查询语句:Stringhql=“selectp.age,sum(p.age),count(p.id)fromPersonaspgroupbyp.age”,24.2条件查询Criteria接口,HQL极为强大,但是有些人希望能够动态的使用一种面向对象API创建查询,而非在Java代码中嵌入字符串。对于那部分人来说,Hibernate提供了直观的Criteria查询API,QueryByCriteria简称QBC。表示特定持久类的查询Criteriacriteria=session.createCriteria(Person.class);criteria.setMaxResults(50);ListpersonList=criteria.list();,添加查询条件,一个单独的查询条件是org.hibernate.criterion.Criterion接口的一个实例。Hibernate提供了一个工具类-org.hibernate.criterion.Restrictions(rstrkn),它定义了获得某些内置Criterion类型的工厂方法,来构造Restrictions对象,如:/添加查询条件Criteriacriteria=session.createCriteria(Person.class);criteria.add(Restrictions.like(name,李%);criteria.add(Restrictions.between(age,18,24);ListpersonList=criteria.list();,Restrictions.gtRestrictions.geRestrictions.ltRestrictions.leRestrictions.betweenBETWEENRestrictions.likeLIKERestrictions.ininRestrictions.andandRestrictions.ororRestrictions.sqlRestriction用SQL限定查询,Restrictions用法,结果集排序,使用org.hibernate.criterion.Order来为查询结果排序。Order类同样提供了工厂方法来构建,另一种方式是通过Property类构建,如下代码两种方式都提供了:/工厂方法来构建Order类Criteriacriteria2=session.createCriteria(Person.class);criteria2.add(Restrictions.like(name,李%);criteria2.addOrder(Order.asc(name);criteria2.addOrder(Order.desc(age);criteria2.setMaxResults(10);ListpersonList=criteria2.list();/Property类构建Order类Criteriacriteria2=session.createCriteria(Person.class);criteria2.add(Property.forName(name).like(李%);criteria2.addOrder(Property.forName(name).asc();criteria2.addOrder(Property.forName(age).desc();ListpersonList=criteria2.setMaxResults(10).list();,样例查询,样例查询顾名思义就是一个一个样例作为条件,把与这个样例有相同属性的实例查询出来。Hibernate提供了org.hibernate.criterion.Example类,允许用户通过一个给定实例来构建一个条件查询。如下代码,构造一个person实例作为查询条件,此时id、age和sex被忽略。默认情况下值为null的属性将被排除。Personperson=newPerson();person.setName(李_8);ListpersonList=session.createCriteria(Person.class).add(Example.create(person).list();,24.3直接使用SQL,Hibernate还支持使用SQL查询,使用SQL查询可以利用某些数据库的特性,或者用于将原有的JDBC应用迁移到Hibernate应用上。使用命名的SQL查询还可以将SQL语句放在配置文件中配置,从而提高程序的解耦,命名SQL查询还可以用于调用存储过程。如果是一个新的应用,通常不要使用SQL查询。,24.3使用SQL查询,SQL查询是通过SQLQuery接口来表示的,SQLQuery接口是Query接口的子接口,因此完全可以调用Query接口的方法:setFirstResult(),设置返回结果集的起始点。setMaxResults(),设置查询获取的最大记录数。list(),返回查询到的结果集。但SQLQuery比Query多了两个重载的方法:addEntity,将查询到的记录与特定的实体关联。addScalar,将查询的记录关联成标量值。,ListpersonList=session.createSQLQuery(SELECT*FROMPerson).addEntity(Person.class).list();ListobjsList=session.createSQLQuery(SELECT*FROMperson).addScalar(id,Hibernate.INTEGER).addScalar(age,Hibernate.INTEGER).list();Objecto=(Object)objsList.get(0);System.out.println(o1);,1.increment:用途:适用于int,short,long类型的主键,每次主键自增1缺点:并发操作数据库时,多个实例各自维护自己的主键状态,会发生冲突2.identity:用途:适用于内部支持标识字段的数据库(db2,mysql,sybase,mssql)3.sequence:用途:适用于内部支持序列的数据库(db2,oracle,postgre)用法:必须在数据库中先创建一个序列,并且在hibernate配置文件中对param进行配置4.hilo:用途:通过hi/lo算法来生成主键缺点:当使用数据库连接池时,不可以使用,因为检索hi值的sql语句必须在一个独立的事务中完成,因此生成器必须获得新的connection5.native:用途:根据使用的数据库自行判断使用identity,sequence,hi/lo,二十五Hibernate主键生成策略,二十六复杂的映射-关联关系映射,Hibernate中的关联映射主要有3种:一对一关联(one-to-one)一对多(或多对一)关联(many-to-one)多对多关联。(many-to-many)每种关联都可以分为单向和双向两种。关联关系映射通常情况是最难配置正确的。在这个部分中,将从单向关系映射开始,然后考虑双向关系映射。,26.1一对一(onetoone),一对一的关联分为主键关联和外键关联。(1)主键关联(共享主键方式):基于主键关联的单向一对一关联通常使用一个特定的id生成器。这里的关联关系是定义在类的映射文件中,在辅表的one-to-one的属性里要constrained=“true”表示受到约束。(2)外键关联:基于外键关联的单向一对一关联和单向多对一关联几乎是一样的。唯一的不同就是单向一对一关联中的外键字段具有唯一性约束。,(1)主键关联(共享主键方式),一、共享主键方式在注册某个论坛会员的时候,往往不但要填写登录账号和密码,还要填写其他的详细信息,这两部分信息通常会放在不同的表中,如表4.1、表4.2所示。,表4.1详细信息表Detail,表4.2登录表Login,例1、登录表和详细信息表属于典型的一对一关联关系,可按共享主键方式进行。步骤如下:1、建立web项目2、导入数据库包和hibernate包3、编写持久化类4、编写生成数据库表对应的Java类对象和映射文件。Detail表对应的Detail.java:,(1)主键关联(共享主键方式),;publicclassDetailimplementsjava.io.Serializableprivateintid;/ID号privateStringtrueName;/真实姓名privateStringemail;/电子邮件privateLoginlogin;/登录信息/省略上述各属性的getter和setter方法,Login表对应的POJO类Login.java:,(1)主键关联(共享主键方式),;publicclassLoginimplementsjava.io.Serializableprivateintid;/ID号privateStringusername;/登录账号privateStringpassword;/密码privateDetaildetail;/详细信息/省略上述各属性的getter和setter方法,Detail表与Detail类的ORM映射文Detail.hbm.xml:,name表示属性名字,class表示被关联的类的名字cascade=“all”表明主控类的所有操作,对关联类也执行同样操作lazy=false表示此关联为立即加载,(1)主键关联(共享主键方式),Login表与Login类的ORM映射文Login.hbm.xml。,detail,(1)主键关联(共享主键方式),5、在hibernate.cfg.xml文件中加入配置映射文件的语句。,Sessionsession=HibernateSessionFactory.getSession()Transactionts=session.beginTransaction();/创建事务对象Detaildetail=newDetail();Loginlogin=newLogin();login.setUsername(yanhong);login.setPassword(123);detail.setTrueName(严红);detail.setEmail(yanhong);/相互设置关联login.setDetail(detail);detail.setLogin(login);/这样完成后就可以通过Session对象调用session.save(detail)来持久化该对象session.save(detail);mit();HibernateSessionFactory.closeSession();,(1)主键关联(共享主键方式),6、测试,7、运行程序,测试结果。插入数据后,Login表和Detail表的内容如图4.12、图4.13所示。,图4.12Login表图4.13Detail表,(1)主键关联(共享主键方式),二、唯一外键关联唯一外键的情况很多,例如,每个人对应一个房间。其实在很多情况下,可以是几个人住在同一个房间里面,就是多对一的关系。但是如果把这个多变成唯一,也就是说让一个人住一个房间,就变成了一对一的关系了,这就是前面说的一对一的关系其实是多对一关联关系的一种特殊情况。对应的Person表和Room表如表4.3、表4.4所示。,表4.3Person表,表4.4Room表,(2)唯一外键方式,例2、外键关联1、在项目的包下编写生成数据库表对应的Java类对象和映射文件。,Person表对应的POJO类Person.java:;publicclassPersonimplementsjava.io.SerializableprivateIntegerid;privateStringname;privateRoomroom;/省略上述各属性的getter和setter方法Room表对应的POJO类Room.java:;publicclassRoomimplementsjava.io.Serializableprivateintid;privateStringaddress;privatePersonperson;/省略上述各属性的getter和setter方法,(2)唯一外键方式,Person表与Person类的ORM映射文件Person.hbm.xml:,/唯一性约束,实现一对一,(2)唯一外键方式,Person.hbm.xml,Room表与Room类的ORM映射文件Room.hbm.xml:,/指定关联类的属性名,本对象关联查询相关对象时的条件,(2)唯一外键方式,Room.hbm.xml,2、在hibernate.cfg.xml文件中加入如下的配置映射文件的语句。,Personperson=newPerson();person.setName(liumin);Roomroom=newRoom();room.setAddress(NJ-S1-328);person.setRoom(room);session.save(person);,(2)唯一外键方式,3、编写测试。,4、运行程序,测试结果。因为该程序为JavaApplication,所以可以直接运行。在完全没有操作数据库的情况下,程序就完成了对数据的插入。插入数据后,Person表和Room表的内容如图4.14、图4.15所示。,图4.14Person表图4.15Room表,(2)唯一外键方式,26.2多对一单向关联,例3、把上面例2中的一对一的唯一外键关联实例稍微修改就可以变成多对一。1、Person表对应的类也不变。,;publicclassPersonimplementsjava.io.SerializableprivateIntegerid;privateStringname;privateRoomroom;/省略上述各属性的getter和setter方法,2、对应的Person.hbm.xml文件修改如下:,/主控类所有操作,对关联类也执行同样操作去掉:unique=“true”属性,4、Room表与Room类的ORM映射文件Room.hbm.xml如下:,;publicclassRoomimplementsjava.io.Serializableprivateintid;privateStringaddress;/省略上述各属性的getter和setter方法,26.2多对一单向关联,3、而Room表不变,对应的POJO类如下:,5、编写测试代码。,Roomroom=newRoom();room.setAddress(NJ-S1-328);Personperson=newPerson();person.setName(liuyanmin);person.setRoom(room);session.save(person);,26.2多对一单向关联,6、运行程序,测试结果。插入数据后,Person表和Room表的内容如图4.16、图4.17所示。,图4.16Person表图4.17Room表,26.2多对一单向关联,26.3一对多双向关联,例4下面通过修改例3来完成双向多对一的实现。步骤如下:1、Person表对应的POJO不用改变;publicclassPersonimplementsjava.io.SerializableprivateIntegerid;privateStringname;privateRoomroom;/省略上述各属性的getter和setter方法,2、Person类对应的Person.hbm.xml文件不改变,/主控类所有操作,对关联类也执行同样操作,26.3一对多双向关联,3、现在来修改Room表对应的POJO类改变,packageorg.model;importjava.util.HashSet;importjava.util.Set;publicclassRoomprivateintid;privateStringaddress;privateSetperson=newHashSet();/集合,存放多个Person对象/省略getter和setter方法,26.3一对多双向关联,26.3一对多双向关联,4、Room类的ORM映射文件Room.hbm.xml修改。,/级联程度/充当外键的字段名/被关联的类名字,表示关联关系的维护工作由谁来负责,默认false,表示由主控方负责;true表示由被控方负责。由于该例是双向操作,故需要设为false,也可不写,26.3一对多双向关联,该配置文件中cascade配置的是级联程度,它有以下几种取值:,all:表示所有操作句在关联层级上进行连锁操作。save-update:表示只有save和update操作进行连锁操作。delete:表示只有delete操作进行连锁操作。all-delete-orphan:在删除当前持久化对象时,它相当于delete;在保存或更新当前持久化对象时,它相当于save-update。另外它还可以删除与当前持久化对象断开关联关系的其他持久化对象。,26.3一对多双向关联,5、编写测试代码。,Personperson1=newPerson();Personperson2=newPerson();Roomroom=newRoom();room.setAddress(NJ-S1-328);person1.setName(李方方);person2.setName(王艳);person1.setRoom(room);person2.setRoom(room);/这样完成后就可以通过Session对象/调用session.save(person1)和session.save(person)/会自动保存roomsession.save(person1);session.save(person2);,26.3一对多双向关联,6、运行程序,测试结果。因为该程序为JavaApplication,所以可以直接运行。在完全没有操作数据库的情况下,程序就完成了对数据的插入。插入数据后,Person表和Room表的内容如图4.18、图4.19所示。,图4.18Person表图4.19Room表,26.3一对多双向关联,思考:由于是双向的,可以从Room的一方来保存Person,代码如下:,.Personperson1=newPerson();Personperson2=newPerson();Roomroom=newRoom();person1.setName(李方方);person2.setName(王艳);Setpersons=newHashSet();persons.add(person1);persons.add(person2);room.setAddress(NJ-S1-328);room.setPerson(persons);/这样完成后,就可以通过Session对象/调用session.save(room)/会自动保存person1和person2.,26.3一对多双向关联,运行程序,插入数据后,Person表和Room表的内容如图4.20、图4.21所示。,图4.20Person表图4.21Room表,26.4多对多关联,一、多对多单向关联学生和课程就是多对多的关系,一个学生可以选择多门课程,而一门课程又可以被多个学生选择。多对多关系在关系数据库中不能直接实现,还必须依赖一张连接表。如表4.6、表4.7和表4.8所示。,表4.6学生表student,表4.7课程表course,表4.8连接表stu_cour,26.4多对多关联,例5、由于是单向的,也就是说从一方可以知道另一方,反之不行。这里以从学生知道选择了哪些课程为例实现多对多单向关联。步骤如下:1、在项目的包下编写生成数据库表对应的Java类对象和映射文件。student表对应的POJO类如下:,;importjava.util.HashSet;importjava.util.Set;publicclassStudentimplementsjava.io.Serializableprivateintid;privateStringsnumber;privateStringsname;privateintsage;privateSetcourses=newHashSet();/省略上述各属性的getter和setter方法,2、Student类的ORM映射文件Student.hbm.xml,26.4多对多关联,26.4多对多关联,3、course表对应的POJO类如下:,;publicclassCourseimplementsjava.io.Serializableprivateintid;privateStringcnumber;privateStringcname;/省略上述各属性的getter和setter方法。,26.4多对多关联,4、Course类的ORM映射文件Course.hbm.xml,5、在hibernate.cfg.xml文件中加入如下的配置映射文件的语句,26.4多对多关联,6、编写测试代码,Coursecour1=newCourse();Coursecour2=newCourse();Coursecour3=newCourse();cour1.setCnumber(101);cour1.setCname(计算机基础);cour2.setCnumber(102);cour2.setCname(数据库原理);cour3.setCnumber(103);cour3.setCname(计算机原理);Setcourses=newHashSet();courses.add(cour1);courses.add(cour2);courses.add(cour3);Studentstu=newStudent();stu.setSnumber(081101);stu.setSname(李方方);stu.setSage(21);stu.setCourses(courses);session.save(stu);,26.4多对多关联,7、运行程序,测试结果。因为该程序为JavaApplication,所以可以直接运行。在完全没有操作数据库的情况下,程序就完成了对数据的插入。插入数据后,student表、course表及连接表stu_cour表的内容如图4.22、图4.23、图4.24所示。,图4.22student表,图4.23course表图4.24stu_cour表,例6单向多对多查询,Configurationcfg=newConfiguration();cfg.configure();SessionFactorysf=cfg.buildSessionFactory();Sessions=sf.openSession();ArrayLista=(ArrayList)(s.createQuery(fromStudentasswheres.id=2).list();for(inti=0;i);out.println(coursecount=+st.getCourses().size()+);Iteratoritr=st.getCourses().iterator();while(itr.hasNext()Coursec=(Course)itr.next();out.println(c.getCname()+);,26.4多对多关联,26.4多对多关联,二、多对多双向关联例6、首先将其Course表所对应的POJO对象修改成如下代码:,;importjava.util.HashSet;importjava.util.Set;publicclassCourseimplementsjava.io.Serializableprivateintid;privateStringcnumber;privateStringcname;privateSetstus=newHashSet();/省略上述各属性的getter和setter方法,26.4多对多关联,2、多对多双向关联Course表与Course类的ORM映射文件C

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论