上文我们对会话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了。最后用一张图来表示一下以上六个过程之间的关系: