EJB3.0开发之多对多和一对一

合集下载

程序员应用EJB 3.0必要的准备

程序员应用EJB 3.0必要的准备

程序员应用EJB 3.0必要的准备EJB 3.0极其重视开发的简易性,并调整了模型。

这绝非巧合,因为规范的主要设计者:Linda DeMichiel选择了广泛听取外界的意见,并借鉴TopLink等产品所取得的经验。

这样一来,这项规范就可以沿着已经由流行、得到公认的技术开辟出来的道路前进,而这些道路实际上成了业内事实上的最佳实践。

那么,作为程序员的你,面对新的规范,该做哪些准备呢?处理好架构问题首先要确保你的架构可以利用持久性方面的标准及认可的设计模式。

实际上,这可能需要改动你的应用程序,不过如果你期望应用程序能经得起时间的考验,那么进行这种投入是值得的。

使用会话外观、数据访问对象(DAO)层或者服务层总是好主意,不过在这里它们都至关重要。

如果你的应用程序已经使用远程实体构建而成——虽然这种做法并不常见,那么就需要重新设计架构。

访问持久性对象之前,应当先部署可远程化服务层。

如果要使用实体,它就应当完全是本地实体。

不过,使用本地实体不是目的,因为实体还为部署人员提供了为实体声明事务和安全需求的功能。

EJB 3.0不允许任何这些属性在实体层面进行设定。

相反,实体的运行环境将由调用者来确定,所以所需的任何事务或者安全环境将由负责封闭的J2EE组件来安装或者声明。

CMP应用程序如果你已经是容器管理持久性(CMP)用户,那么你可能迫不及待地想获得新特性,希望抛弃无关的接口、不必要的bean代码以及繁琐的XML部署描述符,这些是与以前的实体bean 开发相关的一些烦人问题。

分别要扩展EJBObject和EJBLocalObject的远程和本地接口再也不需要了;现在实体只要实现普通Java接口(POJI)即可,如果它们选择这么做的话。

其次,你可能在想如何更容易地在容器中部署EJB,或者甚至根本不用部署,而是在独立环境中的容器外面进行测试。

因为实体是具体的普通Java对象(POJO),你就可以像一直以来创建Java对象的方式那样,即使用new()来创建。

Java企业级应用开发:EJB和Hibernate

Java企业级应用开发:EJB和Hibernate

Java企业级应用开发:EJB和Hibernate第一章:介绍1.1 Java企业级应用开发概述Java企业级应用开发是指使用Java编程语言开发大型、复杂的企业级应用程序。

这些应用程序通常需要处理大量的数据和复杂的业务逻辑,而且需要满足高性能、可扩展性、可靠性和安全性等要求。

1.2 EJB和Hibernate的作用EJB(Enterprise JavaBean)是一种用于开发分布式应用程序的Java组件模型,它提供了事务管理、远程访问、消息传递等功能,可以帮助开发人员更方便地构建可重用的企业级组件。

Hibernate是一个开源的对象关系映射(ORM)框架,它可以将Java对象和关系数据库中的数据进行映射,使开发人员可以使用面向对象的方式来操作数据库,大大简化了开发流程。

本章将对EJB和Hibernate进行详细介绍,包括它们的特点、优势和适用场景等。

第二章:EJB2.1 EJB的概述EJB是一种Java组件模型,它定义了一套规范,用于开发分布式应用程序。

EJB 提供了事务管理、远程访问、消息传递等功能,可以帮助开发人员更方便地构建可重用的企业级组件。

2.2 EJB的特点和优势EJB具有以下特点和优势:(1)分布式事务管理:EJB提供了容器管理的事务机制,可以确保分布式应用程序中的事务一致性。

(2)远程访问:EJB可以通过RMI(Remote Method Invocation)协议实现远程访问,使得应用程序可以跨越网络边界进行通信。

(3)消息传递:EJB支持JMS(Java Message Service)协议,可以实现异步消息传递,提高系统的响应速度和可靠性。

