一、目的:
- 使初學者能更好的去了解SSH框架。
- 給以後的自己,也給別人一個參考。
- 嘗試搭建一個完整的SSH框架項目。
二、SSH三大框架的概述
Struts + Spring + Hibernate三者各自的特點都是什麼?
Struts 的MVC設計模式可以使我們的邏輯變得很清晰,主要負責表示層的顯示。
Spring 的IOC和AOP可以使我們的項目在最大限度上解藕。
hibernate的就是實體對象的持久化了, 數據庫的封裝。
表現層、中間層(業務邏輯層)和數據服務層。三層體系將業務規則、數據訪問及合法性校驗等工作放在中間層處理。客戶端不直接與數據庫交互,而是通過組件與中間層建立連接,再由中間層與數據庫交互。
表現層是傳統的JSP技術。
中間層採用的是流行的Spring+Hibernate,爲了將控制層與業務邏輯層分離,又細分爲以下幾種。
Web層,就是MVC模式裏面的“C”(controller<action>),負責控制業務邏輯層與表現層的交互,調用業務邏輯層,並將業務數據返回給表現層作組織表現,該系統的MVC框架採用Struts。
Service層(就是業務邏輯層),負責實現業務邏輯。業務邏輯層以DAO層爲基礎,通過對DAO組件的正面模式包裝,完成系統所要求的業務邏輯。
DAO層,負責與持久化對象交互。該層封裝了數據的增、刪、查、改的操作。
PO,持久化對象。通過實體關係映射工具將關係型數據庫的數據映射成對象,很方便地實現以面向對象方式操作數據庫。
Spring的作用貫穿了整個中間層,將Web層、Service層、DAO層及PO無縫整合,其數據服務層用來存放數據。
三、項目實戰案例
創建項目有兩種方式:web動態項目及maven項目(建議使用maven創建項目)。
創建web動態工程注意classpath路徑
導入本次項目要使用到的jar包:
struts:http://struts.apache.org/
hibernate:https://sourceforge.net/projects/hibernate/files/latest/download?source=files (訪問就提示下載,無需做其它操作)
spring:http://maven.springframework.org/release/org/springframework/spring/
在lib文件夾下添加相關jar包依賴(建議使用maven創建項目,便於jar包管理,避免jar版本衝突)
相關配置文件:
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>ssh</display-name> <!-- 將Spring配置到web項目中 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 將struts配置到web項目中 --> <filter> <filter-name>struts</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> |
spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- 自動處理靜態資源文件 --> |
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- context 註解 --> <!-- tx 事務--> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 開啓註解 --> <context:annotation-config/> <!-- 指定哪些包下受baen管制 --> <context:component-scan base-package="com.blog"></context:component-scan> <!-- 數據源(數據庫) --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="url" value="jdbc:mariadb://localhost:3300/blog"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <!-- 配置SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 擴展使用Hibernate原生的配置 --> <property name="hibernateProperties"> <props> <prop key="dialect">org.hibernate.dialect.MariaDB53Dialect</prop> <prop key="show_sql">true</prop> </props> </property> <!-- 映射實體類(Entity) --> <property name="packagesToScan" value="com.blog.blog.entity, com.blog.admin.entity"/> </bean> <!-- 事務層 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 事務註解 --> <tx:annotation-driven/> <!-- 開啓aop --> <aop:aspectj-autoproxy/> </beans> |
struts.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package namespace="/" name="default" extends="struts-default"> <!-- 設置和配置action的攔截器 --> <interceptors> <interceptor name="loginInterceptor" class="com.blogAdmin.action.articleTpye.LoginInterceptorAction"></interceptor> </interceptors> <!-- 定義爲全局結果,這樣action和result都能訪問 --> <global-results> <result name="loginRedirect" type="redirectAction">loginPage</result> </global-results> <!-- 登陸成功跳轉的頁面 --> <action name="list" class="com.blogAdmin.action.articleTpye.ListAction"> <interceptor-ref name="defaultStack"></interceptor-ref> <!-- 系統默認攔截器 --> <interceptor-ref name="loginInterceptor"></interceptor-ref> <!-- 自己定義的攔截器 --> <!-- 首頁面 --> <result name="list">/WEB-INF/jsp/articleType/list.jsp</result> </action> </package> </struts> |
後臺代碼(部分,不完整)
Entity層(具體根據數據庫表及字段進行創建相應實體類)
初始化Hibernate的entity
package com.blogAdmin.init;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateInit extends HttpServlet {
private static final long serialVersionUID = 1L;
public static SessionFactory sf;
@Override
public void init() throws ServletException {
super.init();
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
sf = new MetadataSources(registry).buildMetadata().buildSessionFactory();
}
}
dao層
userDao類
package com.blogAdmin.dao;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.query.Query;
import com.opensymphony.xwork2.ActionSupport;
import com.blogAdmin.entity.Article;
import com.blogAdmin.entity.User;
import com.blogAdmin.init.HibernateInit;
/**
* 用戶登陸的dao
* @author admin
*
*/
public class UserDao extends ActionSupport implements Serializable {
private static final long serialVersionUID = -9124089639234157594L;
public User findByUserName(String username){
Session session = HibernateInit.sf.openSession();
String hql = "from User where username=?";
Query<User> dbUser = session.createQuery(hql,User.class);
dbUser.setParameter(0, username);
return dbUser.uniqueResult();
}
public Article getByUser(String id){
Article article = null;
Session session = HibernateInit.sf.openSession();
article = session.get(Article.class, id);
session.close();
return article;
}
}
(增刪改查)dao層
package com.blogAdmin.dao;
import java.math.BigInteger;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import com.blogAdmin.entity.Article;
import com.blogAdmin.init.HibernateInit;
import com.blogAdmin.vo.ArticleVo;
public class ArticleDao {
/**
* 添加
* @param article
*/
public void save(Article article) {
Session session = HibernateInit.sf.openSession();
Transaction ts = session.beginTransaction();
session.save(article);
ts.commit();
session.close();
}
/**
* 刪除
* @param id
*/
public void delete(String id) {
Session session = HibernateInit.sf.openSession();
Transaction ts = session.beginTransaction();
String hql = "delete from Article where id=?";
session.createQuery(hql).setParameter(0, id).executeUpdate();
ts.commit();
session.close();
}
/**
* 修改
* @param article
*/
public void update(Article article) {
Session session = HibernateInit.sf.openSession();
Transaction ts = session.beginTransaction();
session.update(article);
ts.commit();
session.close();
}
/**
* 分頁查詢
* @param pageNum
* @param pageSize
* @return
*/
public List<ArticleVo> pageList(int pageNum, int pageSize) {
List<ArticleVo> returnList = null;
Session session = HibernateInit.sf.openSession();
Query<ArticleVo> query = session.createNativeQuery("select a.*,u.username name,t.name articleType from article a join user u join article_type t on a.user_id=u.id and a.type_id=t.id order by a.create_time",ArticleVo.class);
query.setFirstResult((pageNum - 1) * pageSize);
query.setMaxResults(pageSize);
returnList = query.list();
session.close();
return returnList;
}
/**
* 獲取總條數
* @return
*/
public BigInteger totalCount() {
BigInteger totalCount = new BigInteger("0");
Session session = HibernateInit.sf.openSession();
totalCount = (BigInteger) session.createNativeQuery("select count(id) from article").uniqueResult();
session.close();
return totalCount;
}
/**
* 根據id查詢一條數據
* @param typeId
* @return
*/
public Article getById(String id){
Article article = null;
Session session = HibernateInit.sf.openSession();
article = session.get(Article.class, id);
session.close();
return article;
}
}
service<接口>及serviceImpl<實現類>層
略
action層
LoginAction類
package com.blogAdmin.action.articleTpye;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
import com.blogAdmin.dao.UserDao;
import com.blogAdmin.entity.User;
import com.blogAdmin.vo.UserVo;
/**
* 登陸頁面的action
* @author admin
*
*/
@Results({@Result(location="/WEB-INF/jsp/login.jsp"),
@Result(name="list",type="redirectAction",location="list"),
@Result(name="loginPage",type="redirectAction",location="loginPage")})
public class LoginAction extends ActionSupport implements ServletRequestAware{
private static final long serialVersionUID = 6690219852711831094L;
private HttpSession session; //獲取session對象,將UserVo對象存入session
private UserVo userVo;
public UserVo getUserVo() {
return userVo;
}
public void setUserVo(UserVo userVo) {
this.userVo = userVo;
}
/**
* 1,打開登陸頁面
*/
@Action("/loginPage")
public String loginPage() {
return SUCCESS;
}
/**
*2,登陸按鈕action
* @return
*/
@Action("/login")
public String login(){
//判斷是否爲空
String name = userVo.getUsername();
String pass = userVo.getPassword();
if(name==null||"".equals(name)&&pass==null||"".equals(pass)){
session.setAttribute("msg", "用戶名或密碼不能爲空!");
return "loginPage";
}
UserDao dao = new UserDao();
User user = dao.findByUserName(userVo.getUsername());
if(user==null){
session.setAttribute("msg", "用戶名或密碼不正確!");
return "loginPage";
}
if (!user.getPassword().equals(pass)) {
session.setAttribute("msg", "用戶名或密碼不正確!");
return "loginPage";
}
session.setAttribute("userVo", userVo);
return "list";
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.session = request.getSession();
}
}
LoginInterceptorAction類
package com.blogAdmin.action.articleTpye;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class LoginInterceptorAction implements Interceptor{
private static final long serialVersionUID = -7254285326542480257L;
@Override
public void destroy() {
}
@Override
public void init() {
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
HttpSession session = ServletActionContext.getRequest().getSession(); //通過struts的上下文,獲取到session對象
Object userVo = session.getAttribute("userVo");
if (userVo==null) {
return "loginRedirect"; //如果爲空,重定向到login頁面;
}
return invocation.invoke();
}
}
PageAction相關類
package com.blogAdmin.action.articleTpye;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import com.opensymphony.xwork2.ActionSupport;
import com.blogAdmin.dao.ArticleTypeDao;
import com.blogAdmin.entity.ArticleType;
@Results({ @Result(name = "typeSave", location = "/WEB-INF/jsp/articleType/save.jsp"),
@Result(name="updateType", location = "/WEB-INF/jsp/articleType/update.jsp"),
@Result(name="redirectTypeSave",type="redirectAction",location="typeSave"),
@Result(name="redirectList",type="redirectAction",location="list"),
@Result(name = "list", location = "/WEB-INF/jsp/articleType/list.jsp")
})
public class ArticleTypeAction extends ActionSupport {
private static final long serialVersionUID = 6780775618333937202L;
//添加
private String typeName;
//分頁
private int pageNum;
private int pageSize=10;
//刪除
private String typeId;
//修改時的對象
ArticleType articleType;
/**
* 文章列表
* @return
*/
@Action("/articleType/list")
public String list(){
ArticleTypeDao dao = new ArticleTypeDao();
ServletActionContext.getRequest().setAttribute("list", dao.pageList(pageNum, pageSize));
ServletActionContext.getRequest().setAttribute("totalCount", dao.totalCount());
return "list";
}
/**
* 進入添加頁面
* @return
*/
@Action("/articleType/typeSave")
public String typeSave() {
return "typeSave";
}
/**
* 點擊保存(添加分類)
* @return
*/
@Action("/articleType/save")
public String save() {
ArticleTypeDao dao = new ArticleTypeDao();
dao.save(typeName);
return "redirectList";
}
/**
* 刪除頁面
* @return
*/
@Action("/articleType/delete")
public void delete(){
ArticleTypeDao dao = new ArticleTypeDao();
dao.delete(typeId);
}
/**
* 進入編輯頁面
* @return
*/
@Action("/articleType/updateType")
public String updateType(){
ArticleTypeDao dao = new ArticleTypeDao();
ServletActionContext.getRequest().setAttribute("articleType", dao.getById(typeId));
return "updateType";
}
/**
* 點擊修改
* @return
*/
@Action("/articleType/update")
public String update() {
ArticleTypeDao dao = new ArticleTypeDao();
dao.update(articleType);
return "redirectList";
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public String getTypeId() {
return typeId;
}
public void setTypeId(String typeId) {
this.typeId = typeId;
}
public ArticleType getArticleType() {
return articleType;
}
public void setArticleType(ArticleType articleType) {
this.articleType = articleType;
}
}
IndexAction類
package com.blogAdmin.action.articleTpye;
import com.opensymphony.xwork2.ActionSupport;
/**
* 登陸成功後展示的頁面
* @author admin
*
*/
public class ListAction extends ActionSupport{
private static final long serialVersionUID = -7248676355265672252L;
/**
* 首頁面
* @return
*/
@Override
public String execute() throws Exception {
return "list";
}
}