Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16493905
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:43:55

下载本文示例代码
  在EJB3.0中开发实体Bean非常简单,你可以象开发一般的java bean一样编程,只需做少量的注释。一个实体bean不需要实现Home接口或者Remote、Local接口。   实体Bean通过EntityManager产生、查找、和持久层结合、从持久层收回等操作。  JBoss的EJB3.0架构在Hibernate之上。  注释:  @Entity:如果你要建立一个实体Bean的类,你必须在类上加上这个注释,用来告诉容器这个类是实体Bean。这个Bean的主键由@Id指定。  这个注释的声明如下: @Target(TYPE) @Retention(RUNTIME)public @interface Entity {String name() default "";EntityType entityType() default CMP;AccessType access() default PROPERTY;int version() default 3;}  name用来指定实体Bean的名称,缺省和类名相同。  EntityType用来指定此bean是容器管理的持久实体Bean还是Bean管理的持久实体Bean。可以是CMP和BMP两种方式。  AccessType用来指定容器访问此EJB的持久化数据的方式。PROPERTY用来告诉容器使用get/set访问持久化的数据(就是无Transient注释的数据),FILED告诉容器直接访问字段,字段应该声明称protected类型。  为了提供给其他会话Bean等客户端使用,这个Bean应实现Serializable接口。  实体Bean必须由一个无参数的构造方法。  可持久化的属性包括:java的基本类型(int,long等)、String、BigInteger、BigDecimal、java.util.Date、Calendar、java.sql.Date、java.sql.Time、java.sql.Timestamp、byte[]、char[]、其他实体Bean类型、其他实体Bean的集合(Collection、Set,不支持List)。  @Table  用来指定此实体Bean使用的主表,有时候可能需要其他的表,参看后面的章节的介绍。UniqueConstraint注释用来添加约束条件。  @Id  用来指定此实体Bean的主键。它可以有多种生成方式:  ·TABLE:容器指定用底层的数据表确保唯一。  ·SEQUENCE:使用数据库的SEQUENCE列来保证唯一  ·IDENTITY:使用数据库的INDENTIT列来保证唯一  ·AUTO:由容器挑选一个合适的方式来保证唯一  ·NONE:容器不负责主键的生成,由调用程序来完成。  @OnetoMany  两个实体Bean之间可能有一对多、多对一、一对一、多对多的关系,后面两个关系在后面的例子中介绍。  比如学生和各课分数之间就是一对多的关系。  在EJB3.0中,一对多的关联必须是双向的,也就是说,必定有各多对一的关联和它对应。  OnetoMany注释声明如下: @Target({METHOD, FIELD}) @Retention(RUNTIME)public @interface OneToMany {String targetEntity() default "";CascadeType[] cascade() default {};FetchType fetch() default LAZY;}  当我们使用这个注释为get方法注释时,如果使用JDK5.0的通用编程,返回集合Collection<目标实体类型>,那么就不需要指定targetEntity的类型,否则返回类型声明为普通的Collection的话,就必须声明targetEntity的类型。  CascadeType指定了当这个实体Bean新建或者Merge的时候,与之关联的实体需要怎样的处理:  ·MERGE:当主实体Bean被merge的时候、关联的实体Bean也被merge  ·CREATE:当主实体Bean被create的时候、关联的实体Bean也被create  ·REMOVE:当主实体Bean被evict的时候、关联的实体Bean也被evict  ·ALL:包括以上的情况  FetchType指定从数据中读取的方式:LAZY还是EAGER。LAZY只有当第一次访问的时候,才从数据库中得到相关的实体bean,EAGER则很积极,同主实体Bean一同产生。  @ManytoOne  我们知道一对多的关联是双向的。在关联的实体Bean中必定声明了由ManyToOne注释的方法。  @JoinColumn  我们知道两个实体可以关联,但对应到Table中需要指定一个列作为外键。假如不指定name,那么认为主表中的列和附表中的主键有相同名称的作为外键。如果不指定referencedColumnName,则认为外键对应副表的主键。  @JoinColumns  用来指示符合主键,在后面的章节中介绍。  这个例子主要有以下几个文件,这个例子主要实现了管理学生分数的功能。Student是一个实体Bean,管理学生的基本信息(姓名和各课分数),其中学生的分数又是一个实体Bean。TacherBean是一个无状态的会话Bean,用来调用实体Bean。和前面的例子一样,我们还是使用Client测试。  ·Student.java:实体Bean。  ·Score.java:实体Bean。  ·Teacher.java:会话Bean的业务接口  ·TeacherBean.java:会话Bean的实现类  ·Client.java:测试EJB的客户端类。  ·jndi.properties:jndi属性文件,提供访问jdni的基本配置属性。  ·Build.xml:ant 配置文件,用以编译、发布、测试、清除EJB。  下面针对每个文件的内容做一个介绍。  Student.java package com.kuaff.ejb3.entity;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.OneToMany;import javax.ejb.Table;import java.util.ArrayList;import java.util.Collection;import java.io.Serializable;@Entity@Table(name = "STUDENT")public class Student implements Serializable{ //主键 private int id; //学生名 private String name; //学生的分数 private Collection scores; //主键自动产生 @Id(generate = GeneratorType.AUTO) public int getId() {  return id; } public void setId(int id) {  this.id = id; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } public void addScores(String name,int number) {  if (scores == null)  {   scores = new ArrayList();  }  Score score = new Score();  score.setName(name);  score.setNumber(number);  score.setStudent(this);  scores.add(score); } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "student_id") public Collection getScores() {  return scores; } public void setScores(Collection scores) {  this.scores = scores; }}  Student.java实现了Student实体Bean,它提供学生的基本情况以及学生的得分情况,得分是另外一个实体Bean。Student实体Bean和Score实体Bean是一对多的关系,站在Score的角度看是多对一的关系。  实体Bean需要使用@Entity做注释,另外它指定这个实体Bean与表STUDENT对应(通过注释@Table(name = "STUDENT")),你可以在JBOSS的数据库中看到这个表。  Score.java package com.kuaff.ejb3.entity;import java.io.Serializable;import javax.ejb.Entity;import javax.ejb.GeneratorType;import javax.ejb.Id;import javax.ejb.JoinColumn;import javax.ejb.ManyToOne;import javax.ejb.Table;@Entity@Table(name = "Score")public class Score implements Serializable{ private int id; private String name; private int number; private Student student; //主键自动产生  @Id(generate = GeneratorType.AUTO) public int getId() {  return id; } public void setId(int id) {  this.id = id; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } public int getNumber() {  return number; } public void setNumber(int number) {  this.number = number; } @ManyToOne @JoinColumn(name = "student_id") public Student getStudent() {  return student; } public void setStudent(Student student) {  this.student = student; }}  这个实体Bean存放学生的分数。  Teacher.java package com.kuaff.ejb3.entity;import javax.ejb.Remote;import javax.ejb.Remove;import java.util.Map;@Remotepublic interface Teacher{ public void addScore(String studentName,Map map); public Student getStudent(); @Remove public void leave();}  这个会话Bean接口提供增加分数和得到用户的方法。  TeacherBean.java package com.kuaff.ejb3.entity;import javax.ejb.EntityManager;import javax.ejb.Inject;import javax.ejb.Remove;import javax.ejb.Stateful;import java.util.Map;import java.util.Set;@Statefulpublic class TeacherBean implements Teacher{ @Inject private EntityManager manager; private Student student; public Student getStudent() {  return student; } public void addScore(String studentName, Map map) {  if (student == null)  {   student = new Student();  }  student.setName(studentName);  Set set = map.keySet();  for (String sname:set)  {   student.addScores(sname,map.get(sname).intValue());  } } @Remove public void leave() {  manager.create(student); }}  这个是会话Bean的实现类。  Client.java package com.kuaff.ejb3.entity;import java.util.Map;import java.util.HashMap;import java.util.Collection;import javax.naming.InitialContext;import javax.naming.NamingException;public class Client{ public static void main(String[] args) throws NamingException {  InitialContext ctx = new InitialContext();  Teacher teacher = (Teacher) ctx.lookup(Teacher.class.getName());  Map map = new HashMap();  map.put("语文",new Integer(98));  map.put("化学",new Integer(149));  map.put("物理",new Integer(143));  teacher.addScore("smallnest",map);  Student student = teacher.getStudent();  String name = student.getName();  System.out.printf("显示%s的分数:%n",name);  Collection c = student.getScores();  for (Score score:c)  {   System.out.printf("%s:%s%n",score.getName(),score.getNumber() "");  } }}  这个客户端增加学生的分数,并且测试显示这个学生的相关信息。  请运行{$JBOSS_HOME}/bin目录下的run.bat: run –c all,启动JBOSS。,然后调用startDatabaseManager()方法,打开HSQL管理工具管理数据库。  在Eclipse的Ant视图中执行ejbjar target。或者在命令行下,进入到此工程目录下,执行ant ejbjar,将编译打包发布此EJB。  在Eclipse的Ant视图中执行run target。或者在命令行下,进入到此工程目录下,执行ant run,测试这个EJB。   在EJB3.0中开发实体Bean非常简单,你可以象开发一般的java bean一样编程,只需做少量的注释。一个实体bean不需要实现Home接口或者Remote、Local接口。   实体Bean通过EntityManager产生、查找、和持久层结合、从持久层收回等操作。  JBoss的EJB3.0架构在Hibernate之上。  注释:  @Entity:如果你要建立一个实体Bean的类,你必须在类上加上这个注释,用来告诉容器这个类是实体Bean。这个Bean的主键由@Id指定。  这个注释的声明如下: @Target(TYPE) @Retention(RUNTIME)public @interface Entity {String name() default "";EntityType entityType() default CMP;AccessType access() default PROPERTY;int version() default 3;}  name用来指定实体Bean的名称,缺省和类名相同。  EntityType用来指定此bean是容器管理的持久实体Bean还是Bean管理的持久实体Bean。可以是CMP和BMP两种方式。  AccessType用来指定容器访问此EJB的持久化数据的方式。PROPERTY用来告诉容器使用get/set访问持久化的数据(就是无Transient注释的数据),FILED告诉容器直接访问字段,字段应该声明称protected类型。  为了提供给其他会话Bean等客户端使用,这个Bean应实现Serializable接口。  实体Bean必须由一个无参数的构造方法。  可持久化的属性包括:java的基本类型(int,long等)、String、BigInteger、BigDecimal、java.util.Date、Calendar、java.sql.Date、java.sql.Time、java.sql.Timestamp、byte[]、char[]、其他实体Bean类型、其他实体Bean的集合(Collection、Set,不支持List)。  @Table  用来指定此实体Bean使用的主表,有时候可能需要其他的表,参看后面的章节的介绍。UniqueConstraint注释用来添加约束条件。  @Id  用来指定此实体Bean的主键。它可以有多种生成方式:  ·TABLE:容器指定用底层的数据表确保唯一。  ·SEQUENCE:使用数据库的SEQUENCE列来保证唯一  ·IDENTITY:使用数据库的INDENTIT列来保证唯一  ·AUTO:由容器挑选一个合适的方式来保证唯一  ·NONE:容器不负责主键的生成,由调用程序来完成。  @OnetoMany  两个实体Bean之间可能有一对多、多对一、一对一、多对多的关系,后面两个关系在后面的例子中介绍。  比如学生和各课分数之间就是一对多的关系。  在EJB3.0中,一对多的关联必须是双向的,也就是说,必定有各多对一的关联和它对应。  OnetoMany注释声明如下: @Target({METHOD, FIELD}) @Retention(RUNTIME)public @interface OneToMany {String targetEntity() default "";CascadeType[] cascade() default {};FetchType fetch() default LAZY;}  当我们使用这个注释为get方法注释时,如果使用JDK5.0的通用编程,返回集合Collection<目标实体类型>,那么就不需要指定targetEntity的类型,否则返回类型声明为普通的Collection的话,就必须声明targetEntity的类型。  CascadeType指定了当这个实体Bean新建或者Merge的时候,与之关联的实体需要怎样的处理:  ·MERGE:当主实体Bean被merge的时候、关联的实体Bean也被merge  ·CREATE:当主实体Bean被create的时候、关联的实体Bean也被create  ·REMOVE:当主实体Bean被evict的时候、关联的实体Bean也被evict  ·ALL:包括以上的情况  FetchType指定从数据中读取的方式:LAZY还是EAGER。LAZY只有当第一次访问的时候,才从数据库中得到相关的实体bean,EAGER则很积极,同主实体Bean一同产生。  @ManytoOne  我们知道一对多的关联是双向的。在关联的实体Bean中必定声明了由ManyToOne注释的方法。  @JoinColumn  我们知道两个实体可以关联,但对应到Table中需要指定一个列作为外键。假如不指定name,那么认为主表中的列和附表中的主键有相同名称的作为外键。如果不指定referencedColumnName,则认为外键对应副表的主键。  @JoinColumns  用来指示符合主键,在后面的章节中介绍。  这个例子主要有以下几个文件,这个例子主要实现了管理学生分数的功能。Student是一个实体Bean,管理学生的基本信息(姓名和各课分数),其中学生的分数又是一个实体Bean。TacherBean是一个无状态的会话Bean,用来调用实体Bean。和前面的例子一样,我们还是使用Client测试。  ·Student.java:实体Bean。  ·Score.java:实体Bean。  ·Teacher.java:会话Bean的业务接口  ·TeacherBean.java:会话Bean的实现类  ·Client.java:测试EJB的客户端类。  ·jndi.properties:jndi属性文件,提供访问jdni的基本配置属性。  ·Build.xml:ant 配置文件,用以编译、发布、测试、清除EJB。  下面针对每个文件的内容做一个介绍。  Student.java package com.kuaff.ejb3.entity;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.OneToMany;import javax.ejb.Table;import java.util.ArrayList;import java.util.Collection;import java.io.Serializable;@Entity@Table(name = "STUDENT")public class Student implements Serializable{ //主键 private int id; //学生名 private String name; //学生的分数 private Collection scores; //主键自动产生 @Id(generate = GeneratorType.AUTO) public int getId() {  return id; } public void setId(int id) {  this.id = id; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } public void addScores(String name,int number) {  if (scores == null)  {   scores = new ArrayList();  }  Score score = new Score();  score.setName(name);  score.setNumber(number);  score.setStudent(this);  scores.add(score); } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "student_id") public Collection getScores() {  return scores; } public void setScores(Collection scores) {  this.scores = scores; }}  Student.java实现了Student实体Bean,它提供学生的基本情况以及学生的得分情况,得分是另外一个实体Bean。Student实体Bean和Score实体Bean是一对多的关系,站在Score的角度看是多对一的关系。  实体Bean需要使用@Entity做注释,另外它指定这个实体Bean与表STUDENT对应(通过注释@Table(name = "STUDENT")),你可以在JBOSS的数据库中看到这个表。  Score.java package com.kuaff.ejb3.entity;import java.io.Serializable;import javax.ejb.Entity;import javax.ejb.GeneratorType;import javax.ejb.Id;import javax.ejb.JoinColumn;import javax.ejb.ManyToOne;import javax.ejb.Table;@Entity@Table(name = "Score")public class Score implements Serializable{ private int id; private String name; private int number; private Student student; //主键自动产生  @Id(generate = GeneratorType.AUTO) public int getId() {  return id; } public void setId(int id) {  this.id = id; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } public int getNumber() {  return number; } public void setNumber(int number) {  this.number = number; } @ManyToOne @JoinColumn(name = "student_id") public Student getStudent() {  return student; } public void setStudent(Student student) {  this.student = student; }}  这个实体Bean存放学生的分数。  Teacher.java package com.kuaff.ejb3.entity;import javax.ejb.Remote;import javax.ejb.Remove;import java.util.Map;@Remotepublic interface Teacher{ public void addScore(String studentName,Map map); public Student getStudent(); @Remove public void leave();}  这个会话Bean接口提供增加分数和得到用户的方法。  TeacherBean.java package com.kuaff.ejb3.entity;import javax.ejb.EntityManager;import javax.ejb.Inject;import javax.ejb.Remove;import javax.ejb.Stateful;import java.util.Map;import java.util.Set;@Statefulpublic class TeacherBean implements Teacher{ @Inject private EntityManager manager; private Student student; public Student getStudent() {  return student; } public void addScore(String studentName, Map map) {  if (student == null)  {   student = new Student();  }  student.setName(studentName);  Set set = map.keySet();  for (String sname:set)  {   student.addScores(sname,map.get(sname).intValue());  } } @Remove public void leave() {  manager.create(student); }}  这个是会话Bean的实现类。  Client.java package com.kuaff.ejb3.entity;import java.util.Map;import java.util.HashMap;import java.util.Collection;import javax.naming.InitialContext;import javax.naming.NamingException;public class Client{ public static void main(String[] args) throws NamingException {  InitialContext ctx = new InitialContext();  Teacher teacher = (Teacher) ctx.lookup(Teacher.class.getName());  Map map = new HashMap();  map.put("语文",new Integer(98));  map.put("化学",new Integer(149));  map.put("物理",new Integer(143));  teacher.addScore("smallnest",map);  Student student = teacher.getStudent();  String name = student.getName();  System.out.printf("显示%s的分数:%n",name);  Collection c = student.getScores();  for (Score score:c)  {   System.out.printf("%s:%s%n",score.getName(),score.getNumber() "");  } }}  这个客户端增加学生的分数,并且测试显示这个学生的相关信息。  请运行{$JBOSS_HOME}/bin目录下的run.bat: run –c all,启动JBOSS。,然后调用startDatabaseManager()方法,打开HSQL管理工具管理数据库。  在Eclipse的Ant视图中执行ejbjar target。或者在命令行下,进入到此工程目录下,执行ant ejbjar,将编译打包发布此EJB。  在Eclipse的Ant视图中执行run target。或者在命令行下,进入到此工程目录下,执行ant run,测试这个EJB。 下载本文示例代码


EJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体BeanEJB 3.0 开发指南之实体Bean
阅读(124) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~