理論部分
SSH就是 struts+spring+hibernate 的一個集成框架,是java中一種流行的JAVA WEB 應用程序開源框架。因爲我最熟悉的還是ASP.NET的的MVC和Python的Django框架,今天有必要學習下java 的流行框架SSH,我發現其中有很多類似的地方,
l Struts就是Django中的Views層+模板層的一個前臺數據填充模塊
l spring 就是連接Struts和Hibernate 的中間業務邏輯層,
l Hibernate 就是典型的數據庫映射層嘛
下面是看了篇博客然後總結的:
Struts
這是的java 基於Sun J2EE 平臺的MVC框架,主要是採用 Servlet 和 JSP 技術來實現的。
Spring
解決許多J2EE開發中常見的問題的框架,Spring提供了管理業務對象的一致性方法並且鼓勵面向接口編程而不是對類編程,Spring架構的基礎是基於JavaBean屬性的Inersion of Control容器,String提供了唯一的數據訪問抽象,包括簡單和有效的JDBC框架,String 結合Hibernate和其他的O/R mapping 解決方案等。
官方地址:spring: http://www.springsource.org
Hibernate
他是一個開源的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java 程序員可以隨心所欲的使用對象編程思維來操控數據庫,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。
在SSH的組合模式中,三者各自的作用
Struts 是一個很好的MVC框架,主要技術是Servlet 和Jsp.Struts的MVC設計模式可以使我們的邏輯變得很清晰,讓程序變得層次分明(類似於Django中的Views層)。
Spring提供了管理業務對象的一致化方法,並且鼓勵對接口編程而不是對類編程,這樣在很大程度上鬆解了耦合(已經被融入到Views層中了)。
Hibernate 是用來持久化數據的,提供全面的面向對象的數據庫操作,Hibernate 對JDBC進行了非常輕量級的封裝,這樣和數據庫打交道就容易多了(類似於Django 中的models層)。
其中很多沒說的,直接看看SSH架構圖吧:
Struts負責的是web層:
ActionFormBean接收網頁中表單提交的數據,然後通過Action進行處理,再Forward到對應的網頁中,在Struts-config.xml中定義<action-mapping>,這樣ActionServlet會加載進來。
Spring負責的是業務邏輯層,即Service:
Service爲Action提供統一的調用接口,封裝持久層的DAO,並且集成了Hibernate ,Spring可對JavaBean(對象)和事物進行統一的管理。
Hibernate負責持久層,完成數據庫的CRUD操作:
Hibernate有一組hbm.xml和PO,是數據庫中的對應的表相對應的,然後定義DAO,這些是與數據庫打交道的類。(直接就是複雜化的Models層)
下面是SSH中的對象調用流程圖:
主要的數據流路徑是:Struts->Spring->Hibernate(JSP->Action->Service->DAO->Hibernate)
操作部分
接下來以一個案例談ssh框架
題目:
題目:火車車次信息管理 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
一、語言和環境 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
A、實現語言 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Java |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
B、環境要求 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
JDK1.6、Eclipse、Tomcat7.*、MySql |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
二、功能要求 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
實現火車車次信息管理功能,功能包括車次信息瀏覽、火車車次信息詳情和車次信息刪除兩大功能。具體要求如下: (1)打開火車車次信息管理首頁,以列表方式顯示所有車次信息,頁面列表要求實現隔行變色效果,如圖-1所示。
圖-1 (2)單擊“刪除”鏈接可以進行火車車次信息刪除,如果沒有複選框被選中,當單擊“刪除”鏈接時需要提示“請選擇車次!”信息,如圖-2所示。
圖-2 (3)如果選中複選框,單擊“刪除”鏈接,執行刪除車次信息操作,並根據刪除結果給出相應的信息提示,如圖-3所示。
圖-3 點擊確定後,跳轉至車次信息列表頁面,並顯示更新後的車次列表信息,如圖-4所示。
圖-4 (4)單擊車次超鏈接,則跳轉至指定車次的火車車次詳情頁面,如圖-5所示。
圖-5 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
三、 |
數據庫設計 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
數據庫表名稱及要求: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
四、注意事項 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
1、 請注意界面美觀,控件擺放整齊; |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
2、 請注意代碼的書寫、命名符合規範,在代碼中添加必要的註釋; |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
3、 請注意操作數據庫時進行必要的異常處理。 |
詳細步驟:
第一步:搭建數據庫
CREATE TABLE `train_info` (
`train_no` varchar(50) NOT NULL DEFAULT '' COMMENT '車次編號',
`start_station` varchar(50) DEFAULT NULL COMMENT '始發站',
`arrival_station` varchar(50) DEFAULT NULL COMMENT '終點站',
`start_time` varchar(50) DEFAULT NULL COMMENT '出發時間',
`arrival_time` varchar(50) DEFAULT NULL COMMENT '到達時間',
`type` varchar(50) DEFAULT NULL COMMENT '車次類型',
`runtime` varchar(50) DEFAULT NULL COMMENT '運行時間',
`mile` decimal(18,1) DEFAULT NULL COMMENT '里程',
PRIMARY KEY (`train_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='火車車次信息表';
第二步:建立Dynamic web project(要生成web.xml)文件
Web.XML見下一步
第三步:在web-INF 的lib下導入以下包
Web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>train</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
配置spring的監聽器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置struct2-->
<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>
</web-app>
第四步:在src中創建以下包
4.1創建實體對象包train_ssh.enerty
(爲了探究hibernate持久層如何實現實體對象與數據表的對應該javabean特意與表不對應,在實際中要對應)
創建javabean TrainInfo
package train_ssh.enerty;
import java.io.Serializable;
public class TrainInfo implements Serializable {
private static final long serialVersionUID = 601392197901780L;
private String train_no;
private String start_time;
private String start_station;
private String arrival_time;
private String arrival_station;
private String type;
private String runtime;
private Double mile;
public String getStart_time() {
return this.start_time;
}
public void setStart_time(String start_time) {
this.start_time = start_time;
}
public String getStart_station() {
return this.start_station;
}
public void setStart_station(String start_station) {
this.start_station = start_station;
}
public String getArrival_time() {
return this.arrival_time;
}
public void setArrival_time(String arrival_time) {
this.arrival_time = arrival_time;
}
public Double getMile() {
return this.mile;
}
public void setMile(Double mile) {
this.mile = mile;
}
public String getTrain_no() {
return this.train_no;
}
public void setTrain_no(String train_no) {
this.train_no = train_no;
}
public String getRuntime() {
return this.runtime;
}
public void setRuntime(String runtime) {
this.runtime = runtime;
}
public String getArrival_station() {
return this.arrival_station;
}
public void setArrival_station(String arrival_station) {
this.arrival_station = arrival_station;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
}
生成hibernate maping 映射文件TrainInfo.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">
<!-- Generated 2018-1-17 10:58:25 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="train_ssh.enerty.TrainInfo" table="TRAIN_INFO">
<id name="train_no" type="java.lang.String">
<column name="train_no" />
<generator class="assigned" />
</id>
<property name="start_station" type="java.lang.String">
<column name="START_STATION" />
</property>
<property name="arrival_station" type="java.lang.String">
<column name="ARRIVAL_STATION" />
</property>
<property name="start_time" type="java.lang.String">
<column name="START_TIME" />
</property>
<property name="arrival_time" type="java.lang.String">
<column name="ARRIVAL_TIME" />
</property>
<property name="type" type="java.lang.String">
<column name="TYPE" />
</property>
<property name="runtime" type="java.lang.String">
<column name="RUNTIME" />
</property>
<property name="mile" type="java.lang.Double">
<column name="MILE" />
</property>
</class>
</hibernate-mapping>
4.2創建Dao層
Dao層包含以下兩個包分別是train_ssh.dao接口包和train_ssh.dao.impl接口類實現包
在train_ssh.dao寫以下接口TrainInfoDao:
package train_ssh.dao;
import java.util.List;
import train_ssh.enerty.TrainInfo;
public interface TrainInfoDao {
List<TrainInfo> findTrainaALL();
List<TrainInfo> findTrainOne(String Tno);
String dellist(String Tno);
}
//在train_ssh.dao.impl中寫實現接口的類TrainINfoDaoImpl
package train_ssh.dao.impl;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import train_ssh.dao.TrainInfoDao;
import train_ssh.enerty.TrainInfo;
public class TrainINfoDaoImpl extends HibernateDaoSupport implements TrainInfoDao {
@Override
public List<TrainInfo> findTrainaALL(){
List<TrainInfo> list=super.getHibernateTemplate().find("from TrainInfo");
return list;
}
@Override
public List<TrainInfo> findTrainOne(String Tno) {
List<TrainInfo> list=super.getHibernateTemplate().find("from TrainInfo t where t.train_no=?", Tno);
return list;
}
@Override
public String dellist(String Tno) {
TrainInfo train=super.getHibernateTemplate().get(TrainInfo.class, Tno);
super.getHibernateTemplate().delete(train);
return "success";
}
}
4.3創建業務層
業務層包含以下兩個包分別是train_ssh.serves接口包和train_ssh.serves.impl接口類實現包
在train_ssh.serves寫以下接口TrainServes:
package train_ssh.serves;
import java.util.List;
import train_ssh.enerty.TrainInfo;
public interface TrainServes {
List<TrainInfo> findTrainaALL();
List<TrainInfo> findTrainOne(String Tno);
String deldellist(String Tno);
}
在train_ssh.serves.impl寫以下接口的實現類TrainServesImpl:
package train_ssh.serves.impl;
import java.util.List;
import train_ssh.dao.TrainInfoDao;
import train_ssh.enerty.TrainInfo;
import train_ssh.serves.TrainServes;
public class TrainServesImpl implements TrainServes{
private TrainInfoDao traindao;
public TrainInfoDao getTraindao() {
return traindao;
}
public void setTraindao(TrainInfoDao traindao) {
this.traindao = traindao;
}
@Override
public List<TrainInfo> findTrainaALL() {
return traindao.findTrainaALL();
}
@Override
public List<TrainInfo> findTrainOne(String Tno) {
return traindao.findTrainOne(Tno);
}
@Override
public String deldellist(String Tno) {
return traindao.dellist(Tno);
}
}
4.4創建web層
該部分爲Action 和 jsp兩部分
第一部分:在train_ssh.action編寫TrainAction類
package train_ssh.action;
import java.util.List;
import com.opensymphony.xwork2.Action;
import train_ssh.enerty.TrainInfo;
import train_ssh.serves.TrainServes;
public class TrainAction implements Action {
private TrainServes trainserves;
private List<TrainInfo> trains;
private String Tno;
private List<String> Tnos;
public TrainServes getTrainserves() {
return trainserves;
}
public void setTrainserves(TrainServes trainserves) {
this.trainserves = trainserves;
}
public List<TrainInfo> getTrains() {
return trains;
}
public void setTrains(List<TrainInfo> trains) {
this.trains = trains;
}
public String getTno() {
return Tno;
}
public void setTno(String tno) {
Tno = tno;
}
public List<String> getTnos() {
return Tnos;
}
public void setTnos(List<String> tnos) {
Tnos = tnos;
}
@Override
public String execute() throws Exception {
trains=trainserves.findTrainaALL();
return SUCCESS;
}
public String selectOne() throws Exception{
trains=trainserves.findTrainOne(Tno);
return SUCCESS;
}
public String dellist() throws Exception{
try {
for (String string : Tnos) {
System.out.println(string+"---------");
trainserves.deldellist(string);
}
} catch (Exception e) {
return ERROR;
}
return SUCCESS;
}
}
第二部分:編寫jsp頁面
(後面詳細談)
第五步:寫spring配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- Dao -->
<bean id="traindao" class="train_ssh.dao.impl.TrainINfoDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- service -->
<bean id="trainserves" class="train_ssh.serves.impl.TrainServesImpl">
<property name="traindao" ref="traindao"></property>
</bean>
<!-- action -->
<bean id="trainAction" class="train_ssh.action.TrainAction">
<property name="trainserves" ref="trainserves"></property>
</bean>
該部分是hibernate數據源配置文件或可以分離?
<!-- 數據源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value="jdbc:mysql://127.0.0.1:3306/java1067?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8">
</property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<!-- sessionFactory配置 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</prop>
<!-- 顯示執行的sql語句 -->
<prop key="hibernate.show_sql">true</prop>
<!-- 格式化生成的sql語句 -->
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>train_ssh/enerty/TrainInfo.hbm.xml</value>
</list>
</property>
</bean>
<!--事務管理器配置 -->
<bean id="transactionManger"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 定義事務規則 -->
<tx:advice id="txAdvice" transaction-manager="transactionManger">
<tx:attributes>
<tx:method name="find*" read-only="true" />
<tx:method name="add*" />
<tx:method name="update*" />
<tx:method name="del*" />
</tx:attributes>
</tx:advice>
<!--值入 事務和業務層關聯到一起 申明事務 -->
<aop:config>
<aop:pointcut expression="execution(* train_ssh.serves.*.*(..))"
id="serviceMethod" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
</aop:config>
</beans>
第六步編寫:status2 的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="struts2" namespace="/" extends="struts-default">
<!-- struts2和spring整合後 class寫的是action在spring中配置的id名稱 -->
<action name="trainlist" class="trainAction">
<result>trainlist.jsp</result>
</action>
<action name="train" class="trainAction" method="selectOne">
<result name="success" type="dispatcher">train.jsp</result>
</action>
<action name="dellist" class="trainAction" method="dellist">
<result name="success" type="redirect">trainlist.jsp</result>
</action>
</package>
</struts>
補充:jsp