在上一篇文章中,我們學習了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!