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

           

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


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


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

           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>



          關(guān)于數(shù)據(jù)庫表的建立,在這里就不再贅述了。

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

          1.      設(shè)置classpath,

          A.      hibernate本身需要一些jar(到底需要哪些jar可以參照hibernate文檔),你需要在classpath里面引入這些jar。另外你還會(huì)寫這個(gè)方法也仍然是修改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.      設(shè)置你編譯后的程序目錄,我們這里假設(shè)假如你編譯后的代碼在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導(dǎo)入的工作就完成了。

          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>

          配置時(shí)需要注意的就是session_factory_name中使用了一個(gè)點(diǎn)來代替/,也就是hibernate.quickstart,實(shí)際程序lookup時(shí)候仍然使用hibernate/quickstart

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

          4.      WebLogic的啟動(dòng)類,WebLogic的啟動(dòng)類需要實(shí)現(xiàn)weblogic.common.T3StartupDef接口,編程時(shí)候你要引入這個(gè)接口,可以通過引入weblogic.jar實(shí)現(xiàn)。假如你weblogic安裝在D:\bea下面,你可以在相應(yīng)的weblogic81\server\lib下找到這個(gè)jar。其實(shí)只是獲得SessionFactory,hibernate會(huì)自動(dòng)綁定到相應(yīng)的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了。


           

          下面是一些關(guān)于編程的簡(jiǎn)單介紹。


          如果不使用JTA,比如在一個(gè)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的話其實(shí)寫法和上面是一樣的。

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

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

           

          下面我們通過一個(gè)完整的SLSB的例子來看一下。這里仍然使用了我們?cè)谇懊嫣岬竭^的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;

              }
          }


          這段程序一個(gè)特殊的地方就是我們使用sf.getCurrentSession ()來得到一個(gè)Session對(duì)象,另外一個(gè)就是沒有在里面手動(dòng)地處理事務(wù)。當(dāng)然這只是一個(gè)查詢而已,不過其他的程序?qū)懛ǘ际穷愃频摹?BR>

          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();
                  }
                  
              }

          }


           

          運(yùn)行后就可以看到表中的記錄條數(shù)。

           

          posted on 2005-07-11 19:17 閱讀(4738) 評(píng)論(3)  編輯  收藏 所屬分類: 編程相關(guān)

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

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

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

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

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

          《-----不指定,應(yīng)用服務(wù)器不會(huì)去用到WEB-INF\classes和WEB-INF\lib中相應(yīng)的類

          但是web服務(wù)器可能變成加載了兩次,不過好像也沒有好的辦法  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 仁布县| 贞丰县| 江津市| 那坡县| 开封县| 华池县| 巴林右旗| 沙湾县| 秦皇岛市| 阳东县| 绵阳市| 略阳县| 绿春县| 大冶市| 诸城市| 巴彦淖尔市| 达孜县| 潜山县| 时尚| 石阡县| 临江市| 鹤峰县| 叶城县| 上犹县| 克拉玛依市| 交口县| 建湖县| 宁南县| 宁夏| 梁山县| 兴宁市| 平凉市| 离岛区| 屯昌县| 临夏县| 伊川县| 奈曼旗| 会泽县| 平原县| 东乡| 盐边县|