




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1EJB3.0入门经典入门经典2关于开题报告答辩关于开题报告答辩n请各位同学,根据答辩时老师的建议,认真修请各位同学,根据答辩时老师的建议,认真修改三大件改三大件;n将修改结束以压缩包的形式发给指导教师。将修改结束以压缩包的形式发给指导教师。3重点章节重点章节n第第2章章 会话会话Bean (Session Bean)n第第3章章 实体实体Bean (Entity Bean)n第第6章章 Web服务服务 (Web Service)4题型题型n 读程序,写结果;读程序,写结果;n 编程;编程;n 写操作步骤。写操作步骤。52.1.2 开发只实现开发只实现 Local 接口的无状态接口的无状态 S
2、ession Beann 开发只有开发只有 Local 接口接口的无状态会话的无状态会话Session Bean,使用,使用Local 注释声明接口是本地接口。注释声明接口是本地接口。 n 开发只有开发只有 Remote 接口接口的无状态会话的无状态会话Session Bean ,使,使用用Remote 注释声明接口是远程接口。注释声明接口是远程接口。n 当当Local 和和Remote 注释注释都不存在都不存在时,容器会将时,容器会将 Bean class 实现的接口默认为实现的接口默认为 Local 接口。如果接口。如果 EJB 与与客户端客户端 部署在同一个应用服务器,采用部署在同一个应
3、用服务器,采用 Local 接口访问接口访问 EJB 优于优于 Remote 接口。接口。6业务接口:业务接口:LocalHelloWorld.java n 工程:工程:LocalSessionBean72.4 Stateful Session Bean开发开发n 在一些应用场合中,有时我们需要每个用户都有自己在一些应用场合中,有时我们需要每个用户都有自己的一个实例,这个实例不受其他用户影响。的一个实例,这个实例不受其他用户影响。q 购物车对象,每个用户都应有自己的购物车,不希望有人往购物车对象,每个用户都应有自己的购物车,不希望有人往你的购物车里添加或拿掉商品,而有状态你的购物车里添加或拿掉
4、商品,而有状态Bean正好满足你正好满足你的这种需求。的这种需求。n 每个有状态每个有状态Bean在在bean实例的生命周期内都只服务实例的生命周期内都只服务于一个用户,于一个用户,bean class的成员变量可以在不同的方的成员变量可以在不同的方法调用间维护特定于某个用户的数据。法调用间维护特定于某个用户的数据。82.4 Stateful Session Bean开发开发9Bean 类:类:CartBean.java 10有状态有状态 Bean 的的 JSP 客户端代码:客户端代码:StatefulBeanTest.jsp 先试图从先试图从session中获取购中获取购物车的存根。物车的存
5、根。如果当前如果当前session不存在购不存在购物车,就创建一个新的购物物车,就创建一个新的购物车放入车放入session中。中。后面每执行一次页面都会添后面每执行一次页面都会添加一个相同的商品。加一个相同的商品。112.9 Session Bean的生命周期事件的生命周期事件n PostConstruct:当当bean对象完成实例化后会被立即调用,对象完成实例化后会被立即调用,每个每个beanclass只能定义一个只能定义一个PostConstruct方法。这个注释方法。这个注释同时适用于有状态和无状态会话同时适用于有状态和无状态会话bean。n PreDestroy:标注了这个注释的方法
6、会在容器销毁一个无用标注了这个注释的方法会在容器销毁一个无用的或者过期的的或者过期的bean实例之前调用。这个注释同时适用于有状态实例之前调用。这个注释同时适用于有状态和无状态会话和无状态会话bean。n PrePassivate:当一个有状态的当一个有状态的bean实例空闲时间过长,就实例空闲时间过长,就会发生钝化会发生钝化(passivate)。标注了这个注释的方法会在钝化之前。标注了这个注释的方法会在钝化之前被调用。被调用。bean实例被钝化后,在一段时间内,如果仍然没有用实例被钝化后,在一段时间内,如果仍然没有用户对户对bean实例进行操作,容器将会从硬盘中删除它。以后,任实例进行操作
7、,容器将会从硬盘中删除它。以后,任何针对该何针对该bean方法的调用,容器都会抛出例外。这个注释适用方法的调用,容器都会抛出例外。这个注释适用于有状态会话于有状态会话bean。122.9 Session Bean的生命周期事件的生命周期事件n PostActivate:当客户端再次使用已经被钝化的有状态当客户端再次使用已经被钝化的有状态bean时,时,EJB容器会重新实例化一个容器会重新实例化一个Bean实例,并从硬盘中将之前实例,并从硬盘中将之前的状态恢复。标注了这个注释的方法会在激活完成时被调用。的状态恢复。标注了这个注释的方法会在激活完成时被调用。这个注释只适用于有状态会话这个注释只适用
8、于有状态会话bean。n Init:这个注释指定了有状态这个注释指定了有状态bean初始化的方法。它区别于初始化的方法。它区别于PostConstruct注释在于:多个注释在于:多个Init注释方法可以同时存在注释方法可以同时存在于有状态于有状态sessionbean中,但每个中,但每个bean实例只会有一个实例只会有一个Init注注释的方法会被调用。释的方法会被调用。PostConstruct在在Init之后被调用。之后被调用。n Remove:当客户端调用标注了当客户端调用标注了Remove注释的方法时,容注释的方法时,容器将在方法执行结束后把器将在方法执行结束后把bean实例删除。实例删
9、除。132.9 Session Bean的生命周期事件的生命周期事件142.9 Session Bean的生命周期事件的生命周期事件15162.10 拦截器拦截器(Interceptor) n 拦截器可以拦截拦截器可以拦截Session bean和和message-driven bean的方法调用或生命周期事件。的方法调用或生命周期事件。n 拦截器用于封装应用的公用行为,使这些行为与业务拦截器用于封装应用的公用行为,使这些行为与业务逻辑分离,一旦这些公用行为发生改变,而不必修改逻辑分离,一旦这些公用行为发生改变,而不必修改很多业务类。很多业务类。n 拦截器可以是同一拦截器可以是同一bean类中
10、的方法或是一个外部类。类中的方法或是一个外部类。172.10 拦截器拦截器(Interceptor)n Interceptors 注释指定一个或多个在外部类中定义的拦截器,注释指定一个或多个在外部类中定义的拦截器,多个拦截器类之间用逗号分隔,如:多个拦截器类之间用逗号分隔,如:q Interceptors(A.class,B.class,C.class),如果只有一个拦截器可,如果只有一个拦截器可以省略大括号。以省略大括号。182.10 拦截器拦截器(Interceptor)AroundInvoke注释指定了要用作拦截器的方法,拦截器方法与被拦截的业务方法注释指定了要用作拦截器的方法,拦截器方
11、法与被拦截的业务方法执行在同一个执行在同一个java调用堆栈、同一个事务和安全上下文中。调用堆栈、同一个事务和安全上下文中。用用AroundInvoke注释指定的方法必须遵守以下格式:注释指定的方法必须遵守以下格式:public Object XXX(erceptor.InvocationContext ctx) throws ExceptionXXX代表方法名可以任意代表方法名可以任意erceptor.InvocationContext封装客户端所调用业务方法的一些信息封装客户端所调用业务方法的一些信息192.10 拦截器拦截器(Interceptor)2
12、02.10 拦截器拦截器(Interceptor)212.11 依赖注入依赖注入(dependency injection)n 在实际应用中,在实际应用中,EJB可能会使用到其它可能会使用到其它EJB或资源。或资源。n 在传统的开发中,我们要使用某个类对象,可以通过在传统的开发中,我们要使用某个类对象,可以通过new object的方式来使用它。的方式来使用它。q 但在但在EJB中,不能这样做,因为中,不能这样做,因为EJB实例的创建及销毁是由容器管实例的创建及销毁是由容器管理的。理的。n 要在要在bean中要用其它中要用其它EJB,必须通过,必须通过JNDI查找或注入注释。查找或注入注释。q
13、 如在如在InjectionBean中使用中使用HelloBean EJB,需要在,需要在InjectionBean中通过中通过JNDI查找查找HelloBean的引用的引用222.11 依赖注入依赖注入(dependency injection)n 通过注入注释通过注入注释232.11 依赖注入依赖注入(dependency injection)n 通过通过ejb-jar.xml 添加注册项,该文件需放在添加注册项,该文件需放在 jar的的 META-INF 24Bean 类:类:InjectionBean.java 252.11.1 资源类型的注入资源类型的注入n 如何注入数据源如何注入数
14、据源?q “DefaultMySqlDS”是数据源的局部是数据源的局部 JNDI 名称,只供名称,只供 Jboss 容容器内的应用访问。器内的应用访问。 q 查找该局部查找该局部 JNDI 名称时,需要带有前缀名称时,需要带有前缀“java:/”。 262.11.1 资源类型的注入资源类型的注入272.12 定时服务定时服务(Timer Service)n 定时服务可以用在定时服务可以用在stateless session bean和和message-driven bean,当某个,当某个stateless session bean或或message-driven bean的定时器启动时,容器
15、会从实例池中选择的定时器启动时,容器会从实例池中选择bean的一个实的一个实例,然后调用其例,然后调用其timeout回调方法。回调方法。n 可以使用可以使用Resource注释注入定时服务,或者使用容器对象注释注入定时服务,或者使用容器对象SessionContext创建定时器。创建定时器。n 下面例子在下面例子在session bean中定义一个定时器,每隔中定义一个定时器,每隔3秒钟触发秒钟触发一次事件,当定时事件触发一次事件,当定时事件触发5次的时候便终止定时器的执行。次的时候便终止定时器的执行。282.12 定时服务定时服务(Timer Service)292.12 定时服务定时服务
16、(Timer Service)n 当定时器创建完成后,我们还需要添加定时事件的当定时器创建完成后,我们还需要添加定时事件的回调方法。回调方法回调方法。回调方法使用使用javax.ejb.Timeout注释标注,必须返回注释标注,必须返回void,并接受一个,并接受一个javax.ejb.Timer类型的参数,回调方法声明的格式:类型的参数,回调方法声明的格式:q void XXX(Timer timer)q 在定时事件发生时,此方法将被执行。在定时事件发生时,此方法将被执行。30JSP 客户端代码:客户端代码:TimerServiceTest.jsp 312.13 安全服务安全服务(Secur
17、ity service)n 使用使用Java验证和授权服务(验证和授权服务(Java Authentication Authorization Services JAAS)可以很好地解决上面)可以很好地解决上面的问题,可以用它来管理应用程序的安全性。的问题,可以用它来管理应用程序的安全性。q 验证(验证(Authentication)认证是完成用户名和密码的匹配校验;)认证是完成用户名和密码的匹配校验;其校验的对象是试图访问受保护系统的用户。在进行校验时,其校验的对象是试图访问受保护系统的用户。在进行校验时,应用服务器会检查用户是否存在于系统之中,是否提供了凭证应用服务器会检查用户是否存在于系
18、统之中,是否提供了凭证(通常指密码)。(通常指密码)。q 授权(授权(authorization)用户一旦通过了系统验证,需要与系统)用户一旦通过了系统验证,需要与系统进行某种形式的交互。授权就是决定用户是否有权执行某项操进行某种形式的交互。授权就是决定用户是否有权执行某项操作的过程,授权是基于角色的。作的过程,授权是基于角色的。322.13 安全服务安全服务(Security service)n Jboss服务器提供了安全服务来进行用户认证和根据用户规则服务器提供了安全服务来进行用户认证和根据用户规则来限制对来限制对POJO的访问。的访问。q 对每一个对每一个POJO来说,可以使用来说,可以
19、使用SecurityDomain注释为它指定注释为它指定一个安全域,安全域告诉容器到哪里去找密码和用户角色列表。一个安全域,安全域告诉容器到哪里去找密码和用户角色列表。q Plain Old Java Objects,简单的,简单的Java对象,就是普通对象,就是普通JavaBeans,是为了避免和,是为了避免和EJB混淆所创造的简称。混淆所创造的简称。n JBoss中的中的other域指明要到域指明要到classpath下寻找下寻找pertes和和perties。q 对每一个方法来说,我们可以使用一个安全限制注释来指定谁可对每一个方法来说,我们可以使用一个
20、安全限制注释来指定谁可以运行这个方法以运行这个方法332.13 安全服务安全服务(Security service)n 本例使用本例使用Jboss默认的安全域默认的安全域“other”,“other”安全域告诉安全域告诉容器到容器到classpath下的下的perties和和perties中中寻找密码和用户角色列表。寻找密码和用户角色列表。n “other”安全域定义安全域定义q jboss安装目录安装目录/server/default/conf/login-config.xml文件中文件中342.13 安全服务安全服务(Security service)3
21、52.13 安全服务安全服务(Security service)下面我们开始安全服务的具体开发:下面我们开始安全服务的具体开发:n 第一步,定义安全域,安全域的定义有两种方法:第一步,定义安全域,安全域的定义有两种方法:n 第一种方法:通过第一种方法:通过 Jboss 部署描述文件部署描述文件 jboss.xml 进行定义进行定义(本例采用的方法本例采用的方法) 指定我们使用的安全域是指定我们使用的安全域是“other”,AnonymousUser节点指定允许匿名用户访问。节点指定允许匿名用户访问。jboss.xml 必须必须 放进放进 Jar 文件的文件的 META-INF 目录。目录。36
22、2.13 安全服务安全服务(Security service)372.13 安全服务安全服务(Security service)第三步,为业务方法定义访问角色(后台)。第三步,为业务方法定义访问角色(后台)。n RolesAllowed 注释指定允许访问方法的角色列表,注释指定允许访问方法的角色列表,如果角色存在多个,可以用逗号分隔。如果角色存在多个,可以用逗号分隔。n PermitAll 注释指定注释指定 任何角色都可以访问此方法。任何角色都可以访问此方法。382.13 安全服务安全服务(Security service)392.13 安全服务安全服务(Security service)40
23、2.13 安全服务安全服务(Security service)412.13.1 自定义安全域自定义安全域n 把用户名把用户名/密码及角色存放在密码及角色存放在pertes和和perties文件,不便于日后的管理。文件,不便于日后的管理。n 大多数情况下都希望把用户名大多数情况下都希望把用户名/密码及角色存放在数据库中。密码及角色存放在数据库中。n 我们需要自定义安全域,下面的例子定义了一个名为我们需要自定义安全域,下面的例子定义了一个名为foshanshop的安全域,它采用数据库存储用户名及角色。的安全域,它采用数据库存储用户名及角色。422.13.1 自定
24、义安全域自定义安全域432.13.1 自定义安全域自定义安全域“DefaultMySqlDS” 数据源,数据源,principalsQuery属性指定如何通过给定的用户名获取密码,属性指定如何通过给定的用户名获取密码,rolesQuery属性指定如何通过给定的用户名获取角色列表。属性指定如何通过给定的用户名获取角色列表。注意:注意:SQL中的中的Roles常量字段不能去掉。常量字段不能去掉。unauthenticatedIdentity属性指定允许匿名用户访问。属性指定允许匿名用户访问。442.13.1 自定义安全域自定义安全域452.13.1 自定义安全域自定义安全域46第三章第三章 实体实
25、体 Bean(Entity Bean)nJboss 数据源的配置数据源的配置n单表映射的实体单表映射的实体Bean n成员属性映射成员属性映射n建议重载实体建议重载实体 Bean的的 Equals()和和 Hashcode()方法方法n映射的表名或列名与数据库保留字同名时的处理映射的表名或列名与数据库保留字同名时的处理n多表映射的实体多表映射的实体Bean n持久化实体管理器持久化实体管理器 Entity Managern关系关系/对象映射对象映射nJPQL 查询查询473.1 JBoss 数据源的配置数据源的配置n 数据源用于配置数据库的连接信息,每个数据源必须指定一个数据源用于配置数据库的
26、连接信息,每个数据源必须指定一个唯一的唯一的JNDI名称。应用通过名称。应用通过JNDI名称找到数据源。名称找到数据源。q 在在Jboss中,有一个默认的数据源中,有一个默认的数据源DefaultDS,它使用,它使用Jboss内置内置的的HSQLDB数据库。数据库。q 实际项目中,可能使用不同的数据库,如实际项目中,可能使用不同的数据库,如MySql、SqlServer、Oracle等。等。n 每种数据库的数据源配置模版可以在每种数据库的数据源配置模版可以在Jboss安装目安装目录录docsexamplesjca目录中找到,名称为:数据库名目录中找到,名称为:数据库名+-ds.xml。483.
27、1 JBoss 数据源的配置数据源的配置n 数据源部署的过程很简单,直接把它拷贝到数据源部署的过程很简单,直接把它拷贝到jboss的的deploy目目录即可。录即可。n 容器遇到以容器遇到以*-ds.xml结尾的文件时,会进行动态发布。发布完结尾的文件时,会进行动态发布。发布完成后,你可以在成后,你可以在http:/localhost:8080/jmx-console/查看到数查看到数据源的信息据源的信息493.1 JBoss 数据源的配置数据源的配置503.1 JBoss 数据源的配置数据源的配置n 数据源配置文件的取名格式必须为数据源配置文件的取名格式必须为xxxds.xml,其中,其中x
28、xx代表代表任意名称,如任意名称,如:mysql-ds.xml,mssqlserver-ds.xml,oracle-ds.xml。n 数据源部署前,必须把数据库驱动数据源部署前,必须把数据库驱动Jar拷贝到拷贝到jboss安装目安装目录录/server/配置名配置名/lib目录,本书采用的配置名为目录,本书采用的配置名为default,因此,因此需要把数据库驱动拷贝到需要把数据库驱动拷贝到jboss安装目录安装目录/server/default/lib。完成拷贝后,必须重启完成拷贝后,必须重启Jboss服务器。服务器。n 本书使用的数据库是本书使用的数据库是mysql-5.0.22,其驱动为,
29、其驱动为mysql-connector-java-3.1.13-bin.jar。513.2 单表映射的实体单表映射的实体 Beann 在本例子,该表由持久化驱动自动生成,不需要我们创建。在本例子,该表由持久化驱动自动生成,不需要我们创建。 523.2 单表映射的实体单表映射的实体 Bean53Session Bean 的业务接口的业务接口 n 在在EJB3.0,实体,实体Bean并不直接与客户端打并不直接与客户端打交道。而是被交道。而是被Session bean或或Message-Driven Bean使用。使用。n 定义一个定义一个Session Bean,在,在Session Bean中通
30、过实体中通过实体bean间接操作数据库。间接操作数据库。54Session Bean的实现的实现 Database name55Session Bean的实现的实现 Database nameem.find()方法用于查找方法用于查找特定主键的实体特定主键的实体bean。em.persist()方法用于保存实方法用于保存实体体bean,即插入一条记录。,即插入一条记录。em.merge()方法用于更新或保存实体方法用于更新或保存实体 当实体不存在时,执行保存操作当实体不存在时,执行保存操作 当实体已经存在时,执行更新操作当实体已经存在时,执行更新操作em.remove()方法用于删除实体,方法
31、用于删除实体,即删除一条记录。即删除一条记录。em.createQuery()用于执行用于执行JPQL语句。语句。56 JSP 客户端代码:客户端代码:EntityBeanTest.jsp 573.6 多表映射的实体多表映射的实体Beann 如果实体的成员属性映射的字段分布在多张表中,如何处理?如果实体的成员属性映射的字段分布在多张表中,如何处理?q 本例子的实体本例子的实体MainTable具有四个成员属性:具有四个成员属性:id、name、address和和postcode。q 其中与其中与id和和name映射的字段在映射的字段在MainTable表,与表,与address和和postco
32、de属性映射的字段在属性映射的字段在Address表。表。q 需要使用需要使用javax.persistence.SecondaryTable注释和注释和Column.table()属性属性583.6 多表映射的实体多表映射的实体BeanMainTable.class593.6 多表映射的实体多表映射的实体Bean603.6 多表映射的实体多表映射的实体Bean重载实体重载实体 equals() 方法方法重载实体重载实体 hashCode()方法方法重载实体重载实体 toString() 方法方法613.6 多表映射的实体多表映射的实体BeanMultitableMappingDAO.java
33、n实体实体Bean的使用者的使用者Session Bean623.6 多表映射的实体多表映射的实体BeanMultitableMappingDAOBean.class633.6 多表映射的实体多表映射的实体BeanMultitableMappingTest.jsp643.6 多表映射的实体多表映射的实体Bean653.8 关系关系/对象映射对象映射n双向一对多及多对一映射双向一对多及多对一映射n单向一对多单向一对多n单向多对一单向多对一n双向一对一映射双向一对一映射n单向一对一单向一对一n双向多对多映射双向多对多映射n单向多对多单向多对多663.8.1 双向一对多及多对一映射双向一对多及多对一
34、映射n 现实应用中存在很多一对多的情况,如一项订单中存在一个或现实应用中存在很多一对多的情况,如一项订单中存在一个或多个订购项。多个订购项。n 当当one方存在与方存在与many方关系的定义,而方关系的定义,而many方同时也存在与方同时也存在与one方关系的定义,这样的关系被称为双向关系。方关系的定义,这样的关系被称为双向关系。n 代码上体现为在代码上体现为在one方有一个集合属性指向方有一个集合属性指向many方,而在方,而在many方也有一个属性指向方也有一个属性指向one方。方。673.8.1 双向一对多及多对一映射双向一对多及多对一映射n 双向一对多关系,必须包含一个关系维护端。持久
35、化规范要求双向一对多关系,必须包含一个关系维护端。持久化规范要求多多的一方为关系维护端(的一方为关系维护端(ownerside),),一一的一方为关系被维的一方为关系被维护端(护端(inverseside)。)。n 在在one方的方的OneToMany注释设置注释设置mappedBy属性,以指定属性,以指定它是这一关联中的被维护端,它是这一关联中的被维护端,Many方是关系维护端。方是关系维护端。683.8.1 双向一对多及多对一映射双向一对多及多对一映射Order.java 693.8.1 双向一对多及多对一映射双向一对多及多对一映射指明指明Order与与OrderItem关联关系为一对多关
36、系关联关系为一对多关系703.8.1 双向一对多及多对一映射双向一对多及多对一映射713.8.1 双向一对多及多对一映射双向一对多及多对一映射OrderItem.java 变量变量定义定义 构造构造函数函数 723.8.1 双向一对多及多对一映射双向一对多及多对一映射733.8.1 双向一对多及多对一映射双向一对多及多对一映射public interface ManyToOneClass targetEntity( ) default void.class; CascadeType cascade( ) default ; FetchType fetch( ) default EAGER; b
37、oolean optional( ) default true;targetEntity()、cascade()和和fetch()的具体含义和的具体含义和OneToMany注释的同名属性相同,但注释的同名属性相同,但ManyToOne注释的注释的fetch()属性默认值是属性默认值是FetchType.EAGER。optional()指定关联方是否可以为空指定关联方是否可以为空(null),该属性值默认为,该属性值默认为true。若将其设为若将其设为false,则要求双方必须存在。,则要求双方必须存在。我们不需要设置我们不需要设置JoinColumn注释的注释的nullable()属性。属性。
38、通过通过EntityManager.find()、EntityManager.getReference()查询查询OrderItem实体:实体:u 当当optional=false时,时,OrderItem与与Order关联形式为关联形式为inner join,u 当当optional=true时,时,OrderItem与与Order关联形式为关联形式为left join。743.8.1 双向一对多及多对一映射双向一对多及多对一映射n SessionBean的业务接口:的业务接口:OrderDAO.java753.8.1 双向一对多及多对一映射双向一对多及多对一映射n SessionBean的
39、业务接口:的业务接口:OrderDAOBean.java76JSP 客户端代码:客户端代码:OneToManyTest.jsp773.8.1 双向一对多及多对一映射双向一对多及多对一映射OrderItem表表Order表表783.8.2 单向一对多单向一对多Order.java 793.8.2 单向一对多单向一对多OrderItem.java 803.8.3 单向多对一单向多对一Order.java 813.8.3 单向多对一单向多对一指明指明Order与与OrderItem关联关系为一对多关系关联关系为一对多关系Order.java 823.8.3 单向多对一单向多对一OrderItem.j
40、ava 833.8.3 单向多对一单向多对一OrderItem.java 保持不变!保持不变!843.8.6 双向多对多映射双向多对多映射n 实现生活中,一个学生有多个老师,一个老师有多个学生,他实现生活中,一个学生有多个老师,一个老师有多个学生,他们具有明显的多对多关系。们具有明显的多对多关系。q 多对多映射采取中间表连接的映射策略,建立的中间表将分别引多对多映射采取中间表连接的映射策略,建立的中间表将分别引入两边的主键作为外键。入两边的主键作为外键。q EJB3对于中间表的元数据提供了可配置的方式,用户可以自定义对于中间表的元数据提供了可配置的方式,用户可以自定义中间表的表名、列名。中间表
41、的表名、列名。studentteacherteacher-student*853.8.6 双向多对多映射双向多对多映射n Student.java863.8.6 双向多对多映射双向多对多映射n Student.java在双向在双向ManyToMany关联中,必须包含有一个关系维护端。关联中,必须包含有一个关系维护端。在在Student的的ManyToMany注释中指定注释中指定mappedBy()属性,属性,将其标识为关系将其标识为关系被被维护端,自然维护端,自然Teacher就成了关系维护端。就成了关系维护端。ManyToMany注释指定注释指定Student是多对多关系的一端,是多对多关系
42、的一端,mappedBy属性指定属性指定Student为双向关系的被维护端为双向关系的被维护端(inverse side),指出该关,指出该关系映射信息是在被关联实体系映射信息是在被关联实体Teacher的成员属性的成员属性students上定义的。上定义的。873.8.6 双向多对多映射双向多对多映射n Teacher.java883.8.6 双向多对多映射双向多对多映射n Teacher.java893.8.6 双向多对多映射双向多对多映射n TeacherDAO.java903.8.6 双向多对多映射双向多对多映射n TeacherDAOBean.java913.8.6 双向多对多映射双
43、向多对多映射n TeacherDAOBean.java923.8.6 双向多对多映射双向多对多映射n ManyToManyTest.jspteacherteacher_studentstudent933.8.7 单向多对多单向多对多n Teacher.java943.8.7 单向多对多单向多对多n Teacher.java953.8.7 单向多对多单向多对多n Student.java963.8.7 单向多对多单向多对多n Student.java973.9 JPQL查询查询n 命名参数查询命名参数查询n 位置参数查询位置参数查询n Date参数参数n 一个一个JPQL查询例子查询例子n 命名
44、查询命名查询n 排序排序(order by)n 查询部分属性查询部分属性n 查询中使用构造器查询中使用构造器(Constructor)n 聚合查询聚合查询(Aggregation)n 关联关联(join)n 排除相同的记录排除相同的记录DISTINCTn 比较比较Entityn 批量更新批量更新(Batch Update)n 批量删除批量删除(Batch Remove)n 逻辑非运算符逻辑非运算符NOTn 使用操作符使用操作符BETWEENn 使用操作符使用操作符INn 使用操作符使用操作符LIKEn 使用操作符使用操作符IS NULLn 使用操作符使用操作符IS EMPTYn 字符串函数字符
45、串函数n 日期和时间函数日期和时间函数n 数学函数数学函数n Member ofn 子查询子查询n EXISTSn All, ANY, SOMEn 结果集分页结果集分页98实例数据库实例数据库Person表表Order表表OrderItem表表99(1) 命名参数查询命名参数查询n 命名参数的格式为冒号加上参数名:命名参数的格式为冒号加上参数名:“:+参数名参数名”100(2) 位置参数查询位置参数查询n 位置参数的格式为问号加上位置编号:位置参数的格式为问号加上位置编号:“?+位置编号位置编号”101(3) Date参数参数n 如果需要将如果需要将 java.util.Date 或或 jav
46、a.util.Calendar 作为参数传作为参数传进一个参数查询,使用对应的进一个参数查询,使用对应的 setParameter()方法方法102Person.java 103Person.java104Person.javaOrder表表105Order.java106Order.java107OrderItem.java108OrderItem.javaOrder表表109QueryDAOBean.javaPerson表表Order表表OrderItem表表110QueryDAOBean.java111 JSP客户端代码:客户端代码:QueryTest.jsp 112(5) 命名查询命名
47、查询n 你可以在实体你可以在实体bean上定义一个或多个查询语句,这样可以减少上定义一个或多个查询语句,这样可以减少每次因书写错误而引起的每次因书写错误而引起的BUG。n 实际应用中,一般把经常使用的查询语句定义成命名查询。实际应用中,一般把经常使用的查询语句定义成命名查询。当命名查询定义好了之后,我们可以通过其名称执行查询:当命名查询定义好了之后,我们可以通过其名称执行查询:113(5) 命名查询命名查询n 如果需要定义多个命名查询,可以使用如果需要定义多个命名查询,可以使用javax.persistence.NamedQueries注释。注释。n 在该注释里面,可以放置多个在该注释里面,可
48、以放置多个NamedQuery注释:注释:当命名查询定义好了之后,我们可以通过其名称执行查询:当命名查询定义好了之后,我们可以通过其名称执行查询:114(6) 排序排序(order by)n ASC和和DESC分别为升序和降序,如果不显式指定,分别为升序和降序,如果不显式指定,JPQL默认使用默认使用ASC升序。升序。(QueryDAOBean.java)115(7) 查询部分属性查询部分属性(QueryDAOBean.java)n 在前面的例子中,都是针对实体的查询,返回的结果也是实体在前面的例子中,都是针对实体的查询,返回的结果也是实体类型。类型。JPQL允许查询返回我们需要的成员属性。在
49、一些实体成允许查询返回我们需要的成员属性。在一些实体成员属性比较多的情况,这样的查询可以提高性能。员属性比较多的情况,这样的查询可以提高性能。116(8) 查询中使用构造器查询中使用构造器(Constructor)n JPQL支持将查询的结果直接作为一个支持将查询的结果直接作为一个Java类的构造器参数,类的构造器参数,并产生类对象作为结果返回。并产生类对象作为结果返回。117(8) 查询中使用构造器查询中使用构造器(Constructor)n 将查询的属性结果直接作为将查询的属性结果直接作为 SimplePerson 的构造器参数。的构造器参数。 118(9) 聚合查询聚合查询(Aggreg
50、ation)n像大部分的像大部分的SQL一样,一样,JPQL也支持查询中的聚合函数:也支持查询中的聚合函数:nAVG()求平均数,返回值类型为求平均数,返回值类型为Double;nSUM()求和,返回值类型为被求值的成员属性所对应的类型;求和,返回值类型为被求值的成员属性所对应的类型;nCOUNT()统计,返回类型为统计,返回类型为Long,注意,注意count(*)语法并不属语法并不属于于JPA规范,它在规范,它在hibernate中可用;中可用;nMAX()求最大值,返回值类型为被求值的成员属性所对应的类求最大值,返回值类型为被求值的成员属性所对应的类型。可用于基本数据类型,字符串及可序列
51、化对象;型。可用于基本数据类型,字符串及可序列化对象;nMIN()求最小值,返回值类型为被求值的成员属性所对应的类求最小值,返回值类型为被求值的成员属性所对应的类型。可用于基本数据类型,字符串及可序列化对象。型。可用于基本数据类型,字符串及可序列化对象。q聚合函数在统计时,会忽略掉带聚合函数在统计时,会忽略掉带null值的记录。值的记录。1.如果查询的集合为空(即没有记录),如果查询的集合为空(即没有记录),count()在处理时会返回在处理时会返回0,而而AVG()、SUM()、MAX()、MIN()返回返回null值。值。119(9) 聚合查询聚合查询(Aggregation)120(9)
52、 聚合查询聚合查询(Aggregation)n 和和SQL一样,如果聚合函数不是一样,如果聚合函数不是select.from的唯一一个返回的唯一一个返回列,需要使用列,需要使用GROUPBY语句。语句。121/去掉相同的编号去掉相同的编号(10)关联关联(join)n left out join/left join等,都是允许右边表达式的实体为空。等,都是允许右边表达式的实体为空。OrderOrderItem122(10)关联关联(join)n inner join 要求右边表达式的实体必须存在。要求右边表达式的实体必须存在。OrderOrderItem123(10)关联关联(join)n l
53、eft/left out/inner join fetch 提供了一种灵活的查询加载方式来提供了一种灵活的查询加载方式来提高查询的性能。提高查询的性能。n 在默认的查询中,实体的延迟属性不会被加载。在默认的查询中,实体的延迟属性不会被加载。 当应用需要时,当应用需要时,EJB3 Runtime才会执行一条才会执行一条SQL语句来加语句来加载属于当前载属于当前Order的的OrderItems。使用了使用了fetch,这个查询只会产生一条,这个查询只会产生一条 SQL 语句。语句。124(11) 排除相同的记录排除相同的记录Distinctn 使用关联查询,我们很经常得到重复的对象,如下面语句:
54、使用关联查询,我们很经常得到重复的对象,如下面语句:select o from Order o inner join fetch o.orderItems order by o.orderidq 如果一个如果一个Order有多个有多个orderItem,返回的结果就会有多个相同返回的结果就会有多个相同的的Order,需要使用,需要使用Distinct关键字排除相同的对象。关键字排除相同的对象。q Distinct 操作符还可以与任何聚合函数结合使用,首先去掉重复值,操作符还可以与任何聚合函数结合使用,首先去掉重复值,然后再统计。然后再统计。125(12) 比较比较Entityn 在使用参数查询
55、时,参数类型除了在使用参数查询时,参数类型除了String、原始数据类型、原始数据类型(int, double等等)和它们的对象类型和它们的对象类型(Integer, Double等等),也可以是实体对象。,也可以是实体对象。126(13)批量更新批量更新(Batch Update)Order表表(修改前修改前)127(14) 批量删除批量删除(Batch Remove)128(15) 逻辑非运算符逻辑非运算符NOT129(16) 使用操作符使用操作符BETWEEN130(17) 使用操作符使用操作符IN131(18) 使用操作符使用操作符LIKE132(19) 使用操作符使用操作符IS NU
56、LL133(20) 使用操作符使用操作符IS EMPTY134(21) 字符串函数字符串函数n CONCAT(string 1, string 2)q 将字符串将字符串2追加到字符串追加到字符串1。n SUBSTRING(string, starting position, length)q 从字符串从字符串string开始位置开始位置starting position截取长度为截取长度为length字符。字符。n LOWER(string)q 将一个字符串将一个字符串string转换成小写形式。转换成小写形式。n UPPER(string)q 将一个字符串将一个字符串string转换成大写形
57、式。转换成大写形式。n LENGTH(string)q 返回字符串返回字符串string的长度,为整数。的长度,为整数。n TRIM(LEADING|TRAILING|BOTH char FROM string)q 去掉字符串去掉字符串string头,尾或两者的字符头,尾或两者的字符char。最简形式是。最简形式是TRIM(string),可,可以去掉字符串以去掉字符串string头尾的空格字符。头尾的空格字符。n LOCATE(string1, string2 ,start)q 返回返回string2在在string1的位置。定位函数有一个可选的起始位置的位置。定位函数有一个可选的起始位置s
58、tart。135(21) 字符串函数字符串函数136(23) 数学函数数学函数n ABS (arithmetic expression)q 返回算术表达式的返回算术表达式的绝对值绝对值。n SQRT (arithmetic expression)q 求算术表达式的求算术表达式的方根方根,返回一个,返回一个Double。n MOD (arithmetic expression 1, arithmetic expression 2)q 求参数求参数1与参数与参数2的的模模,返回一个整数。,返回一个整数。n SIZE (collection-valued path-expression)q 计算一个
59、集合中元素的计算一个集合中元素的数量数量,并返回一个整数。,并返回一个整数。q 如果集合为空,返回如果集合为空,返回0。137(23) 数学函数数学函数138(24) Member ofn Member of操作符用于判断实体是否是集合中的一员。操作符用于判断实体是否是集合中的一员。 139(25) 子查询子查询n 子查询可以用于子查询可以用于WHERE和和HAVING条件语句中。条件语句中。140(26) EXISTSn EXISTS需要和子查询配合使用,用来判断子查询是否存在记录。需要和子查询配合使用,用来判断子查询是否存在记录。141(26) EXISTSn EXISTS需要和子查询配合
60、使用,用来判断子查询是否存在记录。需要和子查询配合使用,用来判断子查询是否存在记录。142(27) All, ANY, SOMEn 当子查询返回多条记录时,你可以使用表达式当子查询返回多条记录时,你可以使用表达式ALL、ANY和和SOME对结果做进一步限定。对结果做进一步限定。143(28) 结果集分页结果集分页n 有些时候执行一个查询会返回成千上万条记录,事实上我们只有些时候执行一个查询会返回成千上万条记录,事实上我们只需要显示其中一部分数据,这时我们需要对结果集进行分页。需要显示其中一部分数据,这时我们需要对结果集进行分页。n QueryAPI有两个接口方法可以解决这个问题:有两个接口方法
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论