幻境
          We are extremely fortunate not to know precisely the kind of world we live in
          posts - 22,comments - 39,trackbacks - 0

           

          關于這個話題,javaeye其實有一篇文章專門介紹了(http://www.javaeye.com/viewtopic.php?t=245),但是可能不是很詳細,最近也有一些人我這方面的問題,所以在這里重新介紹一下。不過我還是推薦你在看本文之前首先看一下上面提到的那篇文章。


          首先說明一下我們這里使用的程序,為了更容易理解,我們使用hibernate文檔(英文版: http://www.hibernate.org/hib_docs/v3/reference/en/html/ 中文版:http://www.hibernate.org/hib_docs/v3/reference/zh-cn/html/)中剛開始介紹與Tomcat進行整合時候的那個程序,不過把包名改了一下。


          為了更加清晰,我仍然把代碼貼在下面:

           1 package example;
           2 
           3 public class Cat {
           4 
           5     private String id;
           6     private String name;
           7     private char sex;
           8     private float weight;
           9 
          10     public Cat() {
          11     }
          12 
          13     public String getId() {
          14         return id;
          15     }
          16 
          17     private void setId(String id) {
          18         this.id = id;
          19     }
          20 
          21     public String getName() {
          22         return name;
          23     }
          24 
          25     public void setName(String name) {
          26         this.name = name;
          27     }
          28 
          29     public char getSex() {
          30         return sex;
          31     }
          32 
          33     public void setSex(char sex) {
          34         this.sex = sex;
          35     }
          36 
          37     public float getWeight() {
          38         return weight;
          39     }
          40 
          41     public void setWeight(float weight) {
          42         this.weight = weight;
          43     }
          44 
          45 }
          46 

          還有就是Cat.hbm.xml:

          <?xml version="1.0"?>
          <!DOCTYPE hibernate-mapping
              PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
              "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
          >

          <hibernate-mapping>

              
          <class name="example.Cat" table="CAT">

                  
          <!-- A 32 hex character is our surrogate key. It's automatically
                      generated by Hibernate with the UUID pattern. 
          -->
                  
          <id name="id" type="string" unsaved-value="null" >
                      
          <column name="CAT_ID" sql-type="char(32)" not-null="true"/>
                      
          <generator class="uuid.hex"/>
                  
          </id>

                  
          <!-- A cat has to have a name, but it shouldn' be too long. -->
                  
          <property name="name">
                      
          <column name="NAME" length="16" not-null="true"/>
                  
          </property>

                  
          <property name="sex"/>

                  
          <property name="weight"/>

              
          </class>

          </hibernate-mapping>



          關于數據庫表的建立,在這里就不再贅述了。

          下面我們分成幾步來介紹,為了介紹方便,我們假設你現在有一個weblogic配置在D:\bea\user_projects\domains\mydomain下。

          1.      設置classpath,

          A.      hibernate本身需要一些jar(到底需要哪些jar可以參照hibernate文檔),你需要在classpath里面引入這些jar。另外你還會寫這個方法也仍然是修改startWeblogic.cmd。舉例來講,假如你把這些jar拷貝到了D:\bea\user_projects\domains\mydomain\lib,那么可以在startWeblogic.cmd中添加這樣兩句話:

          set HIBERNATE_LIB=D:\bea\user_projects\domains\mydomain\lib

          set ClASSPATH=%HIBERNATE_LIB%\antlr-2.7.5H3.jar;%HIBERNATE_LIB%\asm-attrs.jar;%HIBERNATE_LIB%\cglib-2.1.jar;%HIBERNATE_LIB%\commons-collections-2.1.1.jar;%HIBERNATE_LIB%\commons-logging-1.0.4.jar;%HIBERNATE_LIB%\concurrent-1.3.2.jar;%HIBERNATE_LIB%\dom4j-1.6.jar;%HIBERNATE_LIB%\jaas.jar;%HIBERNATE_LIB%\jacc-1_0-fr.jar;%HIBERNATE_LIB%\jaxen-1.1-beta-4.jar;%HIBERNATE_LIB%\log4j-1.2.9.jar;%HIBERNATE_LIB%\xml-apis.jar;%HIBERNATE_LIB%\asm.jar;%HIBERNATE_LIB%\hsqldb.jar;%HIBERNATE_LIB%\hibernate3.jar;lib\classes;%HIBERNATE_LIB%\ehcache-1.1.jar;%CLASSPATH%

          B.      設置你編譯后的程序目錄,我們這里假設假如你編譯后的代碼在D:\bea\user_projects\domains\mydomain\classes下,那么仍然是參照上面的方法,在startWeblogic.cmd中添加這樣兩句話:

          set MY_CLASSES=D:\bea\user_projects\domains\mydomain\classes

          set ClASSPATH=%MY_CLASSES%;%CLASSPATH%

          這樣classpath導入的工作就完成了。

          2.      打開Weblogic Administration Console   ,然后配置好你的連接池和datasource,這里我使用datasource的JNDI Name用了mydatasource

          3.      書寫hibernate配置文件,大家都知道hibernate配置文件可以寫成xml也可以寫成properties的形式,這里我使用的是xml的方式。

          <?xml version='1.0' encoding='utf-8'?>
          <!DOCTYPE hibernate-configuration PUBLIC
                  
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                  
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

          <hibernate-configuration>
              
          <session-factory>      
                  
          <!-- SQL dialect -->
                  
          <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
                  
          <!-- Echo all executed SQL to stdout -->
                  
          <property name="show_sql">true</property>         
                  
          <property name="connection.datasource">mydatasource</property>
                   
          <property name="session_factory_name">hibernate.quickstart</property>
                  
          <property name="transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup
          </property>
                   
          <mapping resource="example/Cat.hbm.xml" />
              
          </session-factory>
          </hibernate-configuration>

          配置時需要注意的就是session_factory_name中使用了一個點來代替/,也就是hibernate.quickstart,實際程序lookup時候仍然使用hibernate/quickstart

              至于transaction.manager_lookup_class如果你不打算用JTA可以不配。

          4.      WebLogic的啟動類,WebLogic的啟動類需要實現weblogic.common.T3StartupDef接口,編程時候你要引入這個接口,可以通過引入weblogic.jar實現。假如你weblogic安裝在D:\bea下面,你可以在相應的weblogic81\server\lib下找到這個jar。其實只是獲得SessionFactory,hibernate會自動綁定到相應的JNDI name上的。

          package example;

          import java.util.Hashtable;

          import org.apache.log4j.Logger;
          import org.hibernate.SessionFactory;
          import org.hibernate.cfg.Configuration;

          import weblogic.common.T3ServicesDef;
          import weblogic.common.T3StartupDef;

          public class StartHibernateConfig
              implements T3StartupDef
          {

              
          private Logger log = Logger.getLogger(StartHibernateConfig.class);
              
          public String startup(String arg0, Hashtable arg1)
                  throws Exception
              {
                  Configuration config 
          = new Configuration().configure();
                  SessionFactory sf 
          = config.buildSessionFactory();
                   
                  log.info(
          "Initial hibernate SessionFactory successfully,sf:" + sf);

                  
          return "Initial hibernate SessionFactory successfully";
              }

              
          public void setServices(T3ServicesDef t3servicesdef)
              {
              }

          }

          5.      仍然是在Weblogic Administration Console中,從左邊的applet樹中找到StartUp & Shutdown,然后選擇Configure a new Startup Class...,按照提示一步一步配置就可以了。然后重啟一下Weblogic

          6.      到這里為止,所有的配置工作就完成了,你可以在程序里面使用Hibernate了。


           

          下面是一些關于編程的簡單介紹。


          如果不使用JTA,比如在一個servlet中可以這樣寫

          Context ctx=new InitialContext();
          SessionFactory sessions
          =(SessionFactory)ctx.lookup("hibernate/quickstart");
          Session sess 
          = factory.openSession();
          Transaction tx 
          = null;
          try {
              tx 
          = sess.beginTransaction();

              
          // do some work
              

              tx.commit();
          }
          catch (RuntimeException e) {
              
          if (tx != null) tx.rollback();
              
          throw e; // or display error message
          }
          finally {
              sess.close();
          }

          使用BMT的話其實寫法和上面是一樣的。

          如果使用CMT,那么你的程序里面就不需要自己管理事務,容器會替你完成的。

          另外在獲得Session的時候可以使用SessionFactory的getCurrentSession()方法。

           

          下面我們通過一個完整的SLSB的例子來看一下。這里仍然使用了我們在前面提到過的Cat。

          首先是需要的java程序:


          Remote Interface:

          package example;

          import java.rmi.RemoteException;
          import javax.ejb.EJBObject;
          import javax.naming.NamingException;

          public interface Sample extends EJBObject {
              
              
          public String countCats() throws RemoteException,NamingException;
              
          }

          Home Interface:

          package example;

          import java.rmi.RemoteException;
          import javax.ejb.CreateException;
          import javax.ejb.EJBHome;

          public interface SampleHome extends EJBHome {
              
              
          public Sample create() throws RemoteException,CreateException;
              
          }

          Bean Class:

          package example;

          import java.rmi.RemoteException;
          import java.util.List;
          import javax.ejb.EJBException;
          import javax.ejb.SessionBean;
          import javax.ejb.SessionContext;
          import javax.naming.Context;
          import javax.naming.InitialContext;
          import javax.naming.NamingException;

          import org.apache.log4j.Logger;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;

          public class SampleBean implements SessionBean {

              
          private Logger log = Logger.getLogger(SampleBean.class);

              
          private SessionContext sctx;

              
          public void setSessionContext(SessionContext ctx) throws EJBException,
                      RemoteException {

              }

              
          public void ejbCreate() throws EJBException, RemoteException {
              }

              
          public void ejbRemove() throws EJBException, RemoteException {
              }

              
          public void ejbActivate() throws EJBException, RemoteException {
              }

              
          public void ejbPassivate() throws EJBException, RemoteException {
              }

              
          public String countCats() throws RemoteException, NamingException {
                  Context ctx 
          = new InitialContext();
                  SessionFactory sf 
          = (SessionFactory) ctx.lookup("hibernate/quickstart");
                  Session s 
          = sf.getCurrentSession();
                  
          try {
                      List ls 
          = s.createQuery("from example.Cat").list();
                      String x 
          = String.valueOf(ls.size());
                      log.info(
          "length:" + x);
                      
          return x;
                  } 
          catch (RuntimeException e) {

                  } 
          finally {
                      s.close();
                  }
                  
          return null;

              }
          }


          這段程序一個特殊的地方就是我們使用sf.getCurrentSession ()來得到一個Session對象,另外一個就是沒有在里面手動地處理事務。當然這只是一個查詢而已,不過其他的程序寫法都是類似的。

          ejb-jar.xml

          <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> 
          <ejb-jar> 
              
          <enterprise-beans> 
                  
          <session> 
                      
          <ejb-name>SampleObject</ejb-name>     
                      
          <home>hh.SampleHome</home> 
                      
          <remote>hh.Sample</remote> 
                      
          <ejb-class>example.SampleBean</ejb-class> 
                      
          <session-type>Stateless</session-type> 
                      
          <transaction-type>Container</transaction-type> 
              
                  
          </session> 
              
          </enterprise-beans> 
              
          <assembly-descriptor>
                  
          <container-transaction>
                      
          <method>
                          
          <ejb-name>SampleObject</ejb-name>
                             
          <method-name>*</method-name>
                      
          </method>
                      
          <trans-attribute>Required</trans-attribute>
                  
                  
          </container-transaction>
              
          </assembly-descriptor>
          </ejb-jar>

           

          weblogic-ejb-jar.xml:

          <!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN' 'http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd'> 
          <weblogic-ejb-jar> 
              
          <weblogic-enterprise-bean> 
                  
          <ejb-name>SampleObject</ejb-name>
                  
          <jndi-name>SampleObject</jndi-name> 
              
          </weblogic-enterprise-bean> 
          </weblogic-ejb-jar>


          最后是我們的客戶端程序:


          package example;


          import java.util.Properties;
          import javax.naming.Context;
          import javax.naming.InitialContext;
          import javax.rmi.PortableRemoteObject;

          public class TestClient {
              
          /**
               * @param args
               
          */
              
          public static void main(String[] args) {

                  Properties p
          =new Properties();
                  p.put(Context.INITIAL_CONTEXT_FACTORY,
          "weblogic.jndi.WLInitialContextFactory");
                  p.put(Context.PROVIDER_URL,
          "t3://localhost:7001");      
                  
          try {
                      Context initial
          =new InitialContext(p);
                      Object obj
          =initial.lookup("SampleObject");          
                      SampleHome sample
          =(SampleHome) PortableRemoteObject.narrow(obj,SampleHome.class);           
                      Sample s
          =sample.create();           
                      System.
          out.println("We have " + s.countCats() + " cat(s).");
                      
                  } 
          catch (Exception e)
                  {
                     e.printStackTrace();
                  }
                  
              }

          }


           

          運行后就可以看到表中的記錄條數。

           

          posted on 2005-07-11 19:17 閱讀(4737) 評論(3)  編輯  收藏 所屬分類: 編程相關

          FeedBack:
          # re: 在WebLogic中使用Hibernate
          2006-03-28 18:37 | maidongdong
          請問一些問題:

          我的一個項目(struts+hibernate+weblogic),在struts的DemoAction中通過DAO(DemoDAOFactory,其中封裝了對表Demo的相關操作)訪問數據庫,我也用到了上面的啟動類(HibernateStartUp,并且也在weblogic控制臺中實施了部署),一切工作就緒。
          所有的文件也都放到了如下相應的目錄:
          d:\bea\user_project\domain\mydomain\application\myapp\WEB-INF\
          下(包括HibernateStartUp,也放到了該目錄對應的classes對應的包文件夾下面)。

          但是,啟動weblogic的時候,報錯:無法找到HibernateStartUp類。
          首先,對于web項目,應用服務器對于用到的類不是就會到WEB-INF\lib或者到
          WEB-INF\classes中去找嗎?為什么HibernateStartUp類他會找不到呢,
          對于應用服務器是如何把WEB-INF\lib和WEB-INF\classes放到classpath中的,我實在不甚明白(查遍了startWeblogic.cmd SetEnv.cmd 等一些相關的啟動文件,都找不到)

          其次,如果照上面你說的做的話(即在startWeblogic.cmd中增加set Hibernate_lib set my_classes等等),應用服務器還用到WEB-INF\classes和WEB-INF\lib中相應的類嗎?這樣,啟不是相當于把類的路徑給重定向了。

          望你指破其中玄機?  回復  更多評論
            
          # re: 在WebLogic中使用Hibernate
          2008-03-12 20:18 | jarrywen
          這么好的問題竟然沒有人回答,我也想要這樣的一個好的解決方法。這是weblogic classloaderd的機制問題,ejb加載的classloader比web高一個級別,沒法向下加載web的classloader,而web可以向上找到ejb的jar。
            回復  更多評論
            
          # re: 在WebLogic中使用Hibernate
          2008-03-12 20:20 | jarrywen
          其次,如果照上面你說的做的話(即在startWeblogic.cmd中增加set Hibernate_lib set my_classes等等),應用服務器還嗎?這樣,啟不是相當于把類的路徑給重定向了。

          《-----不指定,應用服務器不會去用到WEB-INF\classes和WEB-INF\lib中相應的類

          但是web服務器可能變成加載了兩次,不過好像也沒有好的辦法  回復  更多評論
            
          主站蜘蛛池模板: 东海县| 额尔古纳市| 兰西县| 灌南县| 和静县| 张北县| 邯郸市| 宁安市| 鄂托克前旗| 长宁区| 屏东市| 武功县| 南阳市| 昌图县| 呼图壁县| 巧家县| 丹阳市| 历史| 封开县| 临城县| 开江县| 漳州市| 格尔木市| 遂川县| 潞西市| 屏边| 含山县| 会理县| 张家口市| 兖州市| 雷山县| 应用必备| 江山市| 德安县| 泸溪县| 沙坪坝区| 温宿县| 乐都县| 永宁县| 仙桃市| 建宁县|