Hibernate-PPT整本书课件完整版电子教案全套课件最全教学教程ppt(最新)_第1页
Hibernate-PPT整本书课件完整版电子教案全套课件最全教学教程ppt(最新)_第2页
Hibernate-PPT整本书课件完整版电子教案全套课件最全教学教程ppt(最新)_第3页
Hibernate-PPT整本书课件完整版电子教案全套课件最全教学教程ppt(最新)_第4页
Hibernate-PPT整本书课件完整版电子教案全套课件最全教学教程ppt(最新)_第5页
已阅读5页,还剩693页未读 继续免费阅读

下载本文档

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

文档简介

1、第一章 Hibernate入门 理解Hiberate原理 掌握如何搭建Hibernate开发环境 理解持久化对象的状态与转换 掌握Hibernate的配置 了解Hibernate的常用接口1本章指引1.1 SSH概述1.2 Hibernate简介1.3 第一个HiBernate项目1.4 映射文件详解1.5 配置文件详解1.6 Hibernate持久化对象1.7 Hibernate的核心接口简介1.8 上机实验21.1 SSH概述 3SSH是JavaEE的 spring,struts2,Hibernate三大框架的缩写SpringStructs2HibernateDAO层控制层提高数据库的操作

2、效率控制程序的跳转。使用了MVC原理以及文件上传下载、数据验证、众多功能标签等技术为类与类之间的过度依赖提供解决方案,以及方便地以AOP方式切入系统级业务,并且接管Hibernate的数据库配置,事务管理等,整合了其余两个框架。1.2 Hibernate简介 Hibernate是当前流行的一种ORM(Object Relational Mapping,对象关系映射)框架。所谓ORM就是对象和关系型数据库表之间的一种映射关系,可以自动把应用程序中的对象,持久化到关系型数据库的表中,反之也可把关系型数据库的表中的一条记录读取出来并转化为程序中的一个对象。什么是ORM?有了ORM,JavaEE开发者

3、就可以使用面向对象的编程思想来操作数据库,取代传统的JDBC。通过操作Java对象,就可以完成对数据库表的操作。1.2 Hibernate简介 Hibernate对应三层架构开发中的数据访问层、JDBC访问数据库的代码做了轻量级封,是“全自动”的ORM框架。支持许多面向对象的特性,如组合,继承,多态等,Java开发者可以自由地使用对象编程思维来操纵数据库支持一对多,多对多关联,连接查询,级联操作,缓存等,功能强大可移植性好,可适用于多种数据库是一种开源框架,必要时可以自行编码进行扩展。可以自动生成SQL语句并自动执行不能使用存储过程不太适合大规模的批处理不适合小型项目与MyBatis相比,较为

4、复杂,不易掌握。使用面向对象的HQL查询语言,有些人使用起来不太习惯。特点缺点1.2 Hibernate简介 /projects/hibernate/files/hibernate3/点击图1.2中的3.6.10.Final链接下载其中的hibernate-distribution-3.6.10.Final-dist.zip压缩包解压后文件结构如图1.4所示下载Hiberante 1.2 Hibernate简介 Hiberante项目必须的jar包 log4j-1.2.17.jar和slf4j-log4j12-1.7.12.jar这2个jar包用于整合Hibernate的日志系统log4j(这

5、两个jar包需要另外上网搜索下载)1.3 第一个Hibernate项目 1.3.1 创建项目并导入JAR包 首先在Eclipse中创建一个Web项目ssh01 将表1.1中Hibernate所需10个jar包复制到项目的WEB-INF/lib目录中 此外还需要连接MySQL数据库,需要添加MySQL的驱动包,本书中使用的 MySQL驱动版本是mysql-connector-java-5.1.21.jar 复制好后,添加到构建路径中1.3 第一个Hibernate项目 1.3.2 创建数据库及表本书使用的数据库为MySQL5.7.18,客户端使用SQLyog在MySQL中创建一个名称为stude

6、ntdb的数据库,在此数据库中创建一张名为student的数据表1.3 第一个Hibernate项目 1.3.3 创建持久化类持久化类与数据库表相对应,持久化类的属性名称、个数、类型都与数据库表的列名、个数、类型一一对应。在项目src目录下,创建com.seehope.entity包,并在包中创建持久化类Student,类中创建与student数据表字段对应的属性,以及相应的getter和setter方法1.3 第一个Hibernate项目 节点 配置持久化类的映射信息;它的name属性对应持久化类名,table属性对应数据库中的表名。节点 节点下;用来定义持久化类的主键属性(对应数据库表中的

7、主键);name属性对应持久化类的主键属性,column属性对应数据库表中的主键列子节点 节点下;用于指定主键的生成策略。这里设置成“native”表示主键由数据库自动生成而不是在程序中指定。节点 节点下;用于映射实体对象的普通属性。其name属性对应实体中的普通属性,column属性对应数据库表中的普通字段(非主键),type属性表示其属性的数据类型。1.3.4 创建映射文件映射文件的作用是告知Hibernate,持久化类Student映射到数据库studentdb中的哪个表,并且进一步精确地指定持久化类中的哪个属性对应数据库表中的哪个字段。在持久化类Student所在包中,新建一个名称为S

