版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Hibernate简介 培训讲师: 张永军 Hibernate的作用处理ORM问题成为ORM第一首选通常用于设计Dao层极大的简化了数据库访问代码良好的数据库可移植性无侵入式的设计,无污染Hibernate在运用程序中的位置JDBCBusiness Classes关系数据库Data Classes耐久层组件Hibernate过程及原理设计实体类(POJO)经过注解或者xml文件定义实体类和数据库表的映射关系Hibernate框架根据映射关系定义和数据库配置动态生成SQL语句,经过JDBC来执行SQL语句原理表示Studentt_studentStudent.hbm.xmlsession.sav
2、e(student)Hibernate任务流程:根据类型找到映射文件读取映射关系根据映射关系生成insert语句用student对象的属性值作为Sql参数值创建运转PreparedStatement.executeUpdate方法编写第一个Hibernate程序Step1:导入Hiernate jar包Step2:导入jdbc驱动jar包Step3:编写Hibernate配置文件从官方例如程序中拷贝模板文件设置数据库相关配置定义自动生成数据库表定义运转时显示SQL语句指定映射文件createtruetrue编写第一个Hibernate程序编写实体类UseruserId,name,birthDa
3、te编写实体映射文件User.hbm.xml必需位于classpath下主键的生成方式处置日期类型映射文件详解编写测试程序初始化配置获取SessionFactory对象并翻开Session经过事务插入User对象封锁Session编写第一个Hibernate程序编写工具类HibernateSessionUtil完成Session获取封锁任务经过MyEclipse自动生成HibernateSessionFactory类分析HibernateSessionFactory类编写第一个Hibernate程序从数据库中获得某个user对象:Session.get方法对该user对象进展修正Session
4、.update方法删除user对象。Session.delete方法update方法 vs saveOrUpdate方法实体生命周期实体对象的生命周期有三种形状:Transient(自在形状)实体对象在内在中自在存在,它与数据库中的记录无关联,只是一个普通的Persistent (耐久形状)实体对象处于由Hibernate所管理的形状,实体和数据库中的记录有关联,其变卦将由Hibernate固化到数据库中。Detached (游离形状)处于Persistent形状的对象,其对应的Session实例封锁之后,那么,此对象就处于Detached形状。Detached形状和Transient形状的区
5、别在于Detached形状的对象可以再次与某个Session实例相关联而成为Persistent对象。实体形状转换User user=new User();user.setName(“John);Transaction tx=session.beginTransaction();session.save(user);txmit();session.close();Transaction tx2=session2.beginTransaction();session2.update(user);user.setName(“Jonh_2);tx2mit();1. 此时user对象处于Transie
6、nt形状。2. 此时user对象曾经由Hibernate纳入管理容器,处于Persistent形状。3. User对象此时形状为Detached,由于与其关联的session曾经封锁。4. 此时处于Detached形状的user对象再次借助session2由Hibernate纳入管理容器,恢复Persistent形状。5. 由于user对象再次处于Persistent形状,因此其属性的改动将由Hibernate自动固化到数据库中。实体生命周期例如图save()saveOrUpdate()newgarbagedelete()TransientPersistentDetachedgetloadit
7、erateetc.close() *clear() *evict() updatesaveOrUpdatelockgarbage* 对session里的一切实体对象都有效VO和PO从实体对象能否被纳入Hibernate实体管理容器的角度,Transient和Detached形状的实体对象可以统称为VOValue Object,而被管理的实体对象称为POPersistent Object。两者的区别: 1.VO是相对独立的实体对象,处于非管理形状。 2.PO是Hibernate纳入其实体管理容器Entity Map的对象,它代表了与数据库中某条记录对应的Hibernate实体,PO的变化在事务提
8、交时将反映到实践数据库中。 3.假设一个PO与其对应的Session实例分别,那么此时,它又会变成一个VO。映射文件初探-主键映射 (4) (5)(1)、name (可选) :标识属性的称号。(2)、type(可选):标识Hibernate类型的名字。(3)、column(可选默以为属性名):对应数据库表的主键字段的名字。(4)、unsaved-value(可选默以为null):这个值用来判别对象能否要保管。(5)、主键生成方式。 主键生成战略assigned主键由运用逻辑产生,数据交由Hibernate保管时,主键值曾经设置完成,无需Hibernate干涉。hilo经过hi/lo算法实现的主
9、键生成机制,需求额外的数据库表保管主键生成历史形状seqhilo与hilo类似,经过hilo算法实现主键生成机制,只是主键历史形状保管在Sequence中,适用于支持Sequence的数据库,如Oracle。increment主键按数值顺序递增。identity采用数据库提供的主键生成机制,如SQL Server,MySQL中的自增长主键生成机制主键生成战略续sequence采用数据库提供的sequence机制生成主键,如Oracle Sequencenative由Hibernate根据数据库适配器中的定义,自动采用identity、hilo、sequence的其中一种作为主键生成方式uuid
10、.hex由Hibernate基于128位独一值产生算法,根据当前设备IP,时间,JVM启动时间,内部自增量等4个参数生成十六进制数值(编码后以长度为32位的字符串表示作为主键。利用uuid.hex方式生成主键将提供最好的数据插入性能和数据库平台顺应性uuid.String与uuid.hex类似,只是生成的主键不进展编码(长度16位)映射文件初探-属性映射(1) Name:指定了映射类中的属性名为 propertyName,此属性将被映射到指定的库表字段。(2) column(可选):指定了库表中对应映射类属性的字段名。(3) type(可选):指定了映射字段的数据类型(4) update, i
11、nsert (可选 - 默以为 true) :阐明在用于UPDATE 和/或 INSERT的SQL语句中能否包含这个字段。 (5) formula (可选): 一个SQL表达式,定义了这个计算computed 属性的值。计算属性没有和它对应的数据库字段。定义1对1关联一对一关联包括两种方式:主键关联独一外键关联1对1主键关联实体定义UseruserId:Integer,birthDay:Date,name:String,passport:PassportPassportpassportId:Integer,serial:String,expiry:Integer,user:User定义1对1关
12、联-主键关联方式一对一主键关联方式即两张关联表经过主键方式一对一映射关系。Hibernate中,经过one-to-one节点对一对一关系进展定义。典型实例:中国公民只允许拥有一份护照。 User.hbm.xmlPassport.hbm.xmluserone-to-one详解1. name: 属性的名字POJO中的。2. class (可选 - 默许是经过反射得到的属性类型):被关联的类的名字。3. cascade(级联) (可选) 阐明操作能否从父对象级联到被关联的对象。4. constrained约束 (可选) 阐明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,经过一个外键
13、援用对主键进展约束。这个选项影响save()和delete()在级联执行时的先后顺序也在schema export tool中被运用。 one-to-one详解5. outer-join外衔接 (可选 - 默以为 自动): 当设置hibernate.use_outer_join的时候,对这个关联允许外衔接抓取。6. property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。假设没有指定,会运用对方关联类的主键POJO中POJO类的实例。7. access (可选 - 默许是 property): Hibernate用来访问属性的战略 one-to-one例如代码对
14、关联对象的保管:User user=new User();user.setAge(new Integer(20);user.setName(“张小小);Passport passport=new Passport ();passport.setSerial(“PDR1234567);passport.setExpiry(new Integer(20210101);/相互设置关联passport.setUser(user);user.setPassport(passport);Transaction tx=session.beginTransaction();session.save(user)
15、txmit();主键关联思索能否可以不设置双向关联,假设不设置双向关联,本案例如何设置?constrained含义是什么?通常设置在哪一方?1对1关联-独一外键关联实体定义UseruserId:Integer,birthDay:Date,name:String,group:GroupGroupgroupId:Integer,name:String,desc:String定义1对1关联-独一外键关联方式.1对1关联-独一外键关联方式思索:此种方式下保管顺序对程序有关系吗?背后的原理是什么?和前一种1对1关系的区别在哪里?什么时候采用关联主键,什么时候采用外键关联多对一关联在某个实体中存在一个属性
16、,该属性是另外一个实体类型。多个当前实体对应了一个对方一个实体例如,一个用户有多个房屋Houseid:Integer,address:String,user:User多对一关联House.hbm.xml多对一关联-抓取战略及lazyfetch=join|selectlazy=proxy|no-proxy|false一对多关联一对多关联在系统实现中运用得非常广泛。比如:每个用户关联到多个地址。一对多关联包括两种方式:单向一对多关联双向一对多关联单向一对多关联只需在方进展配置,双向一对多需求关联双方均加以配置。单向1对多User.hbm.xml单向1对多例如为已有用户添加地址对象Transacti
17、on tx=session.beginTransaction();Address addr=new Address();addr.setTel(“86028888);addr.sestZipcode(“517099);addr.setAddress(“ShenZhen);user.getAddresses().add(addr);session.save(user);txmit();双向一对多关联双向一对多关联,实践上是一对多和多对一关联的组合。必需在主控方配置单向一对多关系的根底上,在被控方配置与其对应的多对一关系User.hbm.xml.Address.hbm.xml双向关联例如代码维护关
18、系Transaction tx=session.beginTransaction();Address addr=new Address();addr.setTel(“86028888);addr.sestZipcode(“517099);addr.setAddress(“ShenZhen);addr.setUser(user);user.getAddresses().add(addr);session.save(user);txmit();问题:为什么User.hbm.xml文件里的inverse设置成true?多对多关联由于引入了中间表,一次读取操作需求反复数次查询,多对多关联的性能不佳,设
19、计时应该尽量防止大量运用。在一个权限管理系统中,一个常见的多对多的映射关系是Role与Privilege之间的映射:Role代表角色(如:会计、出纳)Privilege代表某个特定资源的访问特权(如修正财务报表,查询财务报表)一个Role可以有多种Privilege,一个Privilege可同时属于多个RoleRole.hbm.xml1. t_role_privilege为t_role和t_privilege之间的映射表2. 普通情况下设为save-update,对于多对多逻辑而言,很少出现删除一方需求删除一切关联另一方一切的数据。3. 映射表中对于t_role表记录的标识字段4. 映射表中对
20、于t_privilege表记录的标识字段Privilege.hbm.xml多对多例如代码保管关系代码:Role role1=new Role();role1.setName(“Role1);Role role2=new Role();role2.setName(“Role2);Privilege privilege1=new Privilege();privilege1.setName(“Privilege1);Privilege privilege2=new Privilege();privilege2.setName(“Privilege2);Privilege1.getRoles().a
21、dd(role1);Privilege1.getRoles().add(role2);Privilege2.getRoles().add(role1);role1.getPrivileges.add(privilege1); role1.getPrivileges.add(privilege2); role2.getPrivileges.add(privilege1); TryTransaction tx = session.beginTransaction();/多对多关系必需同时对关联双方进展保管session.save(role1);session.save(role2);session
22、.save(privilege1);session.save(privilege2);txmit();catch(Exception e)多对多关联总结尽量防止运用多对多,严重影响性能inverse必需一端设置为true,一端设置为false缘由?多对多通常都是双向的Hibernate中的集合List: 用于映射 List 集合属性有序集合Set: 用于映射 Set 集合属性无序集合Map: 用于映射 Map 集合性Array: 用于映射数组集合属性Bag: 用于映射无序集合(且可反复)idbag: 用于映射无序集合,但为集合添加逻辑次序List集合的映射属性类型只能是笼统List类型,可以用
23、详细类型设置属性 主键排序列Set集合的映射无序不可反复 Map映射 bag映射 public Collection getSchools() return schools; public void setSchools(Collection schools) this.schools = schools; 承继映射承继关系是关系型数据与面向对象数据构造之间的主要差别之一。Hibernate支持三种类型的承继关系每个详细类一张表(Table per concrete class)表与子类之间的独立一对一关系每个子类一张表(Table per subclass)每个子类对应一张子表,并与主类共享
24、主表每个类分层构造一张表(Table per class hierarchy)表与类的一对多关系实例场景-类图Productid:Integermanufacturer:Stringname:StringDVDregionCode:StringBookpageCount:int每个详细类一张表数据库表构造t_bookidmanufacturernamepage_countint varchar(50)varchar(50)intt_dvdidmanufacturernameregion_codeint varchar(50)varchar(50)varchar(30)Book.hbm.xmlD
25、VD.hbm.xmlQuery query=session.createQuery(“from example.model.Product);List products=query.list();Hibernate输出SQL: select dvd0_.id as id1_, dvd0_.manufacturer as manufact2_1_, dvd0_.name as name1_, dvd0_.region_code as region4_1_ from t_dvd dvd0_ select book0_.id as id0_, book0_.manufacturer as manuf
26、act2_0_, book0_.name as name0_, book0_.page_count as page4_0_ from t_book book0_Hibernate会自动把t_book与t_dvd表里的内容全部查询出来。查询Product每个子类一张表数据库表构造t_bookidpage_countint intt_dvdidregion_codeint varchar(30)t_productidmanufacturernameint varchar(50)varchar(50)Product.hbm.xmlQuery query =session.createQuery(“f
27、rom example.model.Product);List products=query.list();Hibernate输出SQL:select product0_.id as id0_, product0_.manufacturer as manufact2_0_, product0_.name as name0_, product0_1_.page_count as page2_1_, product0_2_.region_code as region2_2_, case when product0_1_.id is not null then 1 when product0_2_.
28、id is not null then 2 when product0_.id is not null then 0 end as clazz_ from t_product product0_ left outer join t_book product0_1_ on product0_.id=product0_1_.id left outer join t_dvd product0_2_ on product0_.id=product0_2_.idHibernate会自动把t_product、t_book与t_dvd表里的内容全部衔接查询出来。查询Product每个类分层构造一张表数据库表
29、构造t_productidcategorymanufacturernamepage_countregion_codeint varchar(10)varchar(50)varchar(50)intvarchar(30)t_product表不但包括Product的id,name,manufacturter字段,同时还包含了Book的page_count字段、DVD的region_code字段,不同的类型商品经过(category)字段加以区分。1. 经过discriminator节点声明用作子类区分的字段名2. 指定详细子类Book的discriminator值book3. 指定详细子类DVD的
30、discriminator值dvdProduct.hbm.xmlQuery query =session.createQuery(“from example.model.Book);List books=query.list();Hibernate输出SQL:select book0_.id as id0_, book0_.manufacturer as manufact3_0_, book0_.name as name0_, book0_.page_count as page5_0_ from t_product book0_ where book0_.category=bookHibern
31、ate会根据配置自动进展类型识别,把t_product表中category=book的数据(Book) 全部查询出来。查询Book总结每个详细类一张表每个子类一张表每个类分层构造一张表Hibernate延迟加载public void testLazy() User u = session.load(1); /断点查看此时的u / 这一句不会触发数据库查询操作 assertEquals(1, u.getId(); / 访问的是非主键属性,开场查询数据库 assertNotSame(11, u.getName(); /设置断点 查看此时的u session.close(); Hibernate延迟
32、加载在hibernate中,假设运用了延迟加载比如常见的load方法,那么除访问主键以外的其它属性时,就会去访问数据库假设不思索hibernate的一级缓存,此时session是不允许被封锁。默许采用CGLib来生成代理对象来代表一些延迟加载配置实现了集合的延迟加载,只需访问集合项时才加载get()无懒加载特性,马上执行SQL查询;Load()有懒加载特性,会返加一个代理对象,所以永远不为null,先不执行SQL,要取对象的值时才执行SQL语句,前题session不能封锁,标签上lazy不为false实现懒加载的前提:PO不能是final的需求asm,cglib两个jar包相应的lazy属性为
33、true 相应的fetch属性为select 通常集合类型的属性都是延迟加载,有时候需求防止这种行为?如何实现?Hibernate.initialize(foo.getBars)Criteria QueryHibernate查询之一,可以处理多数查讯问题,强类型支持,例如:Criteria c = session.createCriteria(User.class);c.add(Expression.eq(name,张三);c.add(Expression.eq(sex,new Integer(1);c.list();Criteria Query查询表达式深化浅出184页Hibernate 3
34、中用Restrictions交换,建议用后者Example类可以用于复合查询:User u = new User();u.setName(张三);criterial.Add(u);Criteria Query查找一切位于上海的用户Criteria c= session.createCriteria(User.class);Criteria addrC = c.createCriteria(addresses);addrC.add(Express.like(address,%上海%);c.list();DetachedCriteria不需求session的存在需求的时候绑定到session转换为
35、一个CriteriaDetachedCriteria dc = DetachedCriteria.forClass(User.class);Criterial c = dc.getExecuteableCriteria(session);Criteria分页setFirstResult(int index)(index based 1),从哪一条开场setMaxResults(int number),取多少条Criteria汇总统计Projections类的静态方法P191页例如HQL查询类似于SQL,查询的主体是实体Query q = session.createQuery(from Use
36、r);q.list();from User as user where =张三select from User userselect ,user.age from User userselect new User(,user.age) from User userselect count(*),avg(user.age) from User userupdate User set age=18 where id=1from User u order by from User u order by
37、 descHQL查询select count(*),u.age from User u group by u.ageselect count(u),u.age from User u group by u.age having count(u)带参数查询Query q1 = sessiong.create(from User u where u.age? and like ?)q1.setInteger(0,18);q1.setString(1, 张%);Query q2 = sessiong.create(from User u where =:name
38、)q1.setParameter(name,张三);HQL查询带参数查询Query q2 = sessiong.create(from User u where =:name)User u1 = new User();u1.setName(张三);q1.setProperties(u1);命名查询在实体映射文件中定义查询.Query q = session.getNamedQuery(queryByName);join操作userIdName1张三2王小二3李四from User u inner join fetch user.Addressfrom User u left
39、join fetch user.Addressfrom User u right join fetch user.AddressidAddruserId1上海12北京13成都24南京25广州nullinner joinuserIdNameIDAddr1张三1上海1张三2北京2王小二3成都2王小二4南京左和右有对应关系的记录被挑选出来Left joinuserIdNameIDAddr1张三1上海1张三2北京2王小二3成都2王小二4南京3李四nullnull以左边为主体,假设左边有对应的右边,做衔接;否那么右边用空来填充Right joinuserIdNameIDAddr1张三1上海1张三2北京2
40、王小二3成都2王小二4南京nullnull5广州以右边为主体,假设有关联的左边做衔接;假设没有关联的左边,用null填充左边fetch在join中的影响fectch可以出如今left和inner join中from User u inner join fetch user.Addres和from User u inner join user.Addres区别前者用address表中的数据填充对应user的addresses属性,并前往一个user集合;后者那么是一个扁平构造,在结果集合中,每一个项都是一个Object类型;list.get(0)0是一个user,list.get01是一个address前者的结果集合中包含了3个user;而后者包含了5条记录子查询在一个查询中还包含了另外一个查询,例如:from User u where (select count(*) from u.addresses)1SQL查询List cats = session.createSQLQu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 赣南师范大学科技学院《汽车企业管理》2023-2024学年第一学期期末试卷
- 赣州师范高等专科学校《文字学概要》2023-2024学年第一学期期末试卷
- 赣东学院《人才管理》2023-2024学年第一学期期末试卷
- 广西中国舞培训教程课件
- 七年级道德与法治上册第三单元师长情谊第六课师生之间第1课时走近老师教案新人教版
- 三年级科学下册第四单元关心天气4今天刮什么风教案苏教版1
- 《读书考试法》课件
- 小学生语法精讲课件
- 工艺基础培训课件
- 《陈列无声的语言》课件
- 工行人工智能风控
- 简易呼吸器使用及检测评分表
- 康复科进修汇报
- 2024-2030年中国水培蔬菜行业发展分析及投资前景预测研究报告
- 2023风电机组预应力混凝土塔筒与基础结构设计标准
- 3D打印技术在医疗领域的应用
- 人员招聘的程序与信息发布
- 仓库班长年终总结
- 血脂康胶囊的经济学评估
- 组织协调方案及措施
- 2024-2029年中国IP授权行业市场现状分析及竞争格局与投资发展研究报告
评论
0/150
提交评论