在上一篇文章中,我们学习了EJB的会话bean,这篇文章我们来说一下EJB的实体bean,说到实体bean,就不得不说JPA了,JPA是在EJB3.0的时候提出来的,但是他不局限于EJB3.0,而是适用于整个J2EE,他是一种规范。
JPA定义了一系列的注解,@Entity,@Table,@Id @Colume等,当一个POJO类加上这些注解后,他就形成了实体bean。
我们看一下实体bean在程序中是怎么应用的呢。如果我们需要使用EJB调用实体Bean,那么我们就需要配置数据源,不知道大家有没有疑问,为什么以前做普通javaweb项目的时候,我们直接在程序中的配置文件中指定数据源就好了,为什么要去服务器上指定呢!配置JBoss数据源,为什么要在JBoss中配置数据源?这其实是面向对象思想的一种体现:通过容器管理对数据库的访问。
最开始我们通过JDBC访问数据库,什么Connection、Command都由我们自己创建。但每次打开关闭数据库很消耗资源,于是出现了数据库连接池,提前建立好对数据库的连接,用的时候去连接池取,用完了送回到连接池。这样虽然解决了资源消耗问题,但连接过程仍需要手动干预。后来在用Spring整合Hibernate时,出现了用Spring的IOC容器管理Hibernate对数据库的访问的思想,这个过程好比用Tomcat管理Servlet的生命周期。我们只需用Servlet完成消息的提交,不必要关心它什么时候创建、什么销毁,JBoss管理数据源也是相同的思想。那么我们看见如何配置JBoss数据源!
我们在jboss-6.1.0.Final\docs\examples\jca下找到你要使用数据库对应的数据源配置,我们使用的是mysql数据库,所以使用的是mysql-ds.xml配置文件。我们拷贝这个文件到部署项目的文件夹jboss-6.1.0.Final\server\default\deploy下边。内容如下!
<?xml version="1.0"encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<!--JNDI的名字,我们通过该名字可以查找到改数据源-->
<jndi-name>MySqlDS</jndi-name>
<!--mySQL的连接字符串-->
<connection-url>jdbc:mysql://localhost:3306/ejb3</connection-url>
<!--mySQL的连接驱动-->
<driver-class>com.mysql.jdbc.Driver</driver-class>
<!--mySQL的连接用户名-->
<user-name>root</user-name>
<!--mySQL的连接密码-->
<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>
这样我们的数据源就配置好了, 如果你在程序中需要多个数据源的话,那么我们可以配置多个<local-tx-datasource>…..</local-tx-datasource>,但是如果是不同的数据库,例如Oracle数据库,我们可以在复制一份oracle-ds.xml文件到jboss-6.1.0.Final\server\default\deploy,或者将里边的内容的<local-tx-datasource>…..</local-tx-datasource>节点的所有内容放入到mysql-ds.xm文件中。
配置完数据源后我们就可以写程序了。我们建立一个EJB3的项目,然后在项目中META-INF文件夹下建立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">
<!-- 持久化单元的名字,可以随便起 transaction-type表示使用事务的类型,有JTA和RESOURCE_LOCALJTA和
RESOURCE_LOCAL的区别就在于一个是声明性事务管理,由容器来打理你添加了 @TransactionAttribut(xxxx)
注释的EJB method过程,而另一个需要手动从EM中得到一个事务句柄并使用begin(),commit()之类编程性事务管理方式 -->
<persistence-unit name="user" transaction-type="JTA">
<!-- 数据源,就是上文中mysql-ds.xml中配置的名称,因为该数据源放在jboss下,所以加了前缀java:/
如果此处不加的话, 在后边依赖查找的时候要加上! -->
<jta-data-source>java:/MySqlDS</jta-data-source>
<properties>
<!-- 配置数据源的属性,应该jboss的底层是采用Hibernate实现的,所以采用我们
熟悉的hibernate的配置方式。如果不了解的话, 可以自己去查一下资料 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
配置完持久化信息后,我们建立我们的实体bean。我们的@Entity和@Table配置在类的上边,表示这个是一个实体类。至于@id和@column既可以配置属性上,也可以配置在get set 方法上,效果都是一样。再有只要标示了@id,@Column是可以省略的!
@Entity
@Table(name="t_user")
public class User implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
privateInteger id;
//设置属性userCode对应的字段为user_code,长度为32,非空
@Column(name= "username", nullable = false, length=32)
privateString userName;
@Column
privateString password;
@Column
privateString att;
publicInteger getId() {
returnid;
}
publicvoid setId(Integer id) {
this.id= id;
}
publicString getUserName() {
returnuserName;
}
publicvoid setUserName(String userName) {
this.userName= userName;
}
publicString getPassword() {
returnpassword;
}
publicvoid setPassword(String password) {
this.password= password;
}
publicString getAtt() {
returnatt;
}
publicvoid setAtt(String att) {
this.att= att;
}
}
我们在建立SessionBean,代码如下所示,并将程序发布到Jboss服务器中。
public interface UserManager {
public void addUser(User user);
}
@Remote
@Stateless
public class UserManagerBean implements UserManager {
//持久化上下文,名字为persistence.xml中配置的名字。 此处使用依赖注入,他的事务由容器管理
//实体管理,类似于Hibernate中的session
@PersistenceContext(name="user")
private EntityManager em;
@Override
public void addUser(User user) {
//循环插入十条数据!
for (int i = 0; i < 10; i++) {
//持久化保存到数据库中
em.persist(user);
//验证事物是否可行!能否进行回滚。
/*if (i==5) {
throw new RuntimeException();
}*/
}
}
}
然后建立客户端,代码如下所示,
package com.tgb.client;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.tgb.domain.User;
import com.tgb.manager.UserManager;
public class EntityBeanClient {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
try {
//建立上下文
InitialContext ctx = new InitialContext(props);
UserManager userManager =(UserManager) ctx.lookup("UserManagerBean/remote");
User user = new User();
user.setUserName("zhj");
user.setPassword("0302");
user.setAtt("");
userManager.addUser(user);
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我们可以看到数据已经插入到数据库中!EJB的实体Bean是借助了JPA来实现的!所以要想用法ejb的实体bean ,就要学习JPA!