8、tudent.hbm.xml的映射文件,在该文件中指定了持久化类Student与数据库中的哪个表对应,以及类Student中的每一个属性与数据库student表的字段一一对应。Student.hbm.xml中的主要节点1.3 第一个Hibernate项目 1.3.5 创建核心配置文件Hibernate的配置文件主要用来配置数据库连接以及Hibernate运行时所需要的各个属性的值。在项目的src目录下创建一个名称为hibernate.cfg.xml的文件,代码如下。该文件将会在本章1.5节详细介绍。1.3 第一个Hibernate项目 1.3.5 创建核心配置文件1.3 第一个Hibernat

9、e项目 1.3.6 创建测试类进行增删改查操作 在项目中新建一个名称为com.seehope.test的包,然后创建Main.java文件。接下来,在该文件中创建4个方法分别进行增删改查操作。 添加数据:在Main类中编写添加数据的方法insertTest(),实现添加一个学生的功能1.3 第一个Hibernate项目 1.3.6 创建测试类进行增删改查操作1.3 第一个Hibernate项目 1.3.6 创建测试类进行增删改查操作使用JUnit4测试运行insertTest()后在MySQL数据库中查询student表的数据从图1.8中可以看出,student表中添加数据成功。这里添加数据的

10、关键方法是session.save(stu),给人感觉保存的是Student对象stu,实际结果却是数据库中新添加了一条记录,这正是hibernate的重要特性,通过操作对象就能实现数据库操作。1.3 第一个Hibernate项目 1.3.6 创建测试类进行增删改查操作 修改数据:在Main类中添加updateTest()方法,使用Hibernate来修改id为2的数据Hibernate修改数据的基本流程与其保存数据的方法大体相同,只是后面创建了一个对象,且该对象的id是要在数据库表中事先存在的,其他属性值则可以设置成与数据库表中对应的值不同。最后通过session.update()方法执行更

11、新操作,表面上给人感觉是更新对象,实际上数据会更新到数据库中。1.3 第一个Hibernate项目 1.3.6 创建测试类进行增删改查操作使用JUnit4测试运行updateTest()方法,其结果如图1.9所示。发现id为2的记录已由李白改成了杜甫。1.3 第一个Hibernate项目 1.3.6 创建测试类进行增删改查操作 查询单个对象数据:在Main类中,添加一个名称为getByIdTest()的查询数据的方法,用于根据指定id查询数据库中的数据,这里查询id为1的学生数据。查询操作使用了session.get()的方法,该方法有两个参数,第一个参数指定要操作的类,第二个参数id指明要查

12、找的对象的主键,该方法用于从数据库中查找到指定主键的数据并封装成对象数据。1.3 第一个Hibernate项目 1.3.6 创建测试类进行增删改查操作使用JUnit4测试运行getByIdTest()方法后,控制台的显示如图所示。图1.10查询结果分析:控制台头部出现了三行红色警告信息,这是因为没有配置log4j导致的,这里可以不必理会,接着出现了黑色的SQL语句信息,这是由于在hibernate.cfg.xml文件中配置了显示SQL语句和格式化SQL的配置信息,这说明Hibernate发出了SQL语句,向数据库查询需要的数据。最后出现的是查询结果。除了使用Session的get()方法查找指

13、定对象id的数据外,还有Session的load()方法也可实现同样的功能,区别在于使用get()方法加载数据时,如果要查找的记录不存在,则返回null,不会报错。使用load()方法加载数据时,如果要查找的记录不存在,则会报出ObjectNotfoundException异常。1.3 第一个Hibernate项目 1.3.6 创建测试类进行增删改查操作 删除数据:在Main类中增加一个名称为deleteByIdTest()的方法,使用Hibernate删除一条记录,这里删除id为5的学生数据,代码如下所示。从图1.11中可以看出,Student表中少了第5条,已被成功删除了。首先通过get方

14、法获得要删除的对象,然后使用Session的delete方法将该对象作为参数,从而在数据库中将它删除。1.3 映射文件详解 Hibernate映射文件用于配置将POJO对象持久化到关系型数据库中的相关信息,一个持久化类对应一个映射文件,映射文件的基本结构如下所示。1.3 映射文件详解 节点用来声明一个持久化类并且指定了Java持久化类与数据库表之间的映射关系主要节点说明节点用来设定持久化类的OID(Object Identifier对象标识符,唯一地标识一个对象,类似表的主键)和数据库表的主键的映射关系。可选的子节点:结点用于指定了主键的生成方式,也称为主键生成策略。主键既可以通过程序指定,也

