上文我们对会话Bean的生命周期和两个子类型(有状态会话Bean和无状态会话Bean)进行了详细解说,本篇博文中我们继续说说EJB组件中的实体Bean。
其实实体Bean就是一个加了注释符(@Entity)的简单java对象(POJO),实体关系和O/R映射也是通过注释符来定义的,并且提供了几种不同的数据库操作规范。一旦被EntityManager访问,它就成为了一个持久化对象,我们就可以像以前使用Hibernate一样来使用实体对象了。
下图是实体Bean的内容结构图,方便我们宏观的了解实体Bean。通过实体管理器操作实体Bean,来实现对数据库的更新、JPQL查询和SQL查询。可以说,实体管理器是工具,实体Bean则是数据。
下面主要是通过一个实体Bean实例,来理解其调用过程。其过程主要包括以下各个过程:
(1)配置数据源
(2)指定数据源
(3)开发一个实体Bean
(4)开发会话Bean进行调用
(5)打包并部署到JBoss服务器
(6)开发客户端进行测试
看着上面六个步骤是不是觉得记不住啊,没有关系,这个不需要记,理解了自然就会了。当我们需要新建一个项目时,(1)首先需要确定数据源并且进行配置吧,这就是我们上面的第一个过程--配置数据源;(2)配置完数据源(一个或者多个)后,我们就需要确定当前实体Bean分别需要使用哪个数据源,也就是第二个过程--指定数据源;(3)做好和数据库连接的准备了,我们需要开发实体Bean来对应数据库中的表,就是第三个过程--开发一个实体Bean;(4)实体Bean开发完成后,可以被会话Bean调用,也可以被其他类调用,在本实例中我们采用会话Bean调用实体Bean,所以需要第四个过程--开发会话Bean进行调用;(5)到此我们服务器端的代码编写就完成了,但是我们还需要进行打包并部署到JBoss服务器上,以供客户端调用,故第五个过程--打包并部署到JBoss服务器;(6)最后就是我们客户端对服务器端组件的调用了,第六个过程--开发客户端进行测试。
通过上面简单通俗的介绍,不知道你对实体Bean调用过程的几个步骤加深印象了没有,暂时没有也没有关系,以后多用,用着用着就理解深刻了,用着用着就烂记于心了。下面我在对这几个过程进行一个详细的演示和解说。
(1)配置数据源
在实际应用中,我们可能需要使用不同的数据库,如MySQL、Oracle、MSSQL Server等。各个数据库的数据源配置模板都在%Jboss_Home%\docs\examples\jca目录下,共包括38中数据源的连接。要配置到某一个数据源的连接,需要进行如下步骤:
1.复制模板--复制该数据库类型的配置模板到%Jboss_Home%\server\default\deploy目录,并设置数据源参数(以MSSQL Server为例);
<span style="font-size:18px;"><datasources>
<local-tx-datasource>
<!-- 数据源名称 -->
<jndi-name>MSSQLDS</jndi-name>
<!-- 指定连接本地的Demo数据库 -->
<connection-url>jdbc:microsoft:sqlserver://localhost:8080;DatabaseName=Demo</connection-url>
<!-- 数据库驱动类 -->
<driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
<!-- Demo数据库登录用户名-->
<user-name>sunliduan</user-name>
<!-- Demo数据库登录密码-->
<password>sunliduan</password>
<metadata>
<type-mapping>MSSQLSERVER2000</type-mapping>
</metadata>
</local-tx-datasource>
</datasources></span>
如果JBoss服务器处于启动状态,则此时JBoss会自动监控到该文件,并加载起来,并在控制台输出相应信息。
2.添加驱动--添加该数据库的驱动程序包到%Jboss_Home%\server\default\lib目录,并重启JBoss服务器加载该程序包。
各个数据库的数据源配置都是这两个步骤,基本类似。
(2)指定数据源
以上配置的数据源都是由JBoss服务器加载和管理的,要使用这些数据源,还需要在应用中指定引用哪一个数据源。而这项工作的完成靠persistence.xml即可。
<span style="font-size:18px;"><SPANstyle="FONT-SIZE: 14px; FONT-FAMILY: MicrosoftYaHei"><persistence>
<!-- Name属性用于定义持久化内容的名称 -->
<persistence-unitname="demo">
<!-- Jta-data-source 用于指定实体Bean使用的数据源名称 -->
<jta-data-source>java:/MSSQLDS</jta-data-source>
<!-- 厂商专有属性(可选) -->
<properties>
<!--自动输出schema创建DDL语句 -->
<propertyname="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence></SPAN></span>
这里需要注意的一点是:"hibernate.hbm2ddl.auto"的值,若为上文中的"create-drop",则在实体Bean发布及卸载时将自动创建及删除相应的数据库表。为了使以后实体Bean的改动能反应到数据库表,建议使用update,这样实体Bean添加一个属性时能同时在数据库表增加相应字段。
(3)开发实体Bean
实体Bean实际上对应了数据库中的表,它是数据库中表在Java类中的表现。EJB容器能够根据实体Bean自动在数据库中创建数据表。
开发一个实体Bean很简单,只需要新建一个POJO类,添加与数据表字段同名的变量,同时使用一些注释符来表示该实体Bean与数据库表的对应映射关系即可。
<span style="font-size:18px;">/**
* @ClassName: 用户实体Bean
* @Description: 用户实体Bean
* @author 孙丽端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="user")
public class User implements Serializable {
private int id; //用户ID
private String username; //用户名
private String password; //密码
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="userName",length=50)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Column(name="password",length=50)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}</span>
需要注意:实体Bean需要实现Serializable接口,这样就可以有EJB客户端创建该对象,并将该对象传送到服务器端。
(4)开发会话Bean并调用
实体Bean既可以被会话Bean调用,也可以被任何的Java类或者JSP调用,在EJB应用程序中,我们通常会在会话Bean中调用实体Bean,来实现对数据库的操作。
新建一个远程的会话Bean组件后会生成一个远程接口类和实现类。代码如下:
<span style="font-size:18px;">/**
* @ClassName: 用户管理的远程接口类
* @Description: 用户管理的远程接口类
* @author 孙丽端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
import javax.ejb.Remote;
@Remote
public interface UserManager {
public void addUser(User user);
}</span>
<span style="font-size:18px;">/**
* @ClassName: 用户管理的实现类
* @Description: 用户管理的实现类
* @author 孙丽端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
@Local
public class UserManagerBean implements UserManager {
@PersistenceContext
protected EntityManager em;
@Override
public void addUser(User user) {
em.persist(user); //保存记录
}
}</span>
其中我们比较陌生的可能是@PersistenceContext和EntityManager。先说EntityManager,它是实体管理器,也就是实体Bean的管理容器。通过该对象,我们能够实现与数据库的各种交互,包括增删改查等。再说@PersistenceContext,EntityManager通过注释@PersistenceContext可以实现动态注入EntityManager对象,如果persistence.xml文件中配置了多个不同的持久化内容,则还需要通过unitName属性来指定持久化名称,如下:
<span style="font-size:18px;">@PersistenceContext(unitName="demo")
protected EntityManager em;</span>
(5)打包并部署到JBoss服务器
完成了以上的开发,我们就可以将当前应用发布到JBoss中,形成JNDI服务以供外部访问了。发布的方法很简单,只需要导出该项目的JAR包到JBoss服务器的部署目录%Jboss_Home%\server\default\deploy即可。然后JBoss服务器就会自动加载该服务,创建数据库表,并且发布JNDI服务UserManagerBean/remote,我们就可以通过客户端访问JNDI服务UserManagerBean/remote了。
(6)开发客户端进行测试
首先我们需要把实体类User.java和接口类UserManager.java导出为Jar包添加到客户端项目的类路径下,然后新建测试类UserManagerClient.java,代码如下:
<span style="font-size:18px;">/**
* @ClassName: 用户管理的客户端测试类
* @Description: 用户管理的客户端测试类
* @author 孙丽端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class UserManagerClient {
public static void main(String[] args) throws NamingException {
InitialContext context = new InitialContext();
UserManager usermanager = (UserManager)context.lookup("UserManagerBean/remote");
User user = new User();
user.setUsername("孙丽端");
user.setPassword("sunliduan");
usermanager.addUser(user);
System.out.print("用户已经成功保存!");
}
}</span>
该类就通过访问远程JNDI服务“UserManagerBean/remote”,取得了远程会话Bean实例usermanager。然后创建了一个实体对象,调用addUser方法插入该对象。
这样就是一个完整的利用实体Bean向数据库中添加数据的一个小demo了。最后用一张图来表示一下以上六个过程之间的关系: