更新时间:2022-09-12 15:06:40
在EJB 2.x中。EJB有3种类型的Bean。各自是会话Bean(Session Bean)、消息驱动Bean(Message-Driven Bean)和实体Bean(Entity Bean)。
随着EJB 3的推出,EJB2.x中的实体Bean逐渐被JPA规范所替代,JPA不仅能在EJB环境中使用,并且能在Java SE、Java EE环境中使用。相对于EJB 2.x中的实体Bean,它的使用范围更广。
但这里我们仍然将其称做实体Bean。
与会话Bean和消息驱动Bean类似,新的实体Bean也是一个加了凝视符(@Entity)的简单Java对象(POJO),实体关系和O/R映射也是通过凝视符来定义的,并提供几种不同的数据库操作规范。
一旦被EntityManager訪问,它就成为了一个持久化对象。而且成为了持久化上下文的一部分。此时我们就能够像使用Hibernate、iBATIS、MYBATIS一样来使用实体对象了。
本文主要将具体解说实体Bean的开发技术。
1、建立与数据库的连接,演示实体Bean的开发与调用过程。
2、实体管理器:运行数据库更新的方法。
3、生命周期:实体Bean的监听和回调。
4、关系实体映射:开发实体的方法。
5、JPQL查询语言:运行数据库实体查询。
6、原生SQL查询:运行原生SQL语句。
它们之间的关系如图所看到的,通过实体管理器操作实体Bean。来实现对数据库的更新、JPQL查询和原生SQL查询。
实体管理器是工具。实体Bean是数据。
以下首先来解说实体Bean的调用过程。然后通过开发第一个实体Bean。演示该配置与开发的过程,包含以下内容:
1、配置数据源。
2、指定数据源。
3、开发第一个实体Bean--Student.java。
4、开发会话Bean进行调用--StudentDAORemote.java和StudentDAO.java。
5、打包并部署到JBossserver。
6、开发client进行測试--StudentDAOClient.java。
终于实现,通过实体Bean的建立与MySQL数据库的连接。往数据表中插入一条记录。
(2)在配置文件persistence.xml中指定数据源。
(3)开发实体Bean。
(4)在会话Bean、Java SE或Java EE中调用实体Bean。
connection-url:数据库连接URL。
driver:数据库驱动类。
user-name:数据库登录username。
password:数据库登陆password。
我们仅仅须要通过引用JNDI命令KsMysqlDS来引用该数据源。引用的方法非常easy。仅仅须要在persistence.xml中指定该别名就可以
配置文件persistence.xml
persistence-unit元素:能够有一个或多个。每一个persistence-unit元素定义了持久化内容名称、使用的数据源名称及Hibernate属性。当中的name属性用于设置持久化名称。
jta-data-source元素:用于指定实体Bean使用的数据源名称KsMysqlDS。当指定数据源名称时java:/前缀不能缺少,并注意数据源名称的大写和小写。
properties元素:用于指定Hibernate的各项属性。假设hibernate.hbm2ddl.auto的值设为update,这样实体Bean加入一个属性时能同一时候在数据表添加对应字段。
(1)properties元素属性在各个应用server使用的持久化产品中都不一样。如JBoss使用Hibernate。WebLogic10使用Kodo,GlassFish/Sun Application Server/Oralce使用Toplink。
(2)JBossserver在启动或关闭时会引发实体Bean的公布及卸载。
package com.ejb.entitybean; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @SuppressWarnings("serial") @Entity @Table(name = "Student") public class Student implements Serializable { private Integer studentid; //学号 private String name; //姓名 private boolean sex; //性别 private Short age; //年龄 private Date birthday; //出生日期 private String address; //地址 private String telephone //电话 @Id @GeneratedValue public Integer getStudentid() { return studentid; } public void setStudentid(Integer studentid) { this.studentid = studentid; } @Column(name = "name", length = 50) public String getName() { return name; } public void setName(String name) { this.name = name; } @Column(nullable = false) public boolean getSex() { return sex; } public void setSex(boolean sex) { this.sex = sex; } @Column(nullable = false) public Short getAge() { return age; } public void setAge(Short age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Column(name = "address", length = 100) public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Column(name = "telephone", length = 20) public String getTelephone() { return telephone; } public void setTelephone(String telephone) { this.telephone = telephone; } }
该类是一个Java POJO类,当中包括了7个变量,并为每一个变量加入了getter/setter函数。
为了将该POJO类表现为一个实体Bean,加入了一些凝视符。来与数据表student进行相应。这些凝视例如以下。
@Entity凝视指明这是一个实体Bean,每一个实体Bean类映射数据库中的一个表。
@Table凝视的name属性指定映射的数据表名称,Student类映射的数据表为Student。
@Column凝视定义了映射到列的全部属性,如列名是否唯一,是否同意为空,是否同意更新等,其属性介绍例如以下。
name:映射的列名。如映射Student表的name列,能够在name属性的getName()方法上面增加@Column(name = "name"),假设不指定映射列名,则容器会将属性名称作为默认的映射列名。
unique:是否唯一。
@GeneratedValue凝视定义了标识字段的生成方式,本例中的studentid的值由MySQL数据库自己主动生成。它能够有下面多种生成方式。
TABLE:容器指定用底层的数据表确保唯一。
SEQUENCE:使用数据库的SEQUENCE 列来保证唯一。
IDENTITY:使用数据库的INDENTIT列来保证唯一。
AUTO:由容器挑选一个合适的方式来保证唯一。
NONE:容器不负责主键的生成,由调用程序来完毕。
比如:
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Integer getId() { return this.id; }
以下我们来开发一个远程的会话Bean组件,通过调用实体Bean类Student.java,来实现往数据表student中插入一条记录。
首先在项目EntityBeanTest中新建一个包com.ejb.dao,然后依照会话Bean的开发方法。在该包中新建一个远程的会话Bean组件StudentDAO。新建完后会产生一个远程接口类StudentDAORemote.java和实现类StudentDAO.java。
<span style="font-family:SimSun;">package com.ejb.dao; import java.util.List; import javax.ejb.Remote; import com.ejb.entitybean.Student; @Remote public interface StudentDAORemote { public boolean insert(Student student); } </span>
首先它包括了一个EntityManager类型的变量em。EntityManager是实体管理器。顾名思义。它是实体Bean的管理容器。通过该对象,我们可以实现与数据库的各种交互,包括增、删、改、查等。
该实体变量em还通过凝视@PersistenceContext来实现动态注入EntityManager对象,假设persistence.xml文件里配置了多个不同的持久化内容。则还须要指定持久化名称注入EntityManager 对象,能够通过@PersistenceContext凝视的unitName属性进行指定,比如:
@PersistenceContext(unitName="exam-entity") EntityManager em;
package com.ejb.dao; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import com.ejb.entitybean.Student; @Stateless public class StudentDAO implements StudentDAORemote { @PersistenceContext protected EntityManager em; public boolean insert(Student student) { try { em.persist(student); } catch (Exception e) { e.printStackTrace(); return false; } return true; } }
1、载入persistence.xml文件。
2、创建数据库表student,此时查看MySQL数据库就会看到新建的表student。
3、公布JNDI服务StudentDAO/remote。
首先将实体类Student.java和接口类StudentDAORemote.java复制加入到測试项目EJBTestJava的相应包中,然后新建測试类
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Properties; import javax.naming.InitialContext; import javax.naming.NamingException; import com.ejb.dao.StudentDAORemote; import com.ejb.entitybean.Student; public class StudentDAOClient { public static void main(String[] args) throws NamingException { Properties props = new Properties(); props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); props.setProperty("java.naming.provider.url", "localhost:1099"); props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming"); try { InitialContext ctx = new InitialContext(props); StudentDAORemote studentDAO = (StudentDAORemote) ctx.lookup("StudentDAO/remote"); Student student = new Student(); student.setName("刘中兵"); student.setSex(true); student.setAge((short)25); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); student.setBirthday(format.parse("1981-05-04")); student.setTelephone("12345678"); student.setAddress("北京"); studentDAO.insert(student); System.out.println("已经插入一个学生记录!"); } catch (NamingException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } } }该类通过訪问远程JNDI服务StudentDAO/remote,取得了远程会话Bean实例studentDAO。然后创建了一个Student实体对象。调用insert()函数插入该对象。
执行该程序后,会在控制台中输出例如以下信息:
已经插入一个学生记录!
这就表明client的Java类已正确地将Student对象提交到远程会话Bean组件中了。