15、可由数据库自动生成,但数据库自动生成的话因不同数据库还是有所差别,比如MySQL的主键可以通过自增长实现,SQL Server通过标识列实现,而Oracle的要通过序列才能实现。通过节点,就可以指定这些不同的实现方式。1.3 映射文件详解 主要节点说明Hibernate提供了几个内置的主键生成策略,如表所示。节点用来指定持久化类的普通属性与数据库表中的普通字段的映射关系。property节点的常用属性有name、column和type三个。name用来指定持久化类中的属性名,column用来指定数据库表中的对应字段名,type用来指定持久化类属性的数据类型。1.5 配置文件详解 1.5.1 基

16、本配置hibernate.cfg.xml配置文件使用property节点来配置Hibernate连接数据库的一些重要信息,如数据库的方言、驱动、URL、用户名和密码等,并使用mapping节点来加载映射文件的信息。文件名称固定为hibernate.cfg.xml,一般放置在src目录下。hibernate.cfg.xml配置文件的常见配置请参见1.3.5。其常用属性名称及用途如表所示。1.5 配置文件详解 1.5.2 配置c3p0连接池Hibernate中也可以使用c3p0连接池进行连接以提高数据库连接的性能与效率。在下载的Hibernate解压缩包的lib目录下的子目录optional中找到

17、C3P0的jar包c3p0-0.9.1.jar,复制到项目ssh01的WebContent/WEB-INF/lib下,并添加到构建路径,然后在hibernate.cfg.xml中新添加如下代码使用Junit4运行测试类Main中的insertTest()方法。查看数据库,插入数据成功,表明C3P0连接池的配置成功。1.6 Hibernate持久化对象的状态 1.6.1 持久化对象的状态持久化就是指将Java运行时的对象数据永久存储到关系型数据库中。在Hibernate中,根据内存中的对象与数据库表中对应记录是否同步关联,持久化对象分为三种状态,分别是瞬时状态、持久状态和游离状态。瞬时状态(tr

18、ansient)瞬时状态是指内存中的对象刚刚创建(new)出来,还没有与Session关联,与数据库中的数据无任何关联,在数据库中没有对应的记录,在内存中孤立存在着,若无其他操作或引用,最后将会被JVM垃圾回收。瞬时对象没有持久化标识OID。持久状态(persistent)持久状态的对象与session相关联,且相关联的Session尚未关闭,在数据库有对应的记录,持久状态对象有持久化标识OID。游离状态(detached)当持久化对象相关联的session关闭时就变成了游离状态。虽然此时对象仍有OID,并且数据库中有对应的记录,但该对象没有与session相关联,Hibernate已检测不到

19、它的变化。1.6 Hibernate持久化对象的状态 1.6.2 持久化对象状态转换Hibernate持久化对象的三种状态,是可以通过Session的一系列方法进行转换的 瞬时状态转换到其他状态 刚刚创建new出来是处于瞬时状态。 瞬时状态转换为持久状态:执行Session的save()或saveOrUpdate()方法。 瞬时状态转换为游离状态:为瞬时状态对象设置持久化标识OID。 瞬时状态和游离状态都没有Session的关联,它们的区别在于瞬时状态没有OID,游离状态对象存在OID,1.6 Hibernate持久化对象的状态 持久状态对象转换到其他状态 持久化对象可以通过Session的g

20、et()、load()方法,或者Query查询从数据库获得。 持久状态转换为瞬时状态:执行Session的delete()方法,持久化对象被删除后,虽然在内存中仍然存在,但不建议再使用,由JVM自行回收。 持久状态转换为游离状态:执行Session的evict()、close()或clear()方法。evict()方法用于清除一级缓存中某一对象。close()方法用于关闭Session,清除一级缓存。clear()方法用于清楚一级缓存的所有对象。 游离状态对象转换到其他状态 游离状态对象不能直接获得,只能由其他状态对象转换而来的。 游离状态转换为持久状态:执行Session的update()、

21、saveOrUpdate()或lock()方法。 游离状态转换为瞬时状态:将游离状态的的持久化标识OID设置为null。例如,在 BookTest.java中的session.close()操作后,加入代码book.setId(null),当程序执行完book.setId(null)代码后,book对象由游离态转换为瞬时状态。1.6 Hibernate持久化对象的状态 持久化对象的状态实例 在ssh01项目的包com.seehope.test下新建TestState测试类上述代码中,stu对象由new关键字创建,此时还未与Session进行关联,它的状态为瞬时状态,在执行了session.sa

22、ve(stu)操作后,stu对象被纳入了Session的管理范围,这时的stu对象变成了持久状态,程序执行完了commit()操作并关闭了Session后,stu对象与Session的关联被关闭,此时stu对象就变成了游离状态。最后游离状态清除了OID,又变成了瞬时状态。1.6 Hibernate持久化对象的状态 持久化对象的状态实例 使用JUnit4测试运行,结果如下图所示。从图1.13可以看出执行save()方法之前id值为null,这时它是属于瞬时状态,执行save()方法之后stu对象的id属性有了值13(持久化标识OID),表明stu对象变成了持久状态,这也证明了瞬时状态对象和持久状

