EJB3.0学习总结(一)--实体Bean(EntityBean)

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&amp;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,进行测试即可。

你可能感兴趣的:(java,应用服务器,bean,jboss,javaee)