持久層是企業級應用的基石。面對對象模型與關係數據庫的「阻抗失配」,Hibernate 作為主流 ORM 框架提供了優雅的映射方案。本文以「化學元素周期表查詢」為例,完整演示 Struts 專案中集成 Hibernate 的全流程:數據庫建表、JavaBean 與 .hbm.xml 映射、hibernate.cfg.xml 配置、Action 調用、以及通過 Struts Plugin 緩存 SessionFactory 提升性能。
java org.hsqldb.Server。elements(id, name, number, mass, symbol),symbol 唯一索引。create table elements (
id integer(3) IDENTITY,
name char(30), number char(30), mass char(30), symbol char(2)
);
CREATE UNIQUE INDEX ui_elements_pk ON elements (symbol);
insert into elements (name, number, mass, symbol) values ('Manganese','25','55','Mn');
...(其餘 7 條)
// Element.java
public class Element {
private int id;
private String name, symbol, number, mass;
// getter/setter 省略
}
<!-- Element.hbm.xml -->
<hibernate-mapping>
<class name="com.strutsrecipes.hibernate.beans.Element" table="elements">
<id name="id" column="id"><generator class="native"/></id>
<property name="name" column="name"/>
<property name="number" column="number"/>
<property name="mass" column="mass"/>
<property name="symbol" column="symbol"/>
</class>
</hibernate-mapping>
關鍵點:<id> 聲明主鍵,generator class="native" 由數據庫決定生成策略;property 的 column 可省略(同名時),但顯式寫出利於維護。
<!-- hibernate.cfg.xml -->
<hibernate-configuration>
<session-factory>
<property name="dialect">net.sf.hibernate.dialect.HSQLDialect</property>
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="connection.url">jdbc:hsqldb:hsql://127.0.0.1</property>
<property name="show_sql">true</property>
<mapping resource="/com/strutscookbook/hibernate/beans/Element.hbm.xml"/>
</session-factory>
</hibernate-configuration>
文件必須置於 classpath 根目錄(如 WEB-INF/classes)。
SessionFactory 創建極其昂貴(解析映射、建立連接池),全局僅需一個實例。利用 org.apache.struts.action.PlugIn 在應用啟動時構建並存入 ServletContext:
public class HibernatePlugIn implements PlugIn {
private static final String FACTORY_KEY = "hibernate.SessionFactory";
public void init(ActionServlet servlet, ModuleConfig config) {
Configuration cfg = new Configuration().configure(); // 讀取 hibernate.cfg.xml
SessionFactory factory = cfg.buildSessionFactory();
servlet.getServletContext().setAttribute(FACTORY_KEY, factory);
}
public void destroy() {
SessionFactory factory = (SessionFactory)
servlet.getServletContext().getAttribute(FACTORY_KEY);
if (factory != null) factory.close();
}
}
struts-config.xml 註冊:
<plug-in className="com.strutsrecipes.hibernate.HibernatePlugIn"/>
public class ElementLookupAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
ServletContext ctx = getServlet().getServletContext();
SessionFactory factory = (SessionFactory) ctx.getAttribute("hibernate.SessionFactory");
Session session = factory.openSession();
try {
String symbol = request.getParameter("symbol");
Query query = session.createQuery("from Element where symbol = :sym");
query.setParameter("sym", symbol);
Element element = (Element) query.uniqueResult();
request.setAttribute("element", element);
return mapping.findForward("success");
} finally {
session.close();
}
}
}
hibernate.cfg.xml、*.hbm.xml → WEB-INF/classesWEB-INF/libWEB-INF/classesStruts 控制流程,Hibernate 處理持久化,Plugin 確保 SessionFactory 單例複用。此架構清晰分層、啟動快、運行穩,是中小型 Struts 1.x 應用的經典整合範式。