23、态对象的区别是:持久状态对象OID有值并且与Session进行了关联。当程序继续向下执行至session.close()时,stu对象脱离了session的管理,此时stu对象变成了游离状态,但stu对象的OID值依然存在,这也证明了游离状态对象与持久状态对象的相同点是都有OID值,不同点就是游离状态对象没有了Session关联。1.7 Hibernate的核心接口简介 在Hibernate中有Configuration、SessionFactory、Session、Transaction、Query、Critreia 共6个常用的核心接口。1.7.1 Configuration接口 Conf

24、iguration是最先用到的一个接口,使用Hibernate时,首先要创建Configuration实例才能开启其他一系列操作。 Configuration实例主要用于启动、加载和管理hibernate的配置文件。 Hibernate启动时,Configuration实例会查找Hibernate配置文件hibernate.cfg.xml,读取其相关配置,然后创建一个唯一的SessionFactory实例,创建完SessionFactory后,Configuration实例生命周期就此结束。Hibernate创建Configuration实例使用右述代码这种方法默认会去src下读取hibern

25、ate.cfg.xml配置文件。如果配置文件不是放在src下也是可以的,但需要指定其实际位置。1.7 Hibernate的核心接口简介 1.7.2 SessionFactory接口 SessionFactory实例通过Configuration实例获取,用于Hibernate的初始化和建立Session对象,其获取过程如下代码所示。 由于SessionFactory是线程安全的,它的同一个实例能同时给多个线程共享,并且它是重量级的不能随便创建和销毁它的实例,所以一个项目中一般只需要一个SessionFactory实例就行了(除非一个项目有多个数据源才需要创建多个SessionFactory实例

26、)。通常会抽取一个命名为HibernateUtils的工具类,在该工具类中创建一个静态的SessionFactory对象,供各个方法调用,这样各个方法就能共用同一个SessionFactory实例,HibernateUtils工具类中还提供创建Session实例的方法。该工具类的具体使用参见1.7.3节。1.7 Hibernate的核心接口简介 1.7.3 Session接口 Session接口是Hibernate向应用程序提供的操作数据库的接口,它提供了基本的保存,更新,删除和查询的方法。Session实例由SessionFactory实例的openSession()方法或getCurren

27、tSession方法获得。区别是前者实例要手动关闭,后者实例在提交或回滚时自动关闭。 Session有以下特点: 它不是线程安全的,因此在软件设计时,应该避免多个线程共享同一个Session实例。 Session实例是轻量级的,它的创建和销毁不需要消耗太多的资源。这意味着在程序中可以经常创建和销毁Session对象,例如可以为每个方法单独分配一个Session实例。 Session还有一个缓存,称为Hibernate的一级缓存,它存放被当前工作单元加载的对象。每个Session实例都有自己的缓存,这个Sesion实例的缓存只能被当前工作单元访问。 Session主要提供下面几种方法。 save

28、(): 添加对象,将瞬时状态的对象数据存入数据库并变为持久状态。它使用映射文件指定的主键生成器为持久化对象分配唯一的OID。 update():修改对象,将游离状态的对象转变为持久状态。1.7 Hibernate的核心接口简介 Session主要提供下面几种方法。 saveOrUpdate():同时包含了save()与update()方法的功能,如果传入的参数是瞬时状态对象,调用save方法,如果参入参数是游离状态对象,调用update()方法,如果传入的是持久化对象,直接返回。 load()/get(): 两者都是根据给定的OID从数据库中加载一个持久化对象,区别在于,当数据库中不存在与OI

29、D对应的记录时,load()方法会抛出ObjectNotFoundException异常,而get()方法返回null. delete():用于从数据库删除一个Java对象,该方法传入的参数既可以是持久状态对象,也可以是游离状态的对象。如果传入的参数是游离状态的对象,则会先使游离对象被当前Session关联,转化为持久状态对象,如果传入的参数是持久状态对象则没有这一步。然后执行SQL的delete语句,在数据库中删除该对象对应的记录,最后将该对象从Session的缓存中删除掉。 evict():从缓存中清除参数指定的持久状态对象。 clear():清空缓存中所有持久化对象。1.7 Hibern

30、ate的核心接口简介 使用下述案例中的HibernateUtils工具类可以完美地实现SessionFactory实例被多个方法(增删改查操作各一个方法)共享,以及session实例则由各个方法独立创建。并且大大简化代码量。项目案例:使用工具类简化第一个项目(源码请见本书配套资源:第1章/ssh01)。(1) src目录新建包com.seehope.util,包下新建类HibernateUtils.java,参考代码如下所示。有了上述HibernateUtils工具类,其他类就可以直接通过HibernateUtils.getSession()的方法获取Session对象,从而简化操作。1.7

