关于这个话题,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="org.hibernate.examples.quickstart.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(); } }
}
运行后就可以看到表中的记录条数。
|