Eclipse开发EJB3
开发环境:
MyEclipse 5.5
jboss-4.2.0.GA
1. 创建 EJB工程(图1):
(图1)
输入EJB工程名称,以及持久化文件配置信息,如下图:
Persistence Unit Name : 输入数据库的名称如:tDB
JNDI Data Source : 输入JBOSS 中配置的数据源名称如:java:MSSQLDS
点击 ”finish”,如(图2)
(图2)
2.创建数据库连接,显示数据库中的表:
Window ----> preferences 选择 MyEclipse ----- > Database Explorer ------ > Database Drivers ----- > DB Browser 操作
如(图3)
(图3)
创建一个连接,注意要选择正确的数据库驱动程序,如(图4)。
(图4)
根据数据库表生成实体BEAN,如(图4-1):
(图4-1)
选择正确的包名称,按以下的方式填写信息,点击“Next”或者 ”finish” ,自动生成实体BEAN信息,如(图5)。
(图5)
3创建Session Bean,如(图6):
(图6)
选择 EJB3 Session Bean ,点击 ”Next”,如(图7)
(图7)
按以下的方式创建 Session Bean 点击 ”finish”,如(图8)
(图8)
根据上面创建的 session bean 添加业务方法:
远程接口业务及方法定义如下:
package com.session;
import java.util.List;
import javax.ejb.Remote;
import com.entity.Curstomer;
@Remote
public interface CustomerDAORemote {
// 按ID 进行查询
public Curstomer getCustomerById(Integer id);
// 按 名称进行查询
public List getCustomerByName(String name);
// 查询所有 信息
public List getCustomerAll();
}
接口实现类如下:
package com.session;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.entity.Curstomer;
@Stateless
public class CustomerDAO implements CustomerDAORemote {
@PersistenceContext
EntityManager manager ;
// 按ID 进行查询
public Curstomer getCustomerById(Integer id){
return manager.find(Curstomer.class, id);
}
// 按 名称进行查询
public List getCustomerByName(String name){
Query query = manager.createQuery(" from Curstomer c where c.curstomername = :cname");
query.setParameter("cname", name);
List list = query.getResultList();
return list;
}
// 查询所有 信息
public List getCustomerAll(){
Query query = manager.createQuery(" from Curstomer");
return query.getResultList();
}
}
编写好EJB后需要打包部署后才能访问,启动JBOSS 服务,打包EJB工程,选择打包的工程,按以下方式打包,如(图9)。
(图9)
选择 jar file,如(图10) .
(图10)
选择 jboss 的服务,本例使用 default 服务。然后点击 “finish”,如(图11)
(图11)
下面创建客户端工程调用以上发布的EJB组件,创建工程,如(图12):
(图12)
输入工程名称,按以下方式进行设置,点击”finish”,如(图 13)
(图13)
在工程中加入 jbossall-client (在 jboss-4.2.0.GA/client 目录下) 和 上面部署在jboss 服务中的ejb 组件包 ejbDemo.jar,
如(图14)
(图14)
编写客户端测试程序:
package com.client;
import java.util.List;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import com.entity.Curstomer;
import com.session.CustomerDAORemote;
public class CustomerClient {
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.put("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
p.put("java.naming.factory.url.pkgs",
"org.jboss.naming:org.jnp.interfaces");
p.put("java.naming.provider.url", "localhost:1099");
Context ctx = new InitialContext(p) ;
CustomerDAORemote remote = (CustomerDAORemote) ctx.lookup("CustomerDAO/remote");
// 通过ID 获取信息
Curstomer curstomer1 = remote.getCustomerById(new Integer(1));
System.out.println("--- by Id name = " + curstomer1.getCurstomername());
System.out.println("--- by Id add = "+ curstomer1.getCurstomeraddress());
System.out.println("----------------------------------------------");
// 通过名称 获取信息
List list = remote.getCustomerByName("scott");
System.out.println("--- list.size = " + list.size());
for (int i = 0; i < list.size(); i++) {
Curstomer curstomer = (Curstomer) list.get(i);
System.out.println("--- custoomerByName name = "
+ curstomer.getCurstomername());
System.out.println("--- custoomerByName address = "+ urstomer.getCurstomeraddress());
}
System.out.println("-----------------------------------------------");
// 查询所有信息
List listAll = remote.getCustomerAll();
System.out.println("--- listAll.size = " + listAll.size());
for (int i = 0; i < listAll.size(); i++) {
Curstomer c = (Curstomer) listAll.get(i);
System.out.println("--- customerAll name = "+ c.getCurstomername());
System.out.println("--- customerAll address = "+ c.getCurstomeraddress());
}
}
}
以上客户端程序运行结果如下:如(图15)
(图15)
EJB3 在WEB 中的应用。下面代码将演示如何在WEB 工程中操作表与表之间的关系,按照上面的操作建立EJB工程 以及WEB工程。
首先建立EJB工程,创建工程的步骤参照图1 和图2 的方式进行,给工程取个名字如:EJB3DBProject
创建author 和 book 表:
CREATE TABLE [dbo].[author] (
[authorId] [int] IDENTITY (1, 1) NOT NULL ,
[authorName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[authorEmail] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[authorPhone] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[book] (
[bookId] [int] IDENTITY (1, 1) NOT NULL ,
[bookName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[publish] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[price] [float] NULL ,
[authorId] [int] NULL
) ON [PRIMARY]
为以上两个表建立主外键关系,如(图16):
(图16)
.创建数据库连接,显示数据库中的表:
Window ----> preferences 选择 MyEclipse ----- > Database Explorer ------ > Database Drivers ----- > DB Browser 操作,
如(图17)
(图17)
按照 (图4-1)的方式创建实体Bean .。 把(图17) 中显示的 book 和author 表创建对应的实体Bean
此时可以看到book 和author 实体Bean 之间建立了一对多和多一关系。
下面创建 会话bean 调用 实体Bean 操作。按照 (图7 和 图8)的方式创建 AuthorDAO 会话 Bean.
创建后的Session Bean 接口和实现类源代码如下,注意红颜色的代码:
package com.session;
import java.util.List;
import javax.ejb.Remote;
import com.entity.Author;
@Remote
public interface AuthorDAORemote {
// 根据 作者ID 返回作者信息
public Author getAuthorById(Integer id);
// 根据 作者ID 返回作者关联的书本信息
public List getAuthorRelationId(Integer id);
// 根据作者名称查询数据
public Author getAuthorByName(String name);
// 查询所有的作者信息
public List getAuthorAll();
//添加作者信息
public void addAuthor(Author author);
}
接口实现类代码如下:
AuthorDAO:
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.entity.Author;
@Stateless
public class AuthorDAO implements AuthorDAORemote {
@PersistenceContext
EntityManager manager;
// 根据 作者ID 返回作者信息
public Author getAuthorById(Integer id) {
return manager.find(Author.class, id);
}
// 根据 作者ID 返回作者关联的书本信息
public List getAuthorRelationId(Integer id) {
Query query = manager
.createQuery(" from Author a inner join fetch a.books where a.authorId = :aid");
query.setParameter("aid", id);
return query.getResultList();
}
// 根据作者名称查询数据,并且返回作者关联的书本信息
public Author getAuthorByName(String name) {
Query query = manager.createQuery(" from Author a where a.authorName = ?1");
query.setParameter(1, name);
Author author = (Author)query.getSingleResult();
author.getBooks().size();
return author;
}
// 查询所有的作者信息
public List getAuthorAll() {
return manager.createQuery("from Author").getResultList();
}
// 添加作者信息
public void addAuthor(Author author){
manager.persist(author);
}
}
打包并且部署以上EJB 组件(如图9 和图10 方式),给部署的jar 包取一个名称,如:ejb3db.jar。
编写客户端代码,测试以上会话 Bean,以下代码演示如何在WEB 工程中进行EJB调用。以及当表与表之间建立关系后该如何进行查询。
创建一个WEB 工程 ,取名为:EJB3DBProjectClient,为工程增加 Struts 支持。把上面的 EJB 如ejb3db.jar 加入到工程的 classPath中。由于WEB 工程部署到JBOSS 服务器中,它与EJB 组件是在同一JVM 中,所以不需要加载任何其他 jar 包(加了其他的包反而会出错).
编写相对应的JSP 和 Action 代码:
fChoose.jsp 功能选择页面。
authorAll.jsp 显示所有作者信息
authorSearch.jsp 作者信息查询页面(根据作者ID 和作者名称进行查询,并且显示作者对应的书本信息)
addAuthor.jsp 添加作者信息.
ShowAuthorAllAction.java 根据fChoose.jsp 的连接 显示所有作者信息。
SearchAuthorAction.java 根据authorSearch.jsp 的查询条件进行查询操作
AuthorAction.java 根据addAuthor.jsp 进行插入操作
AuthorForm.java 封装addAuthor.jsp 对应的Field
SearchAuthorForm.java 封装authorSearch.jsp 对应的Field
ContextUtil.java 获取 jboss 服务中的上下文信息
以下代码对上面的文件进行一一实现:
fChoose.jsp(图18) 功能选择页面选择一个连接,
(图18)
图18 页面代码如下:
<body>
<h3 align="center">功能选择页面</h3>
<html:link page="/showAuthorAll.do">显示所有作者信息</html:link><br>
<html:link page="/searchAuthor.do?method=showSearchPage">查询作者信息</html:link><br>
<html:link page="/addAuthor.jsp">添加作者信息</html:link>
</body>
选择一个链接如:“ 显示所有作者信息“,将通过ShowAuthorAllAction.java类查询所有的作者信息:代码如下:
public class ShowAuthorAllAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
try{
Context ctx = ContextUtil.getInitialContext();
AuthorDAORemote authorRemote = (AuthorDAORemote)ctx.lookup("AuthorDAO/remote");
List authorList = authorRemote.getAuthorAll();
request.setAttribute("authorList", authorList);
}catch(Exception ex){
ex.printStackTrace();
}
return mapping.findForward("showAll");
}
}
ShowAuthorAllAction.java 将通过转发机制转到 authorAll.jsp ,显示结果如图19
(图19)
图19 对应的代码如下:
(图20)
选择一个链接如:“查询作者信息“ 将在authorSearch.jsp 中通过作者ID 和作者名称进行查询,并且把作者对应的
所有书本信息进行显示,如图21。
(图21)
图21 的JSP 代码对应如下:
<body>
<table width="80%">
<tr>
<td>
<html:form action="/searchAuthor.do?method=searchAuthorById">
请输入一个ID<html:text property="authorId"/><html:submit value="提交"/>
</html:form>
</td>
</tr>
<tr>
<td>
<html:form action="/searchAuthor.do?method=searchAuthorByName">
请输入名称:<html:text property="authorName"/><html:submit value="提交"/>
</html:form>
</td>
</tr>
</table>
<table width="80%">
<logic:present name="authorInfo" scope="request">
<tr><td>作者ID:<bean:write name="authorInfo" property="authorId"/></td></tr>
<tr><td>作者名称:<bean:write name="authorInfo" property="authorName"/></td></tr>
<tr><td>作者Email:<bean:write name="authorInfo" property="authorEmail"/></td></tr>
<tr><td>作者电话:<bean:write name="authorInfo" property="authorPhone"/></td></tr>
</logic:present>
</table>
<br>
作者对应的书本信息为:<br>
<table width="80%">
<tr><td>书本ID</td><td>书本名称</td><td>出版社</td><td>价格</td></tr>
<logic:present name="aToBookList">
<logic:iterate id="book" name="aToBookList" scope="request">
<tr>
<td><bean:write name="book" property="bookId"/></td>
<td><bean:write name="book" property="bookName"/></td>
<td><bean:write name="book" property="publish"/></td>
<td><bean:write name="book" property="price"/></td>
</tr>
</logic:iterate>
</logic:present>
</table>
</body>
图21中当输入一个ID 或者名称时,提交到 SearchAuthorAction.java 进行处理。相应的代码如下:
public class SearchAuthorAction extends DispatchAction {
public ActionForward showSearchPage(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
return mapping.findForward("authorSearch");
}
/* 按作者 ID 进行查询,返回作者对应的所有书本信息 */
public ActionForward searchAuthorById(ActionMapping mapping,
ActionForm form, HttpServletRequest request,HttpServletResponse response) {
// TODO Auto-generated method stub
SearchAuthorForm searchForm = (SearchAuthorForm) form;
String id = searchForm.getAuthorId();
try {
Context ctx = ContextUtil.getInitialContext();
AuthorDAORemote authorRemote = (AuthorDAORemote) ctx.lookup("AuthorDAO/remote");
// 根据作者ID 获取作者信息.
List list = authorRemote.getAuthorRelationId(new Integer(id));
if (list.size() > 0) {
Author author = (Author) list.get(0);
// 根据作者ID 获取作者对应所有书本信心
Set bookList = author.getBooks();
request.setAttribute("authorInfo", author);
request.setAttribute("aToBookList", bookList);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return mapping.findForward("authorSearch");
}
/* 按作者 名称进行查询,返回作者对应的所有书本信息 */
public ActionForward searchAuthorByName(ActionMapping mapping,
ActionForm form, HttpServletRequest request,HttpServletResponse response) {
// TODO Auto-generated method stub
SearchAuthorForm searchForm = (SearchAuthorForm) form;
String authorName = searchForm.getAuthorName();
try {
Context ctx = ContextUtil.getInitialContext();
AuthorDAORemote authorRemote = (AuthorDAORemote) ctx.lookup("AuthorDAO/remote");
// 根据作者名称获取作者信息.
Author author = authorRemote.getAuthorByName(authorName);
if(author!=null){
// 根据作者ID 获取作者对应所有书本信心
Set bookList = author.getBooks();
request.setAttribute("authorInfo", author);
request.setAttribute("aToBookList", bookList);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return mapping.findForward("authorSearch");
}
}
选择一个链接如:“添加作者信息 “,连接到addAuthor.jsp显示添加作者信息页面:
(图22)
图22 对应的JSP 代码如下:
addAuthor.jsp
点击 图22 提交按钮 提交到AuthorAction.java ,由AuthorAction.java 调用 Session Bean 的插入代码 保存作者信息到数据库中:
AuthorAction.java 代码如下:
public class AuthorAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
AuthorForm authorForm = (AuthorForm) form;// TODO Auto-generated method stub
String authorName = authorForm.getAuthorName(); //获取输入的名称
String email = authorForm.getAuthorEmail(); //获取输入的Email信息
String phone = authorForm.getAuthorPhone(); //获取输入的电话信息
Author author = new Author();
author.setAuthorName(authorName);
author.setAuthorEmail(email);
author.setAuthorPhone(phone);
try {
Context ctx = ContextUtil.getInitialContext();
AuthorDAORemote authorRemote = (AuthorDAORemote) ctx.lookup("AuthorDAO/remote");
authorRemote.addAuthor(author);
request.setAttribute("info", "信息保存成功");
} catch (Exception ex) {
request.setAttribute("info", "信息保存失败");
ex.printStackTrace();
}
return mapping.findForward("addAuthor");
}
}
在以上代码演示中由于设置了数据库表是自动增长 ,需要改动实体bean 的ID 属性操作:
在 Author 和 Book 两个实体 Bean 的 ID 列上指定主键增长方式,如下:
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Column(name = "authorId", unique = true, nullable = false, insertable = true, updatable = true)
public Integer getAuthorId() {
return this.authorId;
}
AuthorForm.java 和 SearchAuthorForm.java 不进行一一实现。
ContextUtil.java 代码如下:
public class ContextUtil {
public static Context getInitialContext() throws Exception {
Properties p = new Properties();
p.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
p.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
p.put("java.naming.provider.url", "localhost:1099");
return new InitialContext(p);
}
}
Struts-config.xml 配置文件信息如下:
EJB3开发消息驱动Bean:
在上面的EJB工程中创建一个 MyMessageBean 类,代码如下:
package com.message;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/mytest") })
public class MyMessageBean implements MessageListener {
public void onMessage(Message msg) {
try {
TextMessage tmsg = (TextMessage) msg;
this. showMessage (tmsg.getText());
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void showMessage(String content) {
System.out.println("--- content = " + content);
}
}
重新部署EJB工程,在上面 EJB3DBProjectClient 工程中创建myJMS.jsp页面,用于访问消息驱动Bean。代码如下:
<%@ page language="java" pageEncoding="GBK"
import="java.util.*,javax.jms.Queue,javax.jms.QueueConnection,javax.jms.QueueSender,javax.jms.QueueSession,javax.naming.Context,javax.naming.InitialContext,javax.jms.QueueConnectionFactory,javax.jms.TextMessage"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles"%>
<html:html lang="true">
<head> <html:base /> <title>myJMS.jsp</title>
</head>
<body>
<br>
<%
QueueConnection cnn = null;
QueueSender sender = null;
QueueSession sess = null;
Queue queue = null;
try {
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");
InitialContext ctx = new InitialContext(props);
QueueConnectionFactory factory = (QueueConnectionFactory) ctx
.lookup("ConnectionFactory");
cnn = factory.createQueueConnection();
sess = cnn.createQueueSession(false,
QueueSession.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup("queue/mytest");
} catch (Exception e) {
out.println(e.getMessage());
}
TextMessage msg = sess.createTextMessage("this is Message content");
sender = sess.createSender(queue);
sender.send(msg);
sess.close();
out.println("send message success");
%>
</body>
</html:html>