31、Hibernate的核心接口简介 (2)下面对Main类中的4个方法进行简化。在包com.seehope.test下新建测试类Main2,简化原来Main类的4个方法如下。1.7 Hibernate的核心接口简介 1.7.4 Transaction接口 Transaction接口是Hibernate的数据库事务接口,它对底层事务接口进行了封装,底层事务接口包括:JDBC API、JTA(Java Transaction API)、CORBA(Common Object Requet Broker Architecture)APIHibernate应用可通过一致的Transaction接口来声明

32、事务边界,虽然应用也可以绕过Transaction接口,直接访问底层的事务接口,但这种方法不值得推荐,因为它不利于应用在不同的环境移植。使用hibernate进行增删改操作时,必须显式的调用Transaction。 Transaction接口的事务对象通过Session对象开启,其开启方式如下面代码所示。 在Transaction接口常用事务管理方法如下。commit()方法:提交事务。rollback()方法:撤销事务操作。wasCommitted()方法:事务是否提交。Session进行数据库的增删改操作后,还要使用Transaction接口的commit()方法进行事务提交才能真正地将对

33、象数据同步到数据库中。如果事务执行过程中发生异常,就需要使用rollback()方法进行事务回滚,以避免数据不一致。1.8上机练习 题目:在MySQL数据中创建productdb数据库,创建如表1.6所示的商品数据表goods,请在eclipse中创建一个hibernate项目。注意要使用工具类HibernateUtils。1.查询出id为4的商品。2.添加一个新的商品。3.修改一条数据。4.删除一条数据。第二章 HQL与Criteria查询 掌握HQL查询基本语法 学会在HQL中使用参数熟练掌握HQL的各种复杂查询 了解criteria查询40本章指引2.1 HQL查询概述2.2 Crite

34、ria查询2.3 上机实验412.1 HQL 查询概述42Hibernate查询语言(Hibernate Query Language)简称HQL,是一种面向对象的查询语句,形式上跟SQL很相似,但注意它查询不是数据库表,而是类(对象),查询的结果通常是对象或对象的集合,而传统的SQL查询结果则是结构化的关系模型。2.1.1 HQL基本语法1.from子句用于查询指定的对象集合。如:指的是查询所有学生对象,也可用右述形式能更好地理解:上述对象用了全路径类名,能一眼看出这是个类,而不会误认为是数据库表,注意HQL语句本身不区分大小写,但相关的java包,类,属性要区分大小写。from Stude

35、nt这个查询语句中student省略了包名是允许的,但Student写成student就不行。2.Select子句通常用来选取查询目标对象的部分属性,如:表示查询学生对象的姓名,年龄两个属性的值2.1 HQL 查询概述433.where子句用于限定查询条件,跟SQL类似,但where子句中用到的是对象的属性而不是列名,注意区别,虽然很多时候属性名跟列名同名,如:4.order by子句用于排序,升序用asc,降序用desc,默认升序,其用法与SQL一样。5.使用表达式表达式相当于SQL中的各种函数。一般在where子句中使用表达式,例如查询学生的姓名的大写字母是TOM的学生:查询出生年份是20

36、01年的学生:2.1 HQL 查询概述442.1.2 HQL语句的执行HQL语句的执行流程是:首先构建HQL语句,然后创建Query对象,最后使用Query对象的list()方法、iterate()方法,或者uniqueResult()方法执行查询,获取执行结果(返回值)。1.使用Query对象的list()方法执行查询并返回值项目案例:查询所有学生的信息并将查询结果输出到控制台。(源码请见本书配套资源:第2章/ssh02)(1)将上一章的项目复制为ssh02,创建测试类HQLTest,添加下面的方法:(2)运行结果如右 可见list方法可以执行HQL语句并且返回List泛型集合。2.1 HQ

37、L 查询概述453使用uniqueResult()方法执行查询返回唯一的一个对象项目案例:查询姓名为李白的学生。(源码请见本书配套资源:第2章/ssh02)在HQLTest类中添加以下方法。测试运行,控制台只显示一个学生的信息。注意这种情况下只能使用返回单个对象的HQL语句,否则会报错。2使用Query对象的iterator()方法执行HQL语句项目案例:查询所有学生。(源码请参见本书配套资源:第2章/hibernate02)在HQLTest类中添加一个方法。2.1 HQL 查询概述463使用uniqueResult()方法执行查询返回唯一的一个对象项目案例:查询姓名为李白的学生。(源码请见本

38、书配套资源:第2章/ssh02)在HQLTest类中添加以下方法。测试运行,控制台只显示一个学生的信息。注意这种情况下只能使用返回单个对象的HQL语句,否则会报错。2使用Query对象的iterator()方法执行HQL语句项目案例:查询所有学生。(源码请参见本书配套资源:第2章/hibernate02)在HQLTest类中添加一个方法。2.1 HQL 查询概述472.1.3 HQL查询条件中使用参数1使用占位符“?”绑定参数HQL查询条件往往需要用到外部传入的值进行查询,可用参数的形式接收这些外部传入的值。在HQL语句中可以使用一个或多个“?”占位符的方式来绑定参数。“?”占位符表示此处对应