(4)安全性:EJB提供了基于角色的访问控制机制,可以对应用程序的资源进行细粒度的权限控制。

2.3 EJB的适用场景EJB适用于需要面对复杂业务逻辑、大量数据处理和分布式部署的企业级应用程序。

例如,电子商务系统、银行系统、物流管理系统等。

EJB

EJB


EJB 2.0解决了EJB 1.0中强制远程访问支持带来的系统开销 和性能下降问题,EJB 2.0规范引入了本地接口的概念,它允许开 发者自己决定是否要让EJB组件支持远程访问,如果EJB组件不需 要支持远程访问,让Bean实现类实现本地接口即可,这就可以避 免远程访问支持带来的系统开销和性能下降。 EJB 2.0增强了实体Bean的功能,它为CMP(容器管理持久 化)的EJB提供了容器管理关系(CMR)的支持,允许开发者通过 配置文件来管理EJB之间的关联关系。而且还引入了EJB查询语言: EJB-QL,EJB-QL正式为实体Bean提供了查询支持。不幸的是, EJB-QL的功能似乎不如原生SQL强大,往往对开发者形成某种制 约。 EJB 2.0规范的另一个亮点是:消息驱动Bean(MDB),消 息驱动Bean本质上与无状态的会话Bean相同。只是它无须远程接 口,因此它不能被客户机调用。但客户机组件可通过向消息目的 发送消息来触发MDB的onMessage方法。

POJO + annotation
EJB2.1架构图
EJB3.0架构图

Session Bean (会话bean)
◦ Stateful(有状态) ◦ Stateless(无状态)


Message Driven bean(消息驱动bean) Entity Bean(实体bean)

会话bean可以无状态,也可以有状态 有状态bean可以记住方法调用之间的会话状态 无状态bean对于方法的调用之间的客户情况则是什 么也记不住(注:无状态不是真的没有状态,他也是 可以有状态,只不过是不是客户特定的状态)


EJB 2.1增加了Web Service支持,增加Web Service支持后的EJB更有利于异构系统的整合。不 仅如此,EJB 2.1还增加了计时器服务,允许按指定 时间或固定间隔来调用EJB的业务方法,计时器服 务可以非常方便地为系统提供任务调度的支持。 除此之外,EJB 2.1增强了EJB-QL的功能,从而提 供了更强大的查询支持。虽然EJB 2.1在努力改进 EJB-QL查询功能,但大家对EJB 2的骂声掩盖了 Sun在EJB-QL上的努力

EJB 3.0入门经典

EJB 3.0入门经典

由于无状态会话Bean 不维护会话状态,意味着一个bean 实 例可以为多个用户服务。因此EJB 容器使用实例池化技术管理 无状态会话Bean。简单的说就是:当无状态会话Bean 部署到应 用服务器时,EJB 容器会为它预先创建一些bean 实例放在对象 池。当有用户访问EJB 方法时,EJB 容器会从对象池中取出一个 实例为之服务,服务完了就回到对象池。当下一个用户再访问 EJB 方法时,EJB 容器有可能再次把该实例取出来为之服务。正 因如此,无状态会话Bean 只需要少量的实例就可以为成百上千 的用户服务,大大提高了系统性能。 由于无状态会话Bean 能够支持多个用户,并且通常在EJB 容器中共享,可以为需要大量客户的应用提供更好的扩充能力。 无状态会话Bean 比有状态会话Bean 更具性能优势,在条件允许 的情况下开发人员应该首先考虑使用无状态会话Bean。
你可以输入http://localhost:8080 进入Jboss 的欢迎主页。在 JBoss Management 栏点击“JMX Console”进入Jboss的管理平台。如 果需要输入用户名及密码,默认的用户名及密码都是admin。 如果jboss 启动出错,应检查打印在Jboss 控制台的JDK 版本是 否5.0 以上,jboss 所用的端口是否被占用(如1099,8009 ,8080 等端 口)。如果端口被占用就关闭占用此端口的进程。 如果启动时出现这样的错误:“findstr 不是内部或外部命令, 也不是可运行的程序或批处理文件”。那么应该在系统变量Path 中追加%SystemRoot%\system32;%SystemRoot%;。 最后的办法是重装机器上的JDK,祝你好运。

