EJB3的运行环境
EJB3.0应用需要运行在JDK1.5以上版本。
进入http://java.sun.com/javase/downloads/index_jdk5.jsp下载JDK。在页面中找到JDK 5.0 Update 16(版本在不断更新中,有可能大于16),点击右边的Download。
按照安装向导提示安装,安装路径选择C:\Java\jdk1.5.0_16。Jdk安装完后,接着问你是否安装jre,也一起安装上。
右键点击“我的电脑”->“属性”->“高级”->“环境变量”,在“系统变量”里添加JAVA_HOME 变量,值为JDK的安装路径,如:C:\ Java\jdk1.5.0_16。
在“系统变量”里再添加CLASSPATH变量,值为:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
在系统变量栏找到变量名为Path的选项,点“编辑”在变量值的末尾添加;%JAVA_HOME%\bin;
EJB3.0应用需要运行在EJB容器里,下面是一些JavaEE应用服务器,JavaEE应用服务器包含Web容器和EJB容器。
Jboss(4.2.x以上版本)
是一个成熟的开源的准JavaEE应用服务器,在开源JavaEE应用服务器中所占市场份额第一。如果你打算选用开源的JavaEE应用服务器,那么jboss是最值得选择的。
Glassfish
是一个开源的JavaEE应用服务器,对JavaEE规范的支持非常好,其运行性能比较高。因为发展时间相对较短,市场占有率比较低。另外,它能否提供稳定的运行性能,还有待时间的考验。但本人对其后期的发展非常看好。绝对跟jboss有的一拼。
Weblogic(10以上版本)
是商业市场占有率第一的商业JavaEE应用服务器,它具有出色的稳定性,并提供了人性化的管理界面,还有企业需要使用到的众多功能。但在ejb3.0领域,本人认为它做的比jboss差些,bug比较多。
Sun Application Server(9.0以上版本)
商业JavaEE应用服务器,如果你打算选用商业应用服务器运行ejb3,这个是不错的选择。
Oracle Application Server(10g以上版本)
商业JavaEE应用服务器,如果你的数据库是oracle,要想兼容性更好,这个是不错的选择。
apusic应用服务器
这是国内的商业JavaEE应用服务器,主要在政府中占有一定的市场份额。要批评的是,其向开发人员提供的文档实在太少了,本人曾经想在其上面开发应用,结果找了大半天也没有找到需要的开发文档。
注意:Tomcat目前只是Web容器,它不能运行EJB应用。
下载与安装jboss
进入http://labs.jboss.com/jbossas/downloads/下载页面,选择jboss4.2.3.GA下载(大小为95MB),如果你安装的jdk是1.5版本,请选择jboss-4.2.3.GA.zip 文件下载。 如果你安装的jdk是1.6版本,请选择jboss-4.2.3.GA-jdk6.zip 文件下载。下载后直接解压缩文件即可完成安装,为了避免应用出现莫名的错误,解压缩的路径最好不要带有空格和中文,如"Program Files"。
启动JBoss
进入jboss的bin目录,找到启动脚本run.bat 。双击run.bat即可启动jboss,此时启动的配置项为default。
如果启动出错,请检查下列情况:
1.端口是否被占用,如:8080、1099
2是否为JDK设置的JAVA_HOME和ClassPath系统变量,如果没有,请按照前面视频介绍的方法设置。
3.检查jboss所用的jdk是否1.5以上版本,这些信息可以在jboss的控制台观察到。
4.如果启动时出现这样的错误:“findstr不是内部或外部命令,也不是可运行的程序或批处理文件”。那么应该在系统变量Path中追加“%SystemRoot%\system32;%SystemRoot%;”。
最后的办法是重装机器上的JDK,祝你好运。
为jboss设置JBOSS_HOME系统变量
因为在后面的学习中,我们需要使用到系统变量JBOSS_HOME,它指向jboss的安装路径。所以安装完后我们需要添加该变量,方法是:右键点击“我的电脑”->“属性”->“高级”->“环境变量”,在“系统变量”里添加JBOSS_HOME变量,值为Jboss的安装路径,如:D:\JavaEEServer\jboss。
为了方便输入jboss的命令,我们把jboss的bin目录添加到系统路径里。在系统变量一栏找到变量名为Path的选项,点“编辑”在变量值的末尾添加:;%JBOSS_HOME%\bin;
EJB中的三种bean
1.会话bean(session bean)
负责与客户端交互,是编写业务逻辑的地方,在会话bean中可以通过jdbc直接操作数据库,但大多数情况下都是通过实体bean来完成对数据库的操作.
2.实体bean(entity bean)
它实际上属于java持久化规范(简称JPA)里的技术, JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink等ORM框架各自为营的局面。
3.消息驱动bean(message-driven bean)
它是专门用于异步处理java消息的组件.具有处理大量并发消息的能力.
会话bean
无状态会话bean
平常,我们使用最多的是无状态bean,因为它的bean实例可供多个用户使用,所以它的性能比有状态bean高.正因为一个bean实例被多个用户使用.那么,前一个用户设置的值有可能被后一个用户所修改,所以它无法正确保存某个用户设置的值,因此是无状态的.
有状态会话bean
有状态bean平常使用的并不多,因为它的一个bean实例只供一个用户使用,所以性能开销比较大,正因为它的实例只被一个用户使用, 用户为它设置的值是不会被其他用户修改,所以可以正确保存用户设置的值,因此是有状态的.
实体bean
它属于java持久化规范(简称JPA)里的技术,实体bean通过元数据在javabean和数据库表之间建立起映射关系,然后Java程序员就可以随心所欲的使用面向对象的编程思想来操纵数据库。 JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,目前实现的JPA规范的主流产品有Hibernate、TopLink和OpenJPA,在jboss中采用了Hibernate 作为其持久化实现产品。
Java消息服务(Java Message Service)
Java 消息服务(Java Message Service,简称 JMS)是用于访问企业消息系统的开发商中立的API。企业消息系统可以协助应用软件通过网络进行消息交互。
JMS的编程过程很简单,概括为:应用程序A发送一条消息到消息服务器的某个目得地(Destination),然后消息服务器把消息转发给应用程序B。因为应用程序A和应用程序B没有直接的代码关连,所以两者实现了解偶。
消息传递系统的中心就是消息。一条 Message 由三个部分组成:
头(header),属性(property)和主体(body)。
消息有下面几种类型,他们都是派生自 Message 接口。
StreamMessage:一种主体中包含 Java 基元值流的消息。其填充和读取均按顺序进行。
MapMessage:一种主体中包含一组名-值对的消息。没有定义条目顺序。
TextMessage:一种主体中包含 Java 字符串的消息(例如,XML 消息)。
ObjectMessage:一种主体中包含序列化 Java 对象的消息。
BytesMessage:一种主体中包含连续字节流的消息。
JMS 支持两种消息传递模型:点对点(point-to-point,简称 PTP)和发布/订阅(publish/subscribe,简称 pub/sub)。这两种消息传递模型非常相似,但有以下区别:
PTP 消息传递模型规定了一条消息只能传递给一个接收方。 采用javax.jms.Queue 表示。
Pub/sub 消息传递模型允许一条消息传递给多个接收方。采用javax.jms.Topic表示
这两种模型都通过扩展公用基类来实现。例如:javax.jms.Queue 和javax.jms.Topic 都扩展自javax.jms.Destination 类。
下面记录:实体Bean开发(EntityBean)
一、首先,将JBoss服务器加载到MyEclipse中来
windows -> MyEclipse -> Application Servers -> JBoss -> 选择你安全装的版本 -> 将JBoss Server 改成 Enable,在下面JBoss home drictory:选择你JBoss的安装路径。
在安装的版本 -> JDK -> JBoss JDK name 下选择你安装的JDK版本即可。
二、新建一个Java项目:EntityBean
将JBoss安装目录下client文件夹中的所有包导入到项目中来
将mysql的驱动包放在JBoss的安装目录下server\default\lib中
在项目的根目录下新建xml文件:build.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!--.表示同一目录 ..表示在上一目录-->
<project name="EntityBean" basedir=".">
<property name="src.dir" value="${basedir}\src"/>
<property environment="env"/>
<property name="jboss.home" value="${env.JBOSS_HOME}"/>
<property name="jboss.server.config" value="default"/>
<property name="build.dir" value="${basedir}\build"/>
<path id="build.classpath">
<fileset dir="${jboss.home}\client">
<include name="*.jar"/>
</fileset>
<pathelement location="${build.dir}"/>
</path>
<target name="prepare" >
<delete dir="${build.dir}"/>
<mkdir dir="${build.dir}"/>
</target>
<target name="compile" depends="prepare" description="编译">
<javac srcdir="${src.dir}" destdir="${build.dir}" includes="cn/**">
<classpath refid="build.classpath"/>
</javac>
</target>
<target name="ejbjar" depends="compile" description="创建ejb发布包">
<jar jarfile="${basedir}\${ant.project.name}.jar">
<fileset dir="${build.dir}">
<include name="**/*.class"/>
</fileset>
<!--把persistence.xml打包到META-INF目录下-->
<metainf dir="${src.dir}\META-INF"></metainf>
</jar>
</target>
<target name="deploy" depends="ejbjar" description="ejb发布">
<copy file="${basedir}\${ant.project.name}.jar" todir="${jboss.home}\server\${jboss.server.config}\deploy"/>
</target>
<target name="undeploy" description="卸载ejb">
<delete file="${jboss.home}\server\${jboss.server.config}\deploy\${ant.project.name}.jar"/>
</target>
</project>
在项目的类路径下新建META-INF文件夹,并在其中新建xml文件:persistence.xml,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="itcast" transaction-type="JTA">
<jta-data-source>java:itcastDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<!-- 显示最终执行的SQL -->
<property name="hibernate.show_sql" value="true"/>
<!-- 格式化显示的SQL -->
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
在项目的类路径下新建文件:jndi.properties,内容代码如下:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
最后新建一个xml文件mysql-ds.xml,将文件mysql-ds.xml放入JBoss的安装目录下的server\default\deploy中,文件mysql-ds.xml的代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>itcastDS</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/itcast?useUnicode=true&characterEncoding=UTF-8</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>root</password>
<min-pool-size>3</min-pool-size>
<max-pool-size>100</max-pool-size>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
到这儿所有的环境都配置好了。
三、编写JavaBean
在类路径下新建文件Product,放在cn.itcast.bean包下,其代码如下:
package cn.itcast.bean;
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="product")
public class Product implements Serializable{
private static final long serialVersionUID = -3813144866607467433L;
private Integer id;
private String name;
public Product(){}
public Product(String name) {
this.name = name;
}
@Id @Column(name="id") @GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="name",length=20,nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Product other = (Product) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
四、编写数据库操作类
新建接口ProductService,放在类路径下的cn.itcast.service包下,代码如下:
package cn.itcast.service;
import java.util.List;
import cn.itcast.bean.Product;
public interface ProductService {
public void save(Product product);
public void update(Product product);
public void delete(Integer productid);
public Product getProduct(Integer productid);
public List<Product> getProducts();
}
新建接口ProductService的实现类ProductServiceBean,放在类路径下的cn.itcast.service.impl包下,代码如下:
package cn.itcast.service.impl;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import cn.itcast.bean.Product;
import cn.itcast.service.ProductService;
@WebService(targetNamespace="http://ws.itcast.cn",name="ProductService",
serviceName="ProductServiceBean")
@Stateless
@Remote(ProductService.class)
public class ProductServiceBean implements ProductService {
@PersistenceContext(unitName="itcast") EntityManager em;
public void delete(Integer productid) {
em.remove(em.getReference(Product.class, productid));
}
public Product getProduct(Integer productid) {
return em.find(Product.class, productid);
}
@SuppressWarnings("unchecked")
public List<Product> getProducts() {
return em.createQuery("select o from Product o").getResultList();
}
public void save(Product product) {
em.persist(product);
}
public void update(Product product) {
em.merge(product);
}
}
五、编写Junit测试
新建ProductServiceTest 类,将其放在类路径下的junit.test包下,代码如下:
package junit.test;
import java.util.List;
import javax.naming.InitialContext;
import org.junit.BeforeClass;
import org.junit.Test;
import cn.itcast.bean.Product;
import cn.itcast.service.ProductService;
public class ProductServiceTest {
private static ProductService productService;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
try {
InitialContext ctx = new InitialContext();
productService = (ProductService) ctx.lookup("ProductServiceBean/remote");
} catch (RuntimeException e) {
System.out.println("有错误!");
e.printStackTrace();
}
}
@Test
public void testSave() {
productService.save(new Product("2"));
}
@Test
public void testUpdate() {
Product product = productService.getProduct(2);
product.setName("OK");
productService.update(product);
}
@Test
public void testDelete() {
productService.delete(1);
}
@Test
public void testGetProduct() {
Product product = productService.getProduct(1);
System.out.println(product.getName());
}
@Test
public void testGetProducts() {
List<Product> products = productService.getProducts();
for(Product product : products){
System.out.println(product.getName());
}
}
}
六、下面开始测试
1.先启动JBoss服务:
window -> show view -> other ->MyEclipse Enterprise Workbench -> Servers,启动JBoss
2.发布该项目:
打开build.xml,右击Outline窗口的deploy -> Run As -> Ant Build
3.再打开ProductServiceTest,进行测试即可。