39、为一个输入参数,然后在执行HQL语句之前要给这些参数赋值,使用Query对象的setXxx(参数索引,参数值)方法进行赋值,其中XXX表示参数的数据类型,与属性的java类型一致,常见的setXxx()方法如表2.1所示。setXxx(参数索引,参数值)方法里面的第一个参数表示HQL语句中的第几个“?”占位符,从0算起,第二个参数表示给该“?”占位符赋值。2.1 HQL 查询概述48项目案例:查询年龄为XX岁性别为XX的学生。(源码请见本书配套资源:第2章/ssh02)在HQLTest类中添加以下方法:上述代码中,query.setInteger(0, 18);表示给第一个“?”占位符赋值18

40、,值的类型的是整型,query.setString(1, 男);的意思是给第二个“?”占位符赋值“男”,这样原始的HQL语句from Student where age=? and gender=?,将会被构建成from Student where age=18 and gender=男这样的包含实际值的HQL语句再来执行。2.1 HQL 查询概述492.使用参数名称进行绑定使用多个“?”占位符有个不方便的地方就是分别赋值时要想一想算一算是第几个占位符,不小心就会弄错。改用参数名称绑定进行赋值就不会有这个问题。HQL语句中参数名称前用“:”号来标明。赋值时使用setXxx(参数名称,参数值)方

41、法。参数名称的使用规则:在HQL语句中用“: ”号加参数名称一一代替之前的“?”占位符。项目案例:查询年龄为XX岁的性别为XX的学生,使用参数名称绑定实现。(源码请见本书配套资源:第2章/ssh02)在HQLTest类中添加以下方法。这里的HQL语句中分别用“ :age”和“ :gender”代替之前的“?”占位符。setXxx赋值时用参数名称代替之前的索引数字。结果同上。2.1 HQL 查询概述502.1.4 HQL给参数赋值的其他方法1.使用setParameter()方法给参数赋值给HQL中的各个参数赋值时,需要一一判断各个参数对应的数据类型,从而调用相应的setXxx方法进行赋值,比较

42、麻烦一点,而setParameter()方法则是通用型的,参数为任意数据类型均可使用,解决了选用哪个setXxx的烦恼。语法如下:setParameter(第几个占位符或参数名称,参数的值)项目案例:查询年龄为XX性别为XX的学生。(源码请见本书配套资源:第2章/ssh02)在HQLTest类中添加以下方法。上面代码使用了setParameter()代替了setXxx,既适用于“?”占位符的情况(见上述findStudents3()代码),也适用于使用参数名称的情况。测试运行输出结果同前。2.1 HQL 查询概述512使用setProperties()方法获取对象的属性值给HQL中的命名参数赋

43、值该方法需要先实例化一个对象,并且给对象中的全部或部分属性赋值,然后调用Query的setProperties(实例化对象)方法,该方法会自动提取实例化对象的各个属性值赋给HQL中同名的对应命名参数。注意HQL中的命名参数的名称要与对象属性名称一致。项目案例:查询年龄为XX性别为XX的学生。在HQLTest类中添加以下方法(源码请见本书配套资源:第2章/ssh02)。上述代码中,HQL语句中的两个命名参数,通过setProperties方法,分别由封装好的Student对象的对应名称的属性进行了赋值。2.1 HQL 查询概述522.1.5 HQL模糊查询与动态查询动态查询适用于查询条件的个数不

44、确定的情况,比如大家上网购物,每个人搜索商品的搜索条件数量都不相同。使用上面学习的setProperties()方法使得动态查询变得容易。首先实例化一个持久化类的对象,根据用户输入的条件数量给持久化类对象动态赋值(用户输入多少个条件就给持久化类的多少个属性赋值),同时动态构建HQL语句,用户每输入一个条件就增加一句HQL 命名参数查询条件。最后用setProperties()给参数赋值并执行即可。项目案例:搜索学生的条件不确定,进行动态查询。(源码请见本书配套资源:第2章/ssh02)运行后,可以测试多种不同查询条件的情况。上面查询学生姓名时用到了模糊查询,注意模糊查询不要直接在HQL语句中使

45、用%符号,而是在setXXX方法中使用%号。动态查询通过动态构建HQL语句同时动态给对象赋值,并恰当地利用了setProperies这个方法。2.1 HQL 查询概述532.1.6 HQL投影查询有时候并不需要查询一个对象的所有信息(属性),不需要返回完整的对象。只想查询一部分信息(属性),这时可用到HQL投影查询。这时要用到上面提过的select子句。投影查询执行后的返回结果有三种情况。1.只查询单个属性查询结果封装为泛型集合项目案例:查询所有学生的姓名。(源码请见本书配套资源:第2章/ssh02)在HQLTest中添加方法findStudents7()方法如下。测试运行,可发现所有学生姓名