注意:Tomcat 目前只是Web 容器,它不能运行EJB 应用。

一对多,多对一关系映射

一对多,多对一关系映射

⼀对多,多对⼀关系映射 ⼀对多,多对⼀关系映射 现实⽣活中有很多1对多(多对1)的关系模型。

⽐如,⼀个⼈可以有0到多套房⼦,0到多辆汽车;⼀个⽗亲有0到多个孩⼦等等。

这种关系被称作1对多关系。

反过来,房⼦与⼈,汽车与⼈的关系,以及孩⼦与⽗亲的关系就是多对⼀的关系。

这⾥需要注意⼀点的是,多对⼀关系的⼀个前提是:⼀套确定的房⼦只能属于某个确定的⼈(不能属于多⼈);⼀个确定的孩⼦也只能属于某个确定的⽗亲。

下⾯我们就拿最简单的⽗亲和孩⼦的关系来说明1对多(多对1)模型的映射。

关系模型:⽗亲 vs 孩⼦(Father vs Son)。

关系映射:one-to-many反过来,关系模型:孩⼦ vs ⽗亲(Son vs Father)。

关系映射:many-to-one 很多初学者往往有这样的疑问,我什么时候需要定义映射关系呢? 答案很简单:按需求来确定。

就是说你需要哪种关系的时候就定义哪种映射,不需要的时候就可以不定义它们的关系映射了。

还是以上⾯的例⼦来说明。

如果你需要在取得孩⼦(Son)的时候,同时需要知道该孩⼦的⽗亲(Father)是谁,你就可以在孩⼦的实体类⾥定义孩⼦跟⽗亲的关系映射: @ManyToOne 。

同样,如果需要知道某⽗亲的所有孩⼦,就可以在⽗亲的实体类⾥定义⽗亲跟孩⼦的关系映射: @OneToMany 。

1.ManyToOne(多对⼀) 单向:不产⽣中间表,但可以⽤@Joincolumn(name=" ")来指定⽣成外键的名字,外键在多的⼀⽅表中产⽣!2.OneToMany(⼀对多) 单向:会产⽣中间表,此时可以⽤@onetoMany @Joincolumn(name=" ")避免产⽣中间表,并且指定了外键的名字(别看 @joincolumn在⼀中写着,但它存在在多的那个表中)3.OneToMany ,ManyToOne 双向( 两个注解⼀起⽤的):如果不在 @OneToMany 中加mappedy属性就会产⽣中间表,此时通常在 @ManyToOne 的注解下再添上注解 @Joincolumn(name=" ") 来指定外键的名字(说明:多的⼀⽅为关系维护端,关系维护端负责外键记录的更新,关系被维护端没有权利更新外键记录)!( @OneToMany(mappedBy="⼀对多中,多中⼀的属性") 出现mapby为被维护端|||默认为延迟加载)⽤例:1 @ManyToOne(fetch=ZY)2 @JoinColumn(name="child_id")3private OrderChild orderChild;45 @OneToMany(mappedBy="orderChild",fetch=ZY,cascade={CascadeType.MERGE})6 @NotFound(action=NotFoundAction.IGNORE)//代表可以为空,允许为null7private List<OrderChildGoods> goodsList; hibernate中@ManyToOne默认是⽴即加载,@OneToMany默认是懒加载但是如果加上了@NotFound之后设置的fetch=ZY是不起作⽤的,也就是设置@NotFound后变为了⽴即加载eager 下⾯举例详细说明⼀下@ManyToOne  @ManyToOne注解的这端,是多端 1.在注释@ManyToOne(cascade=CascadeType.REFRESH,optional=true)中将属性optional设置为true,这可以使得即使外键为空时仍可以向表中添加数据。

EJB3.0 开发平台配置 和 开发原理

EJB3.0 开发平台配置 和 开发原理

