Eclipse + Jboss AS 7.1 建立 EJB3.0之JPA工程(下)

 

8. 建立 Session Bean 和 Bean Interface


  • 右擊ejbModule -> New -> Session Bean (EJB 3.x)html

  • 輸入包名com.ibytecode.businesslogicjava

  • 輸入類名ProjectBean
  • 選擇狀態爲Stateless
  • 選擇Remote Business Interface並輸入com.ibytecode.business.IProject
  • business interface將會在另外一個包(com.ibytecode.business)中生成
  • 點擊Finishmysql

9. 編寫 Bean 和 Interface


  • 打開「Bean Interface」而且複製下面的代碼
  • Interface 能夠是 @Remote或者@Local。這裏,咱們選擇@Remote (Remote 與 Local 的區別
     1 package com.ibytecode.business;
     2 import java.util.List;
     3 import javax.ejb.Remote;
     4 
     5 import com.ibytecode.entities.Project;
     6 
     7 @Remote
     8 public interface IProject {
     9     void saveProject(Project project);
    10     Project findProject(Project project);
    11     List<Project> retrieveAllProjects();
    12 }
    View Code
  • 打開 Bean 並複製下面的代碼
  • Bean 類型能夠是 @Stateful 或 @Statess,這裏使用@Statess (Stateful 與 Statess 的區別
     1 package com.ibytecode.businesslogic;
     2 
     3 import java.util.List;
     4 import javax.ejb.Stateless;
     5 import javax.persistence.EntityManager;
     6 import javax.persistence.PersistenceContext;
     7 import javax.persistence.Query;
     8 
     9 import com.ibytecode.business.IProject;
    10 import com.ibytecode.entities.Project;
    11 
    12 @Stateless
    13 public class ProjectBean implements IProject {
    14 
    15     @PersistenceContext(unitName = "JPADB")
    16     private EntityManager entityManager;
    17     
    18     public ProjectBean() {   }
    19 
    20     @Override
    21     public void saveProject(Project project) {
    22         entityManager.persist(project);
    23     }
    24 
    25     @Override
    26     public Project findProject(Project project) {
    27         Project p = entityManager.find(Project.class, project.getPnumber());
    28         return p;
    29     }
    30 
    31     @Override
    32     public List<Project> retrieveAllProjects() {
    33         
    34         String q = "SELECT p from " + Project.class.getName() + " p";
    35         Query query = entityManager.createQuery(q);
    36         List<Project> projects = query.getResultList();
    37         return projects;
    38     }
    39 }
    View Code  
  • 下一步,咱們將配置數據源

10. Persistence.xml


server是如何知道,EntityManager API 應該在哪一個數據庫 save / update / query 實體對象?(由於在Jboss 中配置的數據源可能有多個,咱們這裏就要指定standalone.xml 中配置的某個 'datasource jndi-name'
「persistence.xml」文件能夠完整且靈活的配置 EntityManager
「persistence.xml」是 JPA 中一個標準的配置文件,應該被放置在META-INF目錄下。在該文件中應該定義一個persistence unit節點並設置一個惟一的name屬性,該name屬性將被EntityManager使用。
右擊META-INF -> New -> Other -> XML -> XML file,輸入文件名persistence.xml,並粘貼以下內容:sql

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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_2_0.xsd">
    <persistence-unit name="JPADB">
    <jta-data-source>java:/MySQLDS</jta-data-source>
        <properties>
            <property name="showSql" value="true"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        </properties>
    </persistence-unit>
</persistence>

在JBoss AS中,默認的JPA provider是Hibernate,jta-data-source指向此持久元映射到的數據庫的JNDI名稱。java:/MySQLDS指向MySQL DB數據源。咱們將在下一步設置這個數據源。數據庫

11. 在JBoss AS 7中配置MySQL數據源


1.1. 下載 MySQL connector


點此連接下載,解壓獲得MySQL Connector J JAR.api

11.2. 向AS 7中添加Module


AS 7 經過module體系來實現類的獨立加載,咱們須要建立一個新的包含 「MySQL Connector J JAR」文件的模塊.
在你的 AS 7 的根目錄下,按照modules/com/mysql/main的層次創建文件夾,而後複製「MySQL Connector J JAR」文件到main文件中。
而後在XML文件中定義此模塊,新建module.xml並粘貼下面的代碼:服務器

<?xml version="1.0" encoding="UTF-8"?>

<module xmlns="urn:jboss:module:1.0" name="com.mysql">
  <resources>
    <resource-root path="mysql-connector-java-5.1.18-bin.jar"/>
  </resources>
  <dependencies>
    <module name="javax.api"/>
  </dependencies>
</module>

注意:
這個新的模塊目錄包含了如下內容:session

- module.xml
- mysql-connector-java-5.1.18-bin.jar

JAR文件的名稱根據實際進行修改app

JAR的版本高於(包括)5.5.30會在後面出現問題less

11.3. 建立驅動引用


如今,咱們須要在main應運服務器的配置文件(standalone.xml,路徑:JBossAS_Home/standalone/configuration)中創建對module的引用。
找到<drivers>元素,並添加新的驅動:

<drivers>
    <driver name="mysqlDriver" module="com.mysql">
        <xa-datasource-class>
            com.mysql.jdbc.Driver
        </xa-datasource-class>
    </driver>
</drivers>

11.4. 向驅動添加數據源


打開應運服務器配置文件「standalone.xml」,找到<datasources>元素並添加新的數據源:

<datasource jndi-name="java:/MySQLDS" pool-name="MySQLDS" enabled="true" use-java-coMD2ntext="true">
    <connection-url>
        jdbc:mysql://localhost:3306/YOUR-DATABASE-NAME
    </connection-url>
    <driver>mysqlDriver</driver>
    <security>
        <user-name>YOUR-MYSQL-USERNAME</user-name>
        <password>YOUR-MYSQL-PASSWORD</password>
    </security>
</datasource>

注意:

再上面的代碼中,使用你的 database 名稱,MySQL的 username 和 password.

<datasources>元素中,jndi-name=」java:/MySQLDS」應該和「persistence.xml」中的java:/MySQLDS匹配.

<driver>mysqlDriver</driver>應該和「persistence.xml」中的<drivers><driver name=」mysqlDriver」 …>…</driver></drivers>匹配

如今,咱們嘗試啓動 JBOSS ,若是出現如下異常:

 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 29) JBAS014612: Operation ("add") failed - address: ([
    ("subsystem" => "datasources"),
    ("jdbc-driver" => "mysqlDriver")

  ..........

解決方法:

1. 5.1.30 版本的 mysql-connector-java-x.x.xx-bin.jar

2. 在 standalone.xml 的 <datasources> 下的 <drivers> 下添加:

  <driver-class>com.mysql.jdbc.Driver</driver-class>

12. 部署 EJB JPA project


在server上部署「FirstJPAProject」工程有兩種方法:

1. 右鍵 EJB project -> "Run As" -> "Run On Server". 選擇 "JBoss 7.1 Runtime Server", 點擊 "Finish".
2. 在 "Servers" 視圖中右鍵 "JBoss 7.1 Runtime Server" -> "Add and Remove…" ->選擇EJB JAR文件 -> "Add" -> "Finish".

 

你也能夠從Jboss的管理後臺部署EJB組件:

  1. 右鍵 EJB project -> "Export" . 選擇 "EJB Jar file", 輸入保存路徑,點擊 "Finish".

  2. 進入 Jboss 後臺: "1ocalhost:8080",選擇"Administration Console"

  3."Manage Deployments" -->"Add Content",選擇"jar"文件,完成,並將狀態設置爲"Enable"。

 

13. 啓動/重啓 服務器


右鍵 「JBoss 7.1 Runtime Server」 點擊 「start」,若是JNDI 映射和和部署都是正確的,你將在控制檯看到下面一句話:

Deployed "FirstJPAProject.jar"

14. 建立 Client


  • 接下來的這一步咱們將寫一個遠程的 Java client application (with main()) 訪問和調用部署在服務器上的 Bean
  • Client 使用 JNDI 技術查找 Bean 的代理服務器並調用其方法。

14.1. 建立 JNDI InitialContext


經過 InitialContext 得到 Context

  • 全部的命名服務操做都是在「javax.naming.Context」的接口的實現者上進行的。所以,和命名服務器開始交互的起點是:經過提供給服務器啓動服務所需的明確的屬性來得到上下文。在咱們的示例中,就是Jboss應用服務器。(原文是「All naming service operations are performed on some implementation of the javax.naming.Context interface. Therefore, the starting point of interacting with the naming service is to obtain a Context by providing the properties specific to the server implementation being used. In our case it is, JBoss Application Server.)(點此瞭解 javax.Naming 軟件包
  • 爲了產生一個 javax.naming.InitialContext,咱們須要用 properties 從環境中初始化它。JNDI 經過下面兩個來源來校驗property的值
    • 使用 InitialContext 的帶參構造方法,取決於所提供的環境
    • 在 classpath 中的 jndi.properties 源文件

注意:這裏咱們將使用第一種方法

對於 JBoss AS 7,咱們須要設置「Context.URL_PKG_PREFIXES」屬性爲「org.jboss.ejb.client.naming」 來獲得 InitialContext 。

下面的工具類能夠產生 JBoss AS 上的 InitialContext,而且能夠被全部的 application 重用。不然,在全部的 client 中都要複製代碼。

  • 右鍵 ejbModule -> New -> Class
  • 輸入包名 com.ibytecode.clientutility
  • 輸入類名 JNDILookupClass
  • 點擊 Finish

複製下面的代碼:

 1 package com.ibytecode.clientutility;
 2 
 3 import java.util.Properties;
 4 import javax.naming.Context;
 5 import javax.naming.InitialContext;
 6 import javax.naming.NamingException;
 7 
 8 public class JNDILookupClass {
 9 
10     private static Context initialContext;
11 
12     private static final String PKG_INTERFACES = "org.jboss.ejb.client.naming";
13 
14     public static Context getInitialContext() throws NamingException {
15         if (initialContext == null) {
16             Properties properties = new Properties();
17             properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACES);
18 
19             initialContext = new InitialContext(properties);
20         }
21         return initialContext;
22     }
23 }
View Code

 

 

14.2. 建立 client class


  • 右鍵 ejbModule -> New -> Class
  • 輸入包名 com.ibytecode.client
  • 輸入類名 EJBApplicationClient
  • 勾選 main() 方法選項
  • 點擊 Finish

複製下面的代碼:

 1 package com.ibytecode.client;
 2 
 3 import java.util.List;
 4 
 5 import javax.naming.Context;
 6 import javax.naming.NamingException;
 7 
 8 import com.ibytecode.business.IProject;
 9 import com.ibytecode.businesslogic.ProjectBean;
10 import com.ibytecode.clientutility.JNDILookupClass;
11 import com.ibytecode.entities.Project;
12 
13 public class EJBApplicationClient {
14     
15     public static void main(String[] args) {
16         IProject bean = doLookup();
17         
18         Project p1 = new Project();
19         p1.setPname("Banking App");
20         p1.setPlocation("Town City");
21         p1.setDeptNo(1);
22         
23         Project p2 = new Project();
24         p2.setPname("Office Automation");
25         p2.setPlocation("Downtown");
26         p2.setDeptNo(2);
27 
28         // 4. Call business logic
29         //Saving new Projects
30         bean.saveProject(p1);
31         bean.saveProject(p2);
32         
33         //Find a Project
34         p1.setPnumber(1);
35         Project p3 = bean.findProject(p1);
36         System.out.println(p3);
37         
38         //Retrieve all projects
39        System.out.println("List of Projects:");
40         List<Project> projects = bean.retrieveAllProjects();
41         for(Project project : projects)
42             System.out.println(project);
43         
44         
45     }
46 
47     private static IProject doLookup() {
48         Context context = null;
49         IProject bean = null;
50         try {
51             // 1. Obtaining Context
52             context = JNDILookupClass.getInitialContext();
53             // 2. Generate JNDI Lookup name
54             String lookupName = getLookupName();
55             // 3. Lookup and cast
56             bean = (IProject) context.lookup(lookupName);
57 
58         } catch (NamingException e) {
59             e.printStackTrace();
60         }
61         return bean;
62     }
63 
64     private static String getLookupName() {
65         /*The app name is the EAR name of the deployed EJB without .ear 
66         suffix. Since we haven't deployed the application as a .ear, the app 
67         name for us will be an empty string */
68         String appName = "";
69 
70         /* The module name is the JAR name of the deployed EJB without the 
71         .jar suffix.*/
72         String moduleName = "FirstJPAProject";
73 
74         /* AS7 allows each deployment to have an (optional) distinct name. 
75         This can be an empty string if distinct name is not specified.*/
76         String distinctName = "";
77 
78         // The EJB bean implementation class name
79         String beanName = ProjectBean.class.getSimpleName();
80 
81         // Fully qualified remote interface name
82         final String interfaceName = IProject.class.getName();
83 
84         // Create a look up string name
85         String name = "ejb:" + appName + "/" + moduleName + "/" + 
86                 distinctName     + "/" + beanName + "!" + interfaceName;
87         return name;
88     }
89 }
View Code

 

 

14.3. 配置 EJB 客戶端上下文屬性


一個 EJB 客戶端上下文包含了執行遠程 EJB 調用的上下文環境信息。他是一個 JBoss AS 特有的 API。一個 EJB 客戶端上下文能夠和多個 EJB 接收者關聯在一塊兒,每一個 EJB 接收者能夠處理多個 EJB 調用
每一個 EJB 接收者都知道它能夠操做的 EJB 集合,每一個 EJB 接收者都知道使用哪一個 server 目標來處理對 Bean 的調用。server 的IP地址和遠程服務端口應該在放置在客戶端 classpath 的 properties file 中明確給出。而後這個 properties file (EJB client context) 會被 JNDI 的實現類內部使用,去執行在 Bean 代理服務器上的調用。

在應用程序的 classpath 中建立一個「jboss-ejb-client.properties」 文件,咱們能夠把它放在應用程序的 ejbModule 文件夾下,該文件中包含如下屬性:

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
    remote.connections=default
    remote.connection.default.host=localhost
    remote.connection.default.port = 4447
    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
 remote.connection.default.username =YOUR_JBOSS_COSOLE_USERNAME
 remote.connection.default.password =YOUR_JBOSS_COSOLE_PASSWORDYOUR_JBOSS_COSOLE_PASSWORD

14.4. 給 client 添加所需的 JAR 文件來運行客戶端程序


  • Run菜單或Run圖標中打開`Run Configurations…

  • 在左面板中Java Application的下面選擇客戶端應用程序(EJBApplicationClient),而後打開classpath標籤。(若是你沒有看見你的客戶端應用程序,先運行一遍它。)選擇User Entries而後點擊「Add External JARs」。

  • 添加下面的 JAR 文件(jboss 7不須要)

JAR 名稱 位置
jboss-transaction-api_1.1_spec-1.0.0.Final.jar AS7_HOME/modules/javax/transaction/api/main/
jboss-ejb-api_3.1_spec-1.0.1.Final.jar AS7_HOME/modules/javax/ejb/api/main/
jboss-ejb-client-1.0.0.Beta10.jar AS7_HOME/modules/org/jboss/ejb-client/main/
jboss-marshalling-1.3.0.GA.jar AS7_HOME/modules/org/jboss/marshalling/main/
xnio-api-3.0.0.CR5.jar AS7_HOME/modules/org/jboss/xnio/main/
jboss-remoting-3.2.0.CR6.jar AS7_HOME/modules/org/jboss/remoting3/main/
jboss-logging-3.1.0.Beta3.jar AS7_HOME/modules/org/jboss/logging/main/
xnio-nio-3.0.0.CR5.jar AS7_HOME/modules/org/jboss/xnio/nio/main/
jboss-sasl-1.0.0.Beta9.jar AS7_HOME/modules/org/jboss/sasl/main/
jboss-marshalling-river-1.3.0.GA.jar AS7_HOME/modules/org/jboss/marshalling/river/main/

你也能夠經過」Build path」(右鍵 EJB Project->Properties,在左邊選擇Java Build Path,而後中間的標籤欄選擇「Libraries」,最後在右邊選擇「 Add External JARs」)

若是你使用的是 JBoss Application Server (AS) 7.1.0 Final 版本,只須要添加一個客戶端 JAR 文件(jboss-client-7.1.0.Final.jar)便可,它位於「AS7_HOME/bin/client」目錄下

此示例工程的目錄結構以下圖所示:

14.5. 運行客戶端程序



相關文章
相關標籤/搜索