46、都查出来了。这里只查询studentName属性,由于它是String 类型,所有返回值采用List类型,类似地如果只查询age属性,则返回结果采用List类型。2.1 HQL 查询概述542查询多个属性的情况这时返回结果要用List类型来接收。项目案例:查询所有学生的姓名与年龄。(源码请见本书配套资源:第2章/ssh02)在HQLTest中添加方法findStudents8()方法如下:2.1 HQL 查询概述553将部分属性封装成对象首先要在类中添加一个构造方法,比如我要查询学生姓名和年龄,就在Student类中新增一个带studenName和Age两个参数的构造方法,然后再按下述案例所示

47、的形式构造HQL语句。项目案例:查询所有学生的姓名与年龄。(源码请见本书配套资源:第2章/ssh02)(1)持久化类Student中添加一个构造方法(2)HQLTest类中添加方法findStudents9()2.1 HQL 查询概述562.1.7 HQL分页查询分页查询主要用到了Query对象的setFirstResult方法和setMaxResult方法,它们的作用如下。setFirstResult:设置需要返回的第一条记录的起始下标,下标从0算起,有点类似MySQL中limit后的第一个参数。setMaxResult:设置最大返回结果条数。有点类似MySQL中limit后的第二个参数。这

48、两个方法要用在Query对象的list()方法之前。分页查询一般还需要确定两个变量,一个是想查询第几页,这里(本项目)暂用变量名pageNo来表示,另一个变量就是确定一页显示几条记录,这里暂用变量名pageSize来表示。确定好变量后用表达式(pageNo-1)*pageSize作为setFirstResult()方法的参数,用pageSize作为setMaxResult()方法的参数。下面示例对学生信息进行分页查询。2.1 HQL 查询概述572.1.8 HQL聚合函数在HQL语句中可以运用聚合函数,与SQL一致。聚合函数有count(),sum(),avg(),max(),min()五种。

49、注意由于只返回单个数据,所以用Query的uniqueResult()方法来执行HQL语句,另外整型返回结果必须是Long类型。下面示例查询学生的人数,在HQLTest类中添加方法findStudents11(),代码如下。(源码请见本书配套资源:第2章/ssh02)2.1 HQL 查询概述582.1.9 HQL分组查询HQL使用group by子句进行分组查询,与SQL一致。下面示例查询男女生的人数。在HQLTest类中添加方法findStudents12(),代码如下。(源码请见本书配套资源:第2章/ssh02)运行测试结果如下:2.1 HQL 查询概述592.1.10 使用别名HQL语句

50、中也可以使用别名,跟SQL一样,HQL中也是使用关键字as指定别名, as关键字也可以省略。在HQLTest类中创建一个名为aliasTest()的方法,该方法使用HQL别名的方式查询数据,如下所示。(源码请见本书配套资源:第2章/ssh02)在上述代码中,s是Student类的别名,在where条件后,使用其别名查询studentName=”李白”的对象。本章指引2.1 HQL查询概述2.2 Criteria查询2.3 上机实验602.2 Criteria查询61Criteria接口是一个面向对象的,可扩展的条件查询HibernateAPI,它跟HQL查询的不同之处在于它不需要考虑数据库底层

51、实现,以及HQL语句如何编写就能轻松实现各种查询。Criteria实例化对象通过下列代码实现。可见,Criteria对象仍然是由session创建的。2.2.1 Criteria简单查询创建好Criteria对象后,再利用Criterion对象设定查询条件,然后使用Criteria对象的add方法添加查询条件,最后使用list()方法或uniqueResult()执行查询即可实现简单查询。设定Criterion查询条件的和添加查询条件如下代码所示。上面提到的Criterion是Hibernate的一个面向对象查询条件接口,Criterion对象的通过Restrictions类来创建。在Rest

52、rictions类中提供了大量的静态方法来创建查询条件,其常用的方法如表2.2所示。2.2 Criteria查询622.2 Criteria查询63项目案例:使用Criteria查询姓名为李白的学生。(源码请见本书配套资源:第2章/ssh02)在项目ssh02的com.seehope.test包中新建一个名称为CriteriaTest的类,在类中添加一个CriteriaTest1()方法,代码如下所示。使用JUnit4测试运行,控制台的显示结果如图2.1所示。2.2 Criteria查询642.2.2 Criteria多条件查询结合表2.2及下面案例学习多条件查询。项目案例:查询id=2或者s

53、tudentName=李白的学生。在类Criteriatest中建立一个名称为criteriaTest2 ()的方法,如下所示。(源码请见本书配套资源:第2章/ssh02)2.2 Criteria查询652.2.2 Criteria多条件查询结合表2.2及下面案例学习多条件查询。项目案例:查询id=2或者studentName=李白的学生。在类Criteriatest中建立一个名称为criteriaTest2 ()的方法,如下所示。(源码请见本书配套资源:第2章/ssh02)上述代码Restrictions.or方法就相当于SQL中的or关系,Restrictions.eq方法就相当于SQL中