EJB3.0开发平台安装 and开发原理(1). 《EJB3.0开发平台配置》第一步:开发平台的搭建1、下载与安装JDK2、下载与安装Eclipse3、下载与安装JBoss第二步:运行Eclipse,新建一个普通的Java项目:4、菜单操作路径:File-New-Projcet;5、进入新建项目向导窗口,选择Java-Java Project;6、点击next,输入Project name:HelloStudy(名字可以任意取),再按Finish;7、在项目名称上面按右建选择Properties;8、单击左窗格中的Java Build Path;文件,再点击打开;择javaee.jar,再点击打开,再点击OK;11、菜单操作路径:File-New-Class12、分别输入package:com.foshanshop.ejb3,以及Name:HelloWorld后,点击Finish;的HelloWorld.java,打开该文件,按照书上的内容输入代码;14、菜单操作路径:File-New-Class15、分别输入package:com.foshanshop.ejb3.impl,以及Name:HelloWorldBean后,点击Finish;16、双击左侧框HelloStudy项目下的com.foshanshop.ejb3.impl,再双击com.foshanshop.ejb3.impl下面的HelloWorldBean.java,打开该文件,按照书上的内容输入代码;17、在HelloStudy项目上右击,选择Export,在弹出的Export对话框中选择JAR file;18、单击Next按钮,在弹出的JAR Export对话框的select the resources to export(选择要导出的资源)列表框中展开你的项目并选择需要打包的文件。

然后选择一个存放目录及文件夹名,单击Finish按钮结束打包;第七步:当项目打包成jar文件后,将它发布到Jboss:19、发布前先检查JBoss是否已经启动,如果没有启动,打开DOS命令符窗口,进入“JBoss安装目录/bin”,运行run.bat启动JBoss。

第4章EJB3.0

第4章EJB3.0

