今天内容为两个版块JPA与EJB,从学习hibernate、UML到JPA。他们都涉及到一个极为重要的细节——类与类、接口与接口或类与接口之间的四类关联关系。今日上午到下午3点左右内容为JPA中处理这四类关系。我想我应该将他们系统的做一下总结,这项任务就留着后天休息来完成吧!
近三天的课程内容除了带给我知识上的获取和见识的增长,更让我感觉到一种力量!在学习WEB之前,这些互联网的东西让我满头雾水,不知所云。但在传智播客学习到现在,WEB应用中应该没什么还能让我满头雾水的了,云计算也没之前那么让我感到神秘的。带给我什么力量了?一种驾驭知识的力量!我十分有兴与两位高手租房子,我从他们身上学习到了很多知识。因为我没读过本科,所以计算机基础知识不够好。偶有时间,看一看计算机组成原理等。通过与同学的交流,我似乎已经能摸清硬件了执行原理,并不复杂。
通过以前的工作自己掌握的知识、在传智播客学习到的知识,以及与同事、好友、同学们的相处。我似乎已经感觉到将硬件、桌面应用、WEB应用...融汇贯通的感觉!这感觉让我充满力量。
一、JPA中的关联关系
说实在的在学习hibernate和UML时,听着老师讲关联关系一点问题都没有。但他们在我脑子里没形成系统的概念。但今天学习JPA的关联关系,让我找到了感觉。关系关联在我脑子里形成系统的概念,指日可待!
1.一对多单向关联
典型的例子是,客户与订单这种一对多的关系。在客户类的orders属性或getOrders属性方法上添加注解:
@OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST,CascadeType.REMOVE}, targetEntity=Order.class) |
“@OneToMany”表示一对多关联关系的注解,括号内全是他的属性。
“fetch=FetchType.EAGER”,强迫左外连接,默认值为“LAZY”。
“cascade={CascadeType.PERSIST,CascadeType.REMOVE}”,设置保存和删除级联。
“targetEntity=Order.class”,相当于hibernate的class属性。
2.多对一单向关联
订单与客户的例子。在订单类的customer属性或getCustomer属性方法上添加注解:
@ManyToOne(cascade={CascadeType.PERSIST}) @JoinColumn(name="cid") |
“@ManyToOne”表示多对一的关联关系的注解,括号内全是他的属性。
“cascade={CascadeType.PERSIST}”设置保存级联。
“@JoinColumn”设置Orders表的外键。
“name="cid"”外键的名称。
3.一对多(多对一)双向关联
在客户类的orders属性或getOrders属性方法上添加注解:
@OneToMany(mappedBy="customer", fetch=FetchType.EAGER, cascade={CascadeType.PERSIST,CascadeType.REMOVE}, targetEntity=Order.class) |
在订单类的customer属性或getCustomer属性方法上添加注解:
在上面的注解中只“@OneToMany”中多了一个“mappedBy="customer"”属性,它相当于hibernate的“inverse=false”属性,不参与对集合的控制。如果不设置“mappedBy”属性,JPA会为一对多关联关系设置一个中间表。
4.一对一关联
使用学习hibernate时的例子,用户包含大文本信息的地址属性。
外键关联:
在用户表的Addr属性或getAddr属性方法上添加注解:
@ManyToOne(cascade={CascadeType.PERSIST}) @JoinColumn(name="cid") |
“@OneToOne”为一对一关联关系注解。
“@JoinColumn”设置外键。
“name="aid"”外键名称为“aid”。
“unique=true”外键唯一性,用户与地址一一对应。
在地址表的User属性或getUser属性方法上添加注解:
@OneToOne @JoinColumn(name="aid",unique=true) |
“@OneToOne”为一对一关联关系注解。
“mappedBy="addr"”取消对集合的控制权,用User实体来控制外键的值。
主键关联:
在用户表的Addr属性或getAddr属性方法上添加注解:
“@OneToOne”为一对一关联关系注解。
“@PrimaryKeyJoinColumn”,设置主键关联列。
“name="userid"”,本实体关联字段的名称。
“referencedColumnName="addrid"”,所关联实体的表中的字段名称。
在地址表的User属性或getUser属性方法上添加注解:
@OneToOne(mappedBy="addr") |
“@OneToOne”为一对一关联关系注解。
“mappedBy="addr"”取消对集合的控制权,用User实体来控制外键的值。
5.多对多关联
经典的例子,教师与学生多对多关联关系。
在Teacher实体的stus集合属性或getStus属性方法上添加注解:
@OneToOne @PrimaryKeyJoinColumn(name="userid",referencedColumnName="addrid") |
“@ManyToMany”设置多对多关联关系。
“@JoinTable”设置关联表。
“name="jpa_links"”中间表表名。
“joinColumns=@JoinColumn(name="tid")”设置Teacher实体对应的关联列。数组类型,可以设置多重主键。
“inverseJoinColumns=@JoinColumn(name="sid")”设置Student实体对应的关联列。数组类型,可以设置多重主键。
在Student实体的teas集合属性或getTeas属性方法上添加注解:
@OneToOne(mappedBy="addr") |
“@ManyToMany”为多对多关联关系注解。
“mappedBy="addr"”取消对集合的控制权。
6.继承关系
继承关系有三种解决方法,我们仍然使用学习hibernate时所使用的例子。一个员工实体(Employee),一个钟点工子实体(HourlyEmployee)和一个薪水工子实体(SalaryEmployee)。
1).继承关系树对应一张表
在Employee实体类上面添加注解:
@ManyToMany @JoinTable(name="jpa_links", joinColumns=@JoinColumn(name="tid"), inverseJoinColumns=@JoinColumn(name="sid")) |
“@Entity”设置实体。
“@Table(name="jpa_inherit_single_ess")”设置表名。
“@Inheritance(strategy=InheritanceType.SINGLE_TABLE)”设置集成策略为单个表,将整个继承关系树保存在一张表中。
“@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)”设置区分器字段名称和类型。
“@DiscriminatorValue("ee")”Employee对应的区分类型值为“ee”。
在HourlyEmployee实体类上面添加注解:
@ManyToMany(mappedBy="stus") |
“@Entity”设置实体。
“@DiscriminatorValue("he")”Employee对应的区分类型值为“he”。
在SalaryEmployee实体类上面添加注解:
@Entity @Table(name="jpa_inherit_single_ess") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING) @DiscriminatorValue("ee") |
“@Entity”设置实体。
“@DiscriminatorValue("se")”Employee对应的区分类型值为“se”。
2).每个类对应一张表,使用外键关联。
在Employee实体类上面添加注解:
“@Entity”设置实体。
“@Table(name="jpa_inherit_join_ees")”设置表名。
“@Inheritance(strategy=InheritanceType.JOINED)”设置集成策略为联合,为继承关系树中每个成员创建一个表,并使用外键关联(父类的主键被做为子类的外键)。
在HourlyEmployee实体类上面添加注解:
@Entity @DiscriminatorValue("he") |
“@Entity”设置实体。
“@Table(name="jpa_inherit_join_hes")”设置表名。
“@PrimaryKeyJoinColumn(name="eeid")”设置外键。
在SalaryEmployee实体类上面添加注解:
@Entity @DiscriminatorValue("se") |
“@Entity”设置实体。
“@Table(name="jpa_inherit_join_ses")”设置表名。
“@PrimaryKeyJoinColumn(name="eeid")”设置外键。
3).联合表,每个类单独一个表,使用union联合。
在Employee实体类上面添加注解:
@Entity @Table(name="jpa_inherit_join_ees") @Inheritance(strategy=InheritanceType.JOINED) |
“@Entity”设置实体。
“@Table(name="jpa_inherit_join_ess")”设置表名。
“@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)”设置集成策略为union,为继承关系树中的每个成员创建一张表,每个表包含全信息(子类表中包含父类属性的字段)。
在HourlyEmployee实体类上面添加注解:
“@Entity”设置实体。
在SalaryEmployee实体类上面添加注解:
@Entity @Table(name="jpa_inherit_join_hes") @PrimaryKeyJoinColumn(name="eeid") |
“@Entity”设置实体。
二、EJB3简介
在本文中将对新的规范进行一个概要性的介绍,包括新增的元数据支持,EJBQL的修改,实体Bean模型访问bean上下文的新方法和运行时环境等等。作者还讨论了EJB在未来要作出的调整以及EJB3.0与其他开发规范之间的关系。
来自:http://developer.51cto.com/art/200510/6284.htm
三、EJB3“HelloWorld!”
我们使用EJB3编写一个“HelloWorld!”程序:
一、配置JBOSS服务器
1.我们使用的是“jboss-4.2.2.GA”。
2.将“jboss-4.2.2.GA”放置在非中文路径目录。、
3.添加环境变量“JBOSS_HOME”,值为“jboss-4.2.2.GA”所在目录。
4.修改JBOSS服务器端口,配置文件为“jboss-4.2.2.GA\server\default\deploy\jboss-web.deployer\server.xml”。将其中的8080端口修改为8088端口。
5.在IDE中配置JBOSS服务器,指定JBOSS4.X服务器所在目录。
二、EJB组件
1.创建一个普通Java工程,命名为“EJB3_HW_EJB”。
2.将hibernate3.1目录下的“jpa”子目录中的所有jar包导入到工程。
3.在工程中添加一个接口“cn.itcast.cc.ejb3.ejb.HelloWorld”:
@Entity @Table(name="jpa_inherit_join_ses") @PrimaryKeyJoinColumn(name="eeid") |
4.编写一个“HelloWorld”接口的实现类“cn.itcast.cc.ejb3.ejb.HelloWorldImpl”:
@Entity @Table(name="jpa_inherit_join_ess") @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) |
5.将工程“EJB3_HW_EJB”导出为“EJB3_HW_EJB.jar”包。
6.将“EJB3_HW_EJB.jar”拷贝到“JBOSS”的“\server\default\deploy”目录下,JBOSS服务器会自动部署。
三、WEB应用
1.创建一个WEB应用工程,命名为“EJB3_HW_WEB”。
2.将上边的EJB组件工程“”添加为WEB应用工程的Required Project。(在“Configure Build Path”中设置)
3.将“index.jsp”页面的内容设置为:
import javax.ejb.Local; @Local public interface HelloWorld { String hello(String str); } |
import javax.ejb.Stateless; @Stateless public class HelloWorldImpl implements HelloWorld { public String hello(String str) { System.out.println(str); return "Hello "+str+" ,welcome to EJB3!"; } } |
4.将工程“EJB3_HW_WEB”导出为“EJB3_HW_WEB.war”包。
5.将“EJB3_HW_WEB.war”拷贝到“JBOSS”的“\server\default\deploy”目录下,JBOSS服务器会自动部署。
四、运行
1.在IDE中启动JBOSS服务器。
2.打开浏览器。
3.输入URL“http://localhost:8088/EJB3_HW_WEB/index.jsp”。
4.在输出容器中输出:“23:15:51,683 INFO [STDOUT] changcheng”。
5.在JSP页面中输出:“Hello changcheng ,welcome to EJB3! ”
OK,今天的内容到此结束!