54、的等于。测试运行,控制台的输出结果如图2.2所示。2.2 Criteria查询662.2.3 Criteria分页查询Criteria同样可以实现分页查询,它通过Citeria对象的setFirstResult(int firstResult)和setMaxResult(intmaxResult)这两个方法共同来实现。其中setFirstResult(int firstResult)方法用于指定从哪个对象开始检索,序号从0算起,setMaxResult(int maxResult)方法用于指定一次最多检索的对象数,即每页显示几条记录。在测试类CriteriaTest中编写criteriaTes

55、t3()方法,代码如下所示。(源码请见本书配套资源:第2章/ssh02)上述查询的是第1页,每页显示3条,假定页码用pageno变量,每页大小用pageSize变量,则通用查询代码是:2.2 Criteria查询67使用JUnit4测试运行criteriaTest3()方法后,控制台的输出结果如图2.3所示。上机练习题目:在上一章的商品数据库基础上实现:1.查询所有商品信息。2.查询商品名称包含“电”字的商品信息。3.查询所有商品的名称与价格。4.查询商品的总数量。思考题1条件查询中给参数赋值的方法有哪些?2说说HQL查询与Criteria查询的区别。2.3上机练习 题目:在上一章的商品数据库

56、基础上实现:1.查询所有商品信息。2.查询商品名称包含“电”字的商品信息。3.查询所有商品的名称与价格。4.查询商品的总数量。第3章 Hibernate关联映射掌握单向关联与双向关联的概念掌握一对多关联关系的使用掌握多对多关联关系的使用掌握关联关系中的反转和级联掌握延迟加载69本章指引3.1 实体对象的三种关联关系3.2 关联关系中的反转与级联3.3 延迟加载3.4 上机实验703.1 实体对象的三种关联关系数据库中表与表之间的关系有下列三种,数据库表之间的关系是通过外键来实现的: 一对多:班级与学生,一个班级对应多个学生。需要在多方,添加一方的主键作为外键。 多对多:例如教师与学生的关系,一

57、个教师可教多个学生,一个学生可被多个教师教。需要一张中间表,添加两张表的主键作外键。 一对一:比如人与身份证的关系,一个人对应一个身份证。在其中一方添加另一方的主键作外键。Hibernate中数据库对应的实体对象之间同样有上述三种类型的关联关系,设计持久化类时,需要在类中进行特别设置以体现它们之间的关联关系,具体规则如下: 一对一:在其中一个类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a。 一对多:假如是一个A类是一方,B类是多方,需要在A类以Set集合的方式引入B类型的对象,同时在B类中定义A类类型的属性a。 多对多:在A类中定义B类类型的Set集合,在B类

58、中定义A类类型的Set集合,使用Set集合的是为了避免数据的重复(如果采用List集合则有可能有重复)。实体对象之间的三种关联关系,除了在类中进行上述设置外,还要在映射文件中配置,具体看下面案例。注:一对一关联关系的操作同一对多关联关系,在此不单独介绍。713.1 实体对象的三种关联关系数据库中表与表之间的关系有下列三种,数据库表之间的关系是通过外键来实现的: 一对多:班级与学生,一个班级对应多个学生。需要在多方,添加一方的主键作为外键。 多对多:例如教师与学生的关系,一个教师可教多个学生,一个学生可被多个教师教。需要一张中间表,添加两张表的主键作外键。 一对一:比如人与身份证的关系,一个人对

59、应一个身份证。在其中一方添加另一方的主键作外键。Hibernate中数据库对应的实体对象之间同样有上述三种类型的关联关系,设计持久化类时,需要在类中进行特别设置以体现它们之间的关联关系,具体规则如下: 一对一:在其中一个类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a。 一对多:假如是一个A类是一方,B类是多方,需要在A类以Set集合的方式引入B类型的对象,同时在B类中定义A类类型的属性a。 多对多:在A类中定义B类类型的Set集合,在B类中定义A类类型的Set集合,使用Set集合的是为了避免数据的重复(如果采用List集合则有可能有重复)。实体对象之间的三种关

60、联关系,除了在类中进行上述设置外,还要在映射文件中配置,具体看下面案例。注:一对一关联关系的操作同一对多关联关系,在此不单独介绍。723.1 实体对象的三种关联关系3.1.1 单向关联与双向关联以一对多为例,一个班级对应多个学生,这是典型的一对多关系,假设班级Classes类是“一方”,学生Student类是“多方”,如果“一方”Classes类中定义了“多方”Student类型的Set集合属性,并且“多方”Student类中也定义了“一方”Classes类型的属性,这就是双向关联。如果Classes类中定义了Student类型的Set集合属性,但Student类中却没有定义了Classes类

温馨提示

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

评论

0/150

提交评论