图4-1 EQL查询结果图
查询( 查询(QUERY)API )
一个查询API是Java持久化的一个开放接口,我们可以在运行期 是 持久化的一个开放接口, 一个查询 持久化的一个开放接口 间通过实体管理器来获取它。 接口的定义如下: 间通过实体管理器来获取它。Queue接口的定义如下: 接口的定义如下 Package javax.persistence; public interface Query{ public ListgetResultList(); public object getSingleResult(); public int executedate(); pubiic Query setMaxResults(int maxResult); pubiic Query setFirstResult(int startPosition); pubiic Query setHit(String hintName,Object value); pubiic Query setParameter (String name,Object value); public Query setParameter(String name,Date value, TemporalType temporalType); public Query setParameter(int position,Object value); //……等等 }
EJB3.0QL语言 语言
EJB3.0 QL主要对以下做了改进: 主要对以下做了改进: 主要对以下做了改进
批量更新和删除 连接操作 Group By从句 从句 Having从句 从句 投影 子查询 动态查询 命名参数 在SELECT从句中构造新的对象 从句中构造新的对象

第6章 EJB 3.0简介(理论)

第6章 EJB 3.0简介(理论)
4.1 JBOSS下载、安装和配置
JBoss版本为:jboss-4.2.2.GA,下载地址: 下载解压即可完成安装,在使用前需要配置环境变量
4.1 JBOSS下载、安装和配置 下载、 下载
运行JBoss安装目录bin下的run.bat启动服务
JBOSS下载、安装和配置 下载、 下载
第6章 EJB 3.0简介 章 简介
回顾
Hibernate实体对象的3种状态及相互转换 VO(值对象)和PO(持久化对象) Hibernate缓存 Hibernate类级别检索和关联级别检索策略
本章内容
J2EE分布式多层应用程序 EJB简介 EJB3.0新特性 JBoss服务器 Weblogic服务器
描述
4.3 JBOSS的配置 的配置
修改web 服务的端口号
将端口号从 8080改为8989
<Connector port="8989" address="${jboss.bind.address}" maxThreads="250" maxHttpHeaderSize="8192" emptySessionPath="true" protocol="HTTP/1.1" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" />
1.2 J2EE容器 容器
容器(Container)是组件和支持组件功能的底层特定平台(如数据库) 之间的接口 J2EE容器的分类
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

EJB3.0开发之多对多和一对一在前面的例子中,我们演示了一对多和多对一的例子,在本章将演示多对多和一对一的关系。

学生和老师就是多对多的关系。

一个学生有多个老师,一个老师教多个学生。

学生和档案就是一对一的关系(不知道国外的学生有没有档案?)。

为了实现多对多的关系,数据库中需要关联表,用以在两个实体间建立关联。

JBoss可以自动生成关联表,你也可以@AssociationTable来指定关联表的信息。

如:@ManyToMany(cascade = {CascadeType.CREATE, CascadeType.MERGE}, fetch = FetchType.EAGER, isInverse = true)@AssociationTable(table = @Table(name = "STUDENT_TEACHER"),joinColumns = {@JoinColumn(name = "TEACHER_ID")},inverseJoinColumns = {@JoinColumn(name = "STUDENT_ID")})@ AssociationTable的注释声明如下:@Target({METHOD, FIELD})public @interface AssociationTable {Table table() default @Table(specified=false);JoinColumn[] joinColumns() default {};JoinColumn[] inverseJoinColumns() default {};}关联表注释指定了关联表的名称、主表的列和从表的列。

为了实现一对一的关系,需要用@OneToOne来注释。

如:@OneToOne(cascade = {CascadeType.ALL})@JoinColumn(name = "DOS SIER_ID")public Dossier getDossier(){return dossier;}这定义了一个单向的一对一的关系。

如果在Dossier也定义了相关的关联,那么它就是双向的。

双向的意思就是通过一个Student实体就可以查找到一个Dossier,通过一个Dossier 就可以查找到一个Student。

@ OneToOne的注释声明如下:@Target({METHOD, FIELD}) @Retention(RUNTIME)public @interface OneToOne {String targetEntity() default "";CascadeType[] cascade() default {};FetchType fetch() default EAGER;boolean optional() default true;}这个例子主要有以下几个文件,这个例子主要实现了学生和老师、学生和档案之间的关系。

Student、Teacher、Dossier都是实体Bean。

Student和Dossier是一个双向的OneToOne 之间的关系,Student和Teacher是ManyToMany的关系,也是双向的。

和前面的例子一样,我们还是使用Client测试。

Student.java:实体Bean。

Dossier.java:实体Bean所依赖的类。

Teacher.java:实体Bean所依赖的类。

EntityTest.java:会话Bean的业务接口EntityTest Bean.java:会话Bean的实现类Client.java:测试EJB的客户端类。

jndi.properties:jndi属性文件,提供访问jdni的基本配置属性。

Build.xml:ant 配置文件,用以编译、发布、测试、清除EJB。

下面针对每个文件的内容做一个介绍。

Student.javapackage com.kuaff.ejb3.relationships;import javax.ejb.CascadeType;import javax.ejb.Entity;import javax.ejb.FetchType;import javax.ejb.GeneratorType;import javax.ejb.Id;import javax.ejb.JoinColumn;import javax.ejb.OneToOne;import javax.ejb.ManyToMany;import javax.ejb.Table;import javax.ejb.AssociationTable;import java.util.ArrayList;import java.util.Set;import java.util.Collection;import java.io.Serializable;@Entity@Table(name = "STUDENT")public class Student implements Serializable{private int id;private String first;private String last;private Dossier dossier;private Setteachers;@Id(generate = GeneratorType.AUTO)public int getId(){return id;}public void setId(int id){this.id = id;}public void setFirst(String first){this.first = first;}public String getFirst(){return first;}public void setLast(String last){st = last;}public String getLast(){return last;}public void setDossier(Dossier dossier){this.dossier = dossier;}@OneToOne(cascade = {CascadeType.ALL}) @JoinColumn(name = "DOS SIER_ID")public Dossier getDossier(){return dossier;}public void setTeacher(Set teachers)this.teachers = teachers;}@ManyToMany(cascade = {CascadeType.CREATE, CascadeType.MERGE}, fetch = FetchType.EAGER, isInverse = true)@AssociationTable(table = @Table(name = "STUDENT_TEACHER"),joinColumns = {@JoinColumn(name = "TEACHER_ID")},inverseJoinColumns = {@JoinColumn(name = "STUDENT_ID")})public Set getTeacher(){return teachers;}}Dossier.javapackage com.kuaff.ejb3.relationships;import javax.ejb.Entity;import javax.ejb.GeneratorType;import javax.ejb.Id;@Entitypublic class Dossier implements java.io.Serializable{private Long id;private String resume;@Id(generate = GeneratorType.AUTO)public Long getId(){return id;}public void setId(Long id){this.id = id;}public void setResume(String resume)this.resume = resume;}public String getResume(){return resume;}}Teacher.javapackage com.kuaff.ejb3.relationships;import javax.ejb.AssociationTable;import javax.ejb.Basic;import javax.ejb.CascadeType;import javax.ejb.Column;import javax.ejb.Entity;import javax.ejb.FetchType;import javax.ejb.Id;import javax.ejb.JoinColumn;import javax.ejb.ManyToMany;import javax.ejb.Table;import javax.ejb.Transient;import javax.ejb.Version;import java.util.Set;import javax.ejb.GeneratorType;@Entitypublic class Teacher implements java.io.Serializable {private Long id;private String resume;private String name;private String info;private Set students;@Id(generate = GeneratorType.IDENTITY)public Long getId(){return id;public void setId(Long id){this.id = id;}public void setName(String name){ = name;}public String getName(){return name;}public void setInfo(String info){ = info;}public String getInfo(){return info;}public void setStudents(Set students){this.students = students;}@ManyToMany(cascade = {CascadeType.CREATE, CascadeType.MERGE}, fetch = FetchType.EAGER)@AssociationTable(table = @Table(name = "STUDENT_TEACHER"),joinColumns = {@JoinColumn(name = "TEACHER_ID",referencedColumnName="ID")},inverseJoinColumns = {@JoinColumn(name = "STUDENT_ID",referencedColumnName="ID")})public Set getStudents(){return students;}EntityTest.javapackage com.kuaff.ejb3.relationships;import javax.ejb.Remote;import java.util.List;@Remotepublic interface EntityTest{public void createData();public List findByName(String name);}EntityTestBean.javapackage com.kuaff.ejb3.relationships;import javax.ejb.EntityManager;import javax.ejb.Inject;import javax.ejb.Stateless;import java.util.HashSet;import java.util.Set;import java.util.List;@Statelesspublic class EntityTestBean implements EntityTest {private @Inject EntityManager manager;public void createData(){Teacher teacher1 = new Teacher();Teacher teacher2 = new Teacher();Set students1 = new HashSet();Set students2 = new HashSet();Student student1 = new Student();Student student2 = new Student();Student student3 = new Student();Dossier dossier1 = new Dossier();Dossier dossier2 = new Dossier();Dossier dossier3 = new Dossier();teacher1.setId(new Long(1));teacher1.setName("hushisheng");teacher1.setInfo("胡时胜教授,博士生导师");manager.create(teacher1);teacher2.setId(new Long(2));teacher2.setName("liyongchi");teacher2.setInfo("李永池教授,博士生导师");manager.create(teacher2);student1.setFirst("晁");student1.setLast("岳攀");dossier1.setResume("这是晁岳攀的档案");student1.setDossier(dossier1);students1.add(student1);student2.setFirst("赵");student2.setLast("志伟");dossier2.setResume("这是赵志伟的档案");student2.setDossier(dossier2);students1.add(student2);student3.setFirst("田");student3.setLast("明");dossier3.setResume("这是田明的档案");student3.setDossier(dossier3);students2.add(student3);teacher1.setStudents(students1);teacher2.setStudents(students2);}public List findByName(String name){return manager.createQuery("from Teacher t where = :name").setParameter("name", name).listResults();}}在这个会话Bean中提供了创建各个实体Bean的方法,并提供了查找老师的方法。

相关文档
最新文档