关于这个话题,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进行整合时候的那个程序。不过把程序所用的包给换了一下。
为了更加清晰,我仍然把代码贴在下面:
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:
<! 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 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 ClASSPATH =% MY_CLASSES % ; % CLASSPATH %
这样classpath导入的工作就完成了。
2. 打开Weblogic Administration Console ,然后配置好你的连接池和datasource,这里我使用datasource的JNDI Name用了mydatasource
3. 书写hibernate配置文件,大家都知道hibernate配置文件可以写成xml也可以写成properties的形式,这里我使用的是xml的方式。
<! 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上的。
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中可以这样写
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:
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:
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:
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
< 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:
< 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();
}
}
}
运行后就可以看到表中的记录条数。