EJB3 (一)【开发Entity Bean】
首先开发服务端:在IDE中一定记得是NEW一个EJB工程
1.开发Bean class
package dev.com.titan.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="CABIN")
public class Cabin implements Serializable{
?
?private int id;
?private String name;
?private int deckLevel;
?private int shipId;
?private int bedCount;
?
?@Id
?@Column(name="ID")
?public int getId() {
??return id;
?}
?public void setId(int id) {
??this.id = id;
?}
?
?@Column(name="NAME")
?public String getName() {
??return name;
?}
?public void setName(String name) {
??this.name = name;
?}
?
?@Column(name="DECK_LEVEL")
?public int getDeckLevel() {
??return deckLevel;
?}
?public void setDeckLevel(int deckLevel) {
??this.deckLevel = deckLevel;
?}
?
?@Column(name="BED_COUNT")
?public int getBedCount() {
??return bedCount;
?}
?public void setBedCount(int bedCount) {
??this.bedCount = bedCount;
?}
?@Column(name="SHIP_ID")
?public int getShipId() {
??return shipId;
?}
?public void setShipId(int shipId) {
??this.shipId = shipId;
?}
}
注释:
@Entity注解告知persistence provider?这是一个映射到数据库的实体类,并且可以受管于EntityManager服务。
@Table告知EJB容器,该BEAN类被映射到哪一张数据库表。
BEAN类一定要实现Serializable接口。
@Column表示对应映射到数据库中的字段名字,如果没有该标志,那么默认按照属性的名字来命名。
@Id 表示该属性为实体的主键。
?
2.定义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="titan" transaction-type="JTA">
??<jta-data-source>java:/TitanDB</jta-data-source>
?</persistence-unit>
</persistence>
?
黑色字体部分表示告诉EJB容器要用到哪个数据源。
?
3.配置JBoss的数据库连接池
在/server/default/deploy目录中建立一个mysql-ds.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
??? <local-tx-datasource>
??????? <jndi-name>TitanDB</jndi-name>
??????? <connection-url>jdbc:mysql://localhost:3306/ejb</connection-url>
??????? <driver-class>com.mysql.jdbc.Driver</driver-class>
??????? <user-name>root</user-name>
??????? <password>root</password>
??????? <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>
?
黑体字部分的名字必须和你的persistence.xml文件中的黑体字部分一致。
?
mysql-ds.xml文件用于配置mysql的数据源。实际上,该文件可以在/docs/examples/jca目录中找到,读者只需要将数据库名、用户名和密码以及jndi名改成自己的就可以了。最后将修改后的mysql-ds.xml文件复制到deploy目录中(必须叫这个文件名)。
连接mysql数据库需要一个jdbc驱动(jar文件),将该文件复制到/server/default/lib目录中。
?
4.开发接口和实现类
接口:
package dev.com.titan.travelagent;
import javax.ejb.Remote;
import dev.com.titan.domain.Cabin;
@Remote
public interface TravelAgentRemote {
?
?public void createCabin(Cabin cabin);
?
?public Cabin findCabin(int id);
?
}
实现类:
package dev.com.titan.travelagent;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import dev.com.titan.domain.Cabin;
@Stateless
public class TravelAgentBean implements TravelAgentRemote {
?
?@PersistenceContext(unitName="titan") private EntityManager manager;
?public void createCabin(Cabin cabin) {
??manager.persist(cabin);
?}
?public Cabin findCabin(int id) {
??// TODO Auto-generated method stub
??return manager.find(Cabin.class, id);
?}
}
红色部分表示告诉容器去寻找unitName=titan的数据源,而该数据源对应的配置在persistence.xml中,然后根据该配置去EJB容器中找到java:/TitanDB的数据源。
@PersistenceContext
注解来获得ENTITYMANAGER服务的访问,从此来创建和查找CABIN实体,他告知EJB容器,必须用以个EntityManager实例来设置manager数据成员。
EJB容器发现数据成员类型为EntityManager,便知道将数据成员设置为一个指向 EntityManager服务的引用,此服务指向我们在persistence.xml文件里定义的unit.我们可以利用EntityManager 的persist()和find()方法来对实体类进行操作。
然后部署到JBOSS中,可以通过IDE的部署功能直接部署到JBOSS中。
?
创建数据库表:
CREATE TABLE `cabin` (
? `ID` int(11) NOT NULL auto_increment,
? `SHIP_ID` int(11) default NULL,
? `BED_COUNT` int(11) default NULL,
? `NAME` varchar(255) default NULL,
? `DECK_LEVEL` int(11) default NULL,
? PRIMARY KEY? (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
?
开发客户端:
首先将服务端打成一个JAR包,考到客户端中。
然后导入开发JBOSS客户端所需要的jbossall-client.jar
首先在你的SRC目录下新建一个jndi.properties:
#jboss
java.naming.provider.url = 192.168.61.135:1099
java.naming.factory.initial = org.jnp.interfaces.NamingContextFactory
?
客户端代码:
package com;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import dev.com.titan.domain.Cabin;
import dev.com.titan.travelagent.TravelAgentRemote;
public class Client {
?private static InitialContext context = null;
?static
?{
??try {
???buildInitialContext();
??} catch (Exception e) {
???e.printStackTrace();
??}
?}
?public static void buildInitialContext()
?{
??try {
???
???
??? context = new InitialContext();
???
???
??} catch (Exception e) {
???e.printStackTrace();
??}
?}
?
?public static InitialContext getInitialContext()
?{
??if(context==null)
??{
???buildInitialContext();
??}
??return context;
?}
?
?public static void main(String[] args) {
??try {
???
???InitialContext context = getInitialContext();
?//如果采用这种方式来得到InitialContext那么系统会自动去读SRC目录下的jndi.properties文件
//下面的JNDI可以通过http://192.168.61.135:8080/jmx-console/
//然后找到Global JNDI Namespace,下找到你所发布的EJB服务的JNDI名字
?
???Object ref = context.lookup("TravelAgentBean/remote");
???
???TravelAgentRemote dao = (TravelAgentRemote)PortableRemoteObject.narrow(ref,TravelAgentRemote.class);
???//客户端通过PortableRemoteObject.narrow(ref,TravelAgentRemote.class);方法将Object ref窄化成一个?? TravelAgentRemote应用
???Cabin c = new Cabin();
???c.setName("tuping");
???c.setDeckLevel(1);
???c.setShipId(1);
???c.setBedCount(3);
???dao.createCabin(c);
???Cabin c2 = dao.findCabin(1);
???System.out.println(c2.getName());?
??} catch (Exception e) {
???e.printStackTrace();
??}
?}
?
}
运行得到结果:tuping
?
调用成功!