EJB3.0简介
岳乡成
一、 EJB的简介
1、 什么是EJB
Enterprise JavaBeans(EJB)是一个用于分布式业务应用的标准服务器端组件模式。
Enterprise JavaBeans(EJB)定义了3种企业Bean,分别是会话Bean(Session Bean)、实体Bean(Entity Bean)和消息驱动Bean(Massage Driver Bean)。
2、 EJB的运行环境
EJB需要运行在EJB容器,每个Java EE应用服务器都含有EJB容器和Web容器,所以既可以运行EJB,也可以运行Web应用。目前支持EJB 3.0的应用服务器有JBoss,WebLogic等。
(注:Tomcat目前只是Web容器,它不能运行EJB应用。)
二、 会话Bean(Session Bean)
1、 什么是Session Bean
Session Bean用于实现业务逻辑。比如:要实现两个数的相加或是从数据库中读取数据,都是通过Session Bean来实现的。Session Bean相当于我们熟悉的Action类。
Session Bean分为两种:有状态Bean(Stateful Session Beans)和无状态Bean(Stateless Session Beans)。
要开发一个Session Bean,需要定义接口和bean class。其中接口分为远程(Remote)和本地(Local)接口。
远程接口(Remote interface):定义了Session Bean的业务方法,这些方法可以被来自EJB容器之外的应用访问到。
本地接口(Local interface):同样定义了Session Bean的业务方法,这些方法可以同处于EJB容器内的其他应用使用。因为local接口允许Bean之间直接通过内存交互,没有分布式对象协议的开销,从而改善了性能。
Bean类(bean class):Bean class包含了业务逻辑,它必须具备一个远程或本地接口。
2、 Stateless Session Bean(无状态Bean)
(1)无状态Bean不维护会话状态,意味着一个Bean实例可以为多个用户服务。简单的说,就是当无状态会话Bean部署到应用服务器时,EJB容器会为它预先创建一些Bean实例放在对象池。当有用户访问EJB方法时,EJB容器会从对象池中取出一个实例为之服务,服务完成后就回到对象池。当下一个用户再访问EJB方法时,EJB容器有可能再次把该实例取出来为之服务。正因为如此,无状态会话Bean只需要少量的实例就可以为成千上万个用户服务,大大提高了系统性能。
(2) 无状态Bean比有状态Bean更具性能优势,条件允许的情况下开发人员应该首先考虑使用无状态会话Bean。
(3)无状态Bean定义实例如下:
远程接口(Remote interface)如下:
@Remote
public interface NewsDAO extends DAO{
}
本地接口(Local interface)如下:
@Local
public interface NewsLocalDAO extends NewsDAO {
}
无状态Bean定义如下:
/**
* 新闻实体操作类
* @author xiangcheng.yue
*
*/
@Stateless(mappedName="NewsDAOBean")
@Remote (NewsDAO.class)
@Local(NewsLocalDAO.class)
public class NewsDAOBean extends DaoSupport implements NewsDAO, NewsLocalDAO {
}
(4)Stateless Session Bean的生命周期很简单只有两种状态——does not exist和method-ready pool,有兴趣的可以查阅相关资料,因为我们开发中可能不太关注Stateless Session Bean所处的状态,这里就不详细介绍了。但只值得注意的是Session Bean从一种状态转入到另一状态时,往往会产生一个事件,在Bean class类中可以通过注释,为该事件注册一个回调方法。
例如:一个Stateless Session Bean实例从does not exist到method-ready pool状态就会产生一个post-construction事件。可以为某个方法加@javax.annotation.PostConstruct注释做为该事件的回调方法。
@Stateless
@Remote(LifeCycle.class)
Public class LifeCycleBean implements LifeCycle{
@PostConstruct
Public void Construct(){
System.out.println(“Construct()方法被调用”);
}
}
3、 Stateful Session Bean(有状态Bean)
(1)Stateless Session Bean创建在对象池中,提供给众多用户使用,如果Bean class有自己的成员属性(变量),那么这些变量就会受到所有调用它的用户的影响。在一些应用场合中,有时需要每个用户都有自己的一个实例,这个实例不受其他用户的影响。就好比购物车对象,每个用户都应有自己的购物车,谁都不希望有人往自己的购物车里添加或拿掉商品,而有状态Bean正好满足满足了这种需求。每个有状态的Bean在Bean实例的生命周期内都只服务一个用户,Bean class的成员变量可以在不同的方法调用间维护特定于某个用户的数据。正因为在Bean实例的生命周期内Stateful Session Bean保持了用户的信息,所以叫有状态的Bean。
(2)Stateful Session Bean必须实现Serializable接口,这样EJB容器才能在它们不再使用时,把它们序列化保存到硬盘上。
(3)有状态Bean定义实例如下:
业务接口:Cart.java
import java.io.Serializable;
import java.util.List;
public interface Cart extends Serializable {
public void AddBuyItem(String productName);
public List<String> getBuyItem();
}
Bean类:
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateful;
import com.foshanshop.ejb3.Cart;
@SuppressWarnings("serial")
@Stateful
@Remote(Cart.class)
public class CartBean implements Cart{
private List<String> buyitem = new ArrayList<String>();
public void AddBuyItem(String productName) {
buyitem.add(productName);
}
public List<String> getBuyItem() {
return buyitem;
}
}
(4)Stateful Session Bean的生命周期有3个状态,如有兴趣自己研究。
三、实体Bean(Entity Bean)
1、什么是实体Bean
创建实体Bean的目的为了实现持久化,EJB3.0遵循的持久化规范是Java Persistence API,即JPA。JPA定义了一种方法,可以将常规的Java对象映射到数据库。这些普通的Java对象被叫做Entity Bean。其实除了用JPA元数据将其映射到数据库外,Entity Bean与其他Java类没有任何区别。就是我们熟悉的POJO。
2、Entity Bean介绍
(1)Entity Bean必须用@ Entity注明。
(2)Entity Bean必须用@id唯一标示主键。
(3)如果实体Bean对象需要返回客户端,必须实现 Serializable接口。
(4)通过在Entity Bean中加注释可以表示表和表的关联,例如:一对多要用@OneToMany来表示。
(5)JPA还提供了好多注解来实现别的功能,希望大家仔细研究。
3、Entity Bean的实例
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.GenerationType;
@SuppressWarnings("serial")
@Entity
@Table(name = "Person")
public class Person implements Serializable{
private Integer personid;
private String name;
private boolean sex;
private Short age;
private Date birthday;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getPersonid() {
return personid;
}
public void setPersonid(Integer personid) {
this.personid = personid;
}
@Column(nullable=false,length=32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(nullable=false)
public boolean getSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Column(nullable=false)
public Short getAge() {
return age;
}
public void setAge(Short age) {
this.age = age;
}
@Temporal(value=TemporalType.DATE)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
4、 实体Bean的管理器EntityManaager
EntityManaager可以用来添加、删除、更新实体Bean,通过主键查找实体Bean。
EntityManaager管理实体Bean的实例如下:
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.foshanshop.ejb3.PersonDAO;
import com.foshanshop.ejb3.bean.Person;
@Stateless
@Remote (PersonDAO.class)
public class PersonDAOBean implements PersonDAO {
@PersistenceContext
protected EntityManager em;
public void insertPerson(Person person) {
em.persist(person);
}
public Person getPersonByID(int personid) {
return em.find(Person.class, personid);
}
public void mergePerson(Person person) {
em.merge(person);
}
@SuppressWarnings("unchecked")//关闭unchecked警告
public List<Person> getPersonList() {
Query query = em.createQuery("select o from Person o order by o.personid asc");
return (List<Person>) query.getResultList();
}
public void deletePerson(int personid) {
Person person = em.find(Person.class, personid);
if(person!=null) em.remove(person);
}
public void updateName(String newname, int personid) {
Person person = em.find(Person.class, personid);
if(person!=null) person.setName(newname);
}
}
5、 EntityManaager操作数据的方式
(1)利用EntityManaager提供的方法对实体Bean操作。
#用find()或getReference()方法得到实体。
例如:
@PersistenceContext
protected EntityManager em;
public Person getPersonByID(int personid) {
return em.find(Person.class, personid);
}
#用persist()方法保存实体
例如:
@PersistenceContext
protected EntityManager em;
public void insertPerson(Person person) {
em.persist(person);
}
#用merger()方法更新实体
例如:
@PersistenceContext
protected EntityManager em;
public void mergePerson(Person person) {
em.merge(person);
}
#用remoove()方法删除实体
例如:
@PersistenceContext
protected EntityManager em;
public void deletePerson(int personid) {
Person person = em.find(Person.class, personid);
if(person!=null) em.remove(person);
}
(2)操作实体Bean通过EJB QL
EJB QL是JPA提供的一种声明性的查询语言,它可以直接操作实体Bean。相当于我们熟悉的HSQL语句。
javax.persistence.Query是EJB3查询操作的接口。进行查询,首先要通过EntityManager 获得Query对象。
EntityManager为执行EJB QL语句提供了两种方法,createQuery(String ejbqlString)和createNamedQuery(String name)。
createQuery()方法得实例如下:
@PersistenceContext
private EntityManager em;
public List findByName(String first,String last){
Query query = entityManager.createQuery( "select o from Customer o where o.firstName = : first and o.lastName = : last" );
query.setParameter( " first ", first );
query.setParameter( " last ", " last " );
return query. getResultList();
}
createNamedQuery()如何使用请参考相关的文档。
(3)查询数据通过原生SQL
EntityManager为执行原生的SQL提供了三种方式,createNativeQuery(String sqlString),createNativeQuery(String sqlString,Class resultClass),createNativeQuery(String sqlString,String resultSetMapping)。
createNativeQuer(String sqlString,String resultSetMapping)方式实例如下:
@PersistenceContext
private EntityManager em;
Query query = entityManager. createNativeQuery ( "select p.phone_pk,p. phone_number, p.type from phone p ", Phone.class );
其他的两种方式请参考相关文档。
岳乡成
一、 EJB的简介
1、 什么是EJB
Enterprise JavaBeans(EJB)是一个用于分布式业务应用的标准服务器端组件模式。
Enterprise JavaBeans(EJB)定义了3种企业Bean,分别是会话Bean(Session Bean)、实体Bean(Entity Bean)和消息驱动Bean(Massage Driver Bean)。
2、 EJB的运行环境
EJB需要运行在EJB容器,每个Java EE应用服务器都含有EJB容器和Web容器,所以既可以运行EJB,也可以运行Web应用。目前支持EJB 3.0的应用服务器有JBoss,WebLogic等。
(注:Tomcat目前只是Web容器,它不能运行EJB应用。)
二、 会话Bean(Session Bean)
1、 什么是Session Bean
Session Bean用于实现业务逻辑。比如:要实现两个数的相加或是从数据库中读取数据,都是通过Session Bean来实现的。Session Bean相当于我们熟悉的Action类。
Session Bean分为两种:有状态Bean(Stateful Session Beans)和无状态Bean(Stateless Session Beans)。
要开发一个Session Bean,需要定义接口和bean class。其中接口分为远程(Remote)和本地(Local)接口。
远程接口(Remote interface):定义了Session Bean的业务方法,这些方法可以被来自EJB容器之外的应用访问到。
本地接口(Local interface):同样定义了Session Bean的业务方法,这些方法可以同处于EJB容器内的其他应用使用。因为local接口允许Bean之间直接通过内存交互,没有分布式对象协议的开销,从而改善了性能。
Bean类(bean class):Bean class包含了业务逻辑,它必须具备一个远程或本地接口。
2、 Stateless Session Bean(无状态Bean)
(1)无状态Bean不维护会话状态,意味着一个Bean实例可以为多个用户服务。简单的说,就是当无状态会话Bean部署到应用服务器时,EJB容器会为它预先创建一些Bean实例放在对象池。当有用户访问EJB方法时,EJB容器会从对象池中取出一个实例为之服务,服务完成后就回到对象池。当下一个用户再访问EJB方法时,EJB容器有可能再次把该实例取出来为之服务。正因为如此,无状态会话Bean只需要少量的实例就可以为成千上万个用户服务,大大提高了系统性能。
(2) 无状态Bean比有状态Bean更具性能优势,条件允许的情况下开发人员应该首先考虑使用无状态会话Bean。
(3)无状态Bean定义实例如下:
远程接口(Remote interface)如下:
@Remote
public interface NewsDAO extends DAO{
}
本地接口(Local interface)如下:
@Local
public interface NewsLocalDAO extends NewsDAO {
}
无状态Bean定义如下:
/**
* 新闻实体操作类
* @author xiangcheng.yue
*
*/
@Stateless(mappedName="NewsDAOBean")
@Remote (NewsDAO.class)
@Local(NewsLocalDAO.class)
public class NewsDAOBean extends DaoSupport implements NewsDAO, NewsLocalDAO {
}
(4)Stateless Session Bean的生命周期很简单只有两种状态——does not exist和method-ready pool,有兴趣的可以查阅相关资料,因为我们开发中可能不太关注Stateless Session Bean所处的状态,这里就不详细介绍了。但只值得注意的是Session Bean从一种状态转入到另一状态时,往往会产生一个事件,在Bean class类中可以通过注释,为该事件注册一个回调方法。
例如:一个Stateless Session Bean实例从does not exist到method-ready pool状态就会产生一个post-construction事件。可以为某个方法加@javax.annotation.PostConstruct注释做为该事件的回调方法。
@Stateless
@Remote(LifeCycle.class)
Public class LifeCycleBean implements LifeCycle{
@PostConstruct
Public void Construct(){
System.out.println(“Construct()方法被调用”);
}
}
3、 Stateful Session Bean(有状态Bean)
(1)Stateless Session Bean创建在对象池中,提供给众多用户使用,如果Bean class有自己的成员属性(变量),那么这些变量就会受到所有调用它的用户的影响。在一些应用场合中,有时需要每个用户都有自己的一个实例,这个实例不受其他用户的影响。就好比购物车对象,每个用户都应有自己的购物车,谁都不希望有人往自己的购物车里添加或拿掉商品,而有状态Bean正好满足满足了这种需求。每个有状态的Bean在Bean实例的生命周期内都只服务一个用户,Bean class的成员变量可以在不同的方法调用间维护特定于某个用户的数据。正因为在Bean实例的生命周期内Stateful Session Bean保持了用户的信息,所以叫有状态的Bean。
(2)Stateful Session Bean必须实现Serializable接口,这样EJB容器才能在它们不再使用时,把它们序列化保存到硬盘上。
(3)有状态Bean定义实例如下:
业务接口:Cart.java
import java.io.Serializable;
import java.util.List;
public interface Cart extends Serializable {
public void AddBuyItem(String productName);
public List<String> getBuyItem();
}
Bean类:
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateful;
import com.foshanshop.ejb3.Cart;
@SuppressWarnings("serial")
@Stateful
@Remote(Cart.class)
public class CartBean implements Cart{
private List<String> buyitem = new ArrayList<String>();
public void AddBuyItem(String productName) {
buyitem.add(productName);
}
public List<String> getBuyItem() {
return buyitem;
}
}
(4)Stateful Session Bean的生命周期有3个状态,如有兴趣自己研究。
三、实体Bean(Entity Bean)
1、什么是实体Bean
创建实体Bean的目的为了实现持久化,EJB3.0遵循的持久化规范是Java Persistence API,即JPA。JPA定义了一种方法,可以将常规的Java对象映射到数据库。这些普通的Java对象被叫做Entity Bean。其实除了用JPA元数据将其映射到数据库外,Entity Bean与其他Java类没有任何区别。就是我们熟悉的POJO。
2、Entity Bean介绍
(1)Entity Bean必须用@ Entity注明。
(2)Entity Bean必须用@id唯一标示主键。
(3)如果实体Bean对象需要返回客户端,必须实现 Serializable接口。
(4)通过在Entity Bean中加注释可以表示表和表的关联,例如:一对多要用@OneToMany来表示。
(5)JPA还提供了好多注解来实现别的功能,希望大家仔细研究。
3、Entity Bean的实例
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.GenerationType;
@SuppressWarnings("serial")
@Entity
@Table(name = "Person")
public class Person implements Serializable{
private Integer personid;
private String name;
private boolean sex;
private Short age;
private Date birthday;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getPersonid() {
return personid;
}
public void setPersonid(Integer personid) {
this.personid = personid;
}
@Column(nullable=false,length=32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(nullable=false)
public boolean getSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Column(nullable=false)
public Short getAge() {
return age;
}
public void setAge(Short age) {
this.age = age;
}
@Temporal(value=TemporalType.DATE)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
4、 实体Bean的管理器EntityManaager
EntityManaager可以用来添加、删除、更新实体Bean,通过主键查找实体Bean。
EntityManaager管理实体Bean的实例如下:
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.foshanshop.ejb3.PersonDAO;
import com.foshanshop.ejb3.bean.Person;
@Stateless
@Remote (PersonDAO.class)
public class PersonDAOBean implements PersonDAO {
@PersistenceContext
protected EntityManager em;
public void insertPerson(Person person) {
em.persist(person);
}
public Person getPersonByID(int personid) {
return em.find(Person.class, personid);
}
public void mergePerson(Person person) {
em.merge(person);
}
@SuppressWarnings("unchecked")//关闭unchecked警告
public List<Person> getPersonList() {
Query query = em.createQuery("select o from Person o order by o.personid asc");
return (List<Person>) query.getResultList();
}
public void deletePerson(int personid) {
Person person = em.find(Person.class, personid);
if(person!=null) em.remove(person);
}
public void updateName(String newname, int personid) {
Person person = em.find(Person.class, personid);
if(person!=null) person.setName(newname);
}
}
5、 EntityManaager操作数据的方式
(1)利用EntityManaager提供的方法对实体Bean操作。
#用find()或getReference()方法得到实体。
例如:
@PersistenceContext
protected EntityManager em;
public Person getPersonByID(int personid) {
return em.find(Person.class, personid);
}
#用persist()方法保存实体
例如:
@PersistenceContext
protected EntityManager em;
public void insertPerson(Person person) {
em.persist(person);
}
#用merger()方法更新实体
例如:
@PersistenceContext
protected EntityManager em;
public void mergePerson(Person person) {
em.merge(person);
}
#用remoove()方法删除实体
例如:
@PersistenceContext
protected EntityManager em;
public void deletePerson(int personid) {
Person person = em.find(Person.class, personid);
if(person!=null) em.remove(person);
}
(2)操作实体Bean通过EJB QL
EJB QL是JPA提供的一种声明性的查询语言,它可以直接操作实体Bean。相当于我们熟悉的HSQL语句。
javax.persistence.Query是EJB3查询操作的接口。进行查询,首先要通过EntityManager 获得Query对象。
EntityManager为执行EJB QL语句提供了两种方法,createQuery(String ejbqlString)和createNamedQuery(String name)。
createQuery()方法得实例如下:
@PersistenceContext
private EntityManager em;
public List findByName(String first,String last){
Query query = entityManager.createQuery( "select o from Customer o where o.firstName = : first and o.lastName = : last" );
query.setParameter( " first ", first );
query.setParameter( " last ", " last " );
return query. getResultList();
}
createNamedQuery()如何使用请参考相关的文档。
(3)查询数据通过原生SQL
EntityManager为执行原生的SQL提供了三种方式,createNativeQuery(String sqlString),createNativeQuery(String sqlString,Class resultClass),createNativeQuery(String sqlString,String resultSetMapping)。
createNativeQuer(String sqlString,String resultSetMapping)方式实例如下:
@PersistenceContext
private EntityManager em;
Query query = entityManager. createNativeQuery ( "select p.phone_pk,p. phone_number, p.type from phone p ", Phone.class );
其他的两种方式请参考相关文档。