首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

SSH 框架整合實戰:Struts2 + Hibernate + Spring + MySQL 完整搭建流程

     編輯:Java 綜合教學

SSH 框架整合實戰:Struts2 + Hibernate + Spring + MySQL 完整搭建流程

雖然當前主流已轉向 SSM(SpringMVC + Spring + MyBatis),但 SSH 作為經典三層架構代表,理解其整合原理對掌握 IoC、AOP、ORM 協作機制仍有重要價值。本文基於 Struts 2.3.24 + Hibernate 3.6.10 + Spring 4.3.2 + MySQL 5.5 記錄完整搭建步驟與核心配置。

一、項目結構與 JAR 依賴

採用標準三層分包:entity、dao、service、action。核心 JAR 分類管理(MyEclipse User Library):

  • Struts2:核心包、xwork、ognl、freemarker 等
  • Hibernate:核心包、c3p0、javassist、antlr(注意與 Struts2 版本衝突,需排除重複)
  • Spring:core、beans、context、aop、jdbc、tx、orm、web、spring-struts 整合包
  • MySQL:mysql-connector-java-5.0.8-bin.jar

Struts2 JAR Hibernate JAR Spring JAR

二、數據庫設計

-- 用戶表
CREATE TABLE t_user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50),
    password VARCHAR(50),
    deptNo INT,
    FOREIGN KEY (deptNo) REFERENCES _dept(deptNo)
);

-- 部門表(下劃線前綴避免關鍵字衝突)
CREATE TABLE _dept (
    deptNo INT PRIMARY KEY AUTO_INCREMENT,
    deptName VARCHAR(50)
);

三、實體類與映射文件

User.java / User.hbm.xml

// User.java
public class User {
    private int id;
    private String username, password;
    private Dept dept; // 多對一關聯
    // Getter/Setter 省略
}

// User.hbm.xml
<class name="com.mz.entity.User" table="t_user">
    <id name="id" column="id"><generator class="native"/></id>
    <property name="username" column="username"/>
    <property name="password" column="password"/>
    <many-to-one name="dept" column="deptNo" class="com.mz.entity.Dept"/>
</class>

Dept.java / Dept.hbm.xml

// Dept.java
public class Dept {
    private int deptNo;
    private String deptName;
    // Getter/Setter 省略
}

// Dept.hbm.xml
<class name="com.mz.entity.Dept" table="_dept">
    <id name="deptNo" column="deptNo"><generator class="native"/></id>
    <property name="deptName" column="deptName"/>
</class>

四、DAO / Service / Action 實現

UserDao(使用 HibernateTemplate)

public class UserDao {
    private SessionFactory sessionFactory;

    public boolean save(User user) {
        sessionFactory.getCurrentSession().save(user);
        return true;
    }
    public User getUserById(int id) {
        return (User) sessionFactory.getCurrentSession().get(User.class, id);
    }
    public List<User> getUserByDept(int deptNo) {
        String hql = "from User u where u.dept.deptNo = ?";
        return sessionFactory.getCurrentSession()
            .createQuery(hql).setInteger(0, deptNo).list();
    }
    // Getter/Setter for sessionFactory
}
注意:DAO 中無事務代碼,事務由 Spring 聲明式管理。

UserService

public class UserService {
    private UserDao userDao;
    public User getUser(int id) { return userDao.getUserById(id); }
    // Getter/Setter
}

UserAction(實現 RequestAware 獲取 Map)

public class UserAction extends ActionSupport implements RequestAware {
    private Map<String, Object> request;
    private UserService userService;

    public String execute() {
        User user = userService.getUser(2);
        request.put("user", user);
        return SUCCESS;
    }
    // Getter/Setter
}

五、核心配置文件

struts.xml

<package name="user" namespace="/" extends="struts-default">
    <action name="user" class="userAction"> <!-- class 對應 Spring Bean ID -->
        <result name="success">/index.jsp</result>
    </action>
</package>

applicationContext.xml (bean.xml) —— 核心整合點

<beans ... xmlns:aop="..." xmlns:tx="...">
    <!-- 1. C3P0 數據源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"/>
        <property name="user" value="root"/>
        <property name="password" value="111111"/>
        <property name="initialPoolSize" value="3"/>
        <property name="maxPoolSize" value="10"/>
    </bean>

    <!-- 2. SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
            <props>
                <prop key="dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="show_sql">true</prop>
                <prop key="hbm2ddl.auto">update</prop>
            </props>
        </property>
        <property name="mappingLocations">
            <list><value>classpath:com/mz/entity/*.hbm.xml</value></list>
        </property>
    </bean>

    <!-- 3. 事務管理器 -->
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 4. 事務通知 (AOP) -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="*save*" propagation="REQUIRED"/>
            <tx:method name="*get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="pt" expression="execution(* com.mz.service.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
    </aop:config>

    <!-- 5. Bean 裝配 -->
    <bean id="userDao" class="com.mz.dao.UserDao">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id="userService" class="com.mz.service.UserService">
        <property name="userDao" ref="userDao"/>
    </bean>
    <bean id="userAction" class="com.mz.action.UserAction">
        <property name="userService" ref="userService"/>
    </bean>
</beans>

web.xml

<!-- Spring 容器啟動 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:bean.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Struts2 過濾器 -->
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 解決 Hibernate 懶加載異常:OpenSessionInViewFilter -->
<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>openSessionInViewFilter</filter-name>
    <url-pattern>*.action</url-pattern>
</filter-mapping>

六、測試驗證

  1. 部署至 Tomcat 6
  2. 訪問 https://localhost:8080/ssh/user
  3. index.jsp 顯示 ${user.username} 成功
  4. 嘗試顯示關聯部門 ${user.dept.deptName},若拋出 LazyInitializationException,確認 OpenSessionInViewFilter 已正確配置並映射至 *.action

測試成功截圖 懶加載解決後截圖

七、關鍵點總結

環節核心要點
JAR 衝突Struts2 與 Hibernate 共用 antlr,需排除一份
事務管理Spring AOP 織入 Service 層,DAO 無事務代碼
Struts-Spring 整合Action 類在 Spring 中定義 Bean,struts.xml 中 class 指向 Bean ID
懶加載配置 OpenSessionInViewFilter 延長 Session 生命周期至視圖渲染結束
映射文件*.hbm.xml 放在 classpath 下,SessionFactory 掃描 mappingLocations
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved