Spring+Struts+Hibernate整合筆記

前言

??在來寫這篇筆記之前樱衷,去看了一篇別人的美文。自從入行以來酒唉,已經(jīng)記不得有多久沒有去看真正的文學(xué)作品了矩桂。甚至曾經(jīng)一度以為那些能引起我們心靈共鳴的文章對我們的生活并沒有什么作用。畢業(yè)以來痪伦,我也從未放棄看書耍鬓,但看的書卻更具功利性,比如《XXX從入門到精通》流妻、《XXX指南》一類的書牲蜀。貌似這類書更具價值,因為它能變現(xiàn)绅这。不管出于什么樣的目的涣达,現(xiàn)在真正能靜下心來欣賞文學(xué)作品的人越來越少。功名利祿证薇,燈紅酒綠更能吸引人心度苔。但偶爾靜下心來,與心靈對話浑度,也會讓我們這種無產(chǎn)階級短暫的放下壓力寇窑,產(chǎn)生出幸福感。也許風(fēng)雨后的彩虹來得太晚箩张,但明天的路還長甩骏,我不會在今天就倒在路上。
??繼續(xù)我們的成長之旅先慷,這個標題已經(jīng)是老生常談饮笛,這些技能也幾乎是所有java程序員的基本技能。關(guān)于這三個框架的整合的教程已經(jīng)很多了论熙。但是比較系統(tǒng)的福青、或者說比較詳細的并且能在容易入坑的地方著重強調(diào)的文章卻不多。對于像我這種初學(xué)者來說脓诡,是越詳細越好无午,最好能在坑多的地方多做提醒。
??我在寫這篇筆記的時候會盡可能詳細的介紹這三個框架的整合過程祝谚,并在我掉坑的地方著重強調(diào)宪迟,一方面讓我記憶更深,另一方面希望對后來者有所幫助踊跟。我也是初學(xué)者踩验,如有不妥,也希望能留言指點商玫,先行謝過箕憾。

使用Struts框架搭建Web項目

??1、首先下載好Struts庫(點擊下載),在官方下載頁下載struts-2.5.14.1-all.zip拳昌。
??2袭异、創(chuàng)建Web Project:打開Eclipse => File => New => Web Project。
??3炬藤、在 ... => struts-2.5.14.1-all.zip => struts-2.5.14.1 => lib目錄下將如下圖的這些庫(也可下載struts-2.5.14.1-min.zip御铃,其中的庫是搭建Struts項目必須要導(dǎo)入的庫)拷貝到項目的WebRoot => WEB-INF => lib目錄下,并添加到build path沈矿。

image.png

??4上真、在WEB-INF下創(chuàng)建web.xml文件。
??5羹膳、在web.xml文件中配置struts攔截器(注意攔截器不要配錯了睡互,新版本的攔截器和舊版本攔截器不一樣,具體的可以看struts-core.jar下面是否有響應(yīng)的java類):

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>MyWeb</display-name>
  <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  <!-- 新版本struts用下面這個攔截器 -->
    <!--<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter> -->
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>
</web-app>

??6陵像、在src目錄下創(chuàng)建struts配置文件struts.xml (記住是src目錄就珠,不是WEB-INF目錄,如果要放在WEB-INF目錄下醒颖,請在WEB-INF目錄下創(chuàng)建classes目錄妻怎,并將struts.xml放在classes目錄下。這樣做的原因:在編譯的時候會將src下的文件拷貝到classes目錄下泞歉,WEB-INF/classes目錄下的文件也都全部會被拷到編譯路徑的classes目錄下逼侦,而WEB-INF下的文件不會被拷貝到classes目錄下,在程序運行的時候默認是在classes目錄下查找web.xml和struts.xml)腰耙。
??7偿洁、在com.xxx.action下創(chuàng)建LoginAction類:

package com.xxx.action;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport{

    private String userName;
    private String password;
    
    
    public String getUserName() {
        return userName;
    }


    public void setUserName(String userName) {
        this.userName = userName;
    }


    public String getPassword() {
        return password;
    }


    public void setPassword(String password) {
        this.password = password;
    }


    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    

    @Override
    public String execute() throws Exception {
        if ("test".equals(getUserName()) && "123456".equals(getPassword())) {
            return SUCCESS;
        }
        return ERROR;
    }

}

??8、在WEB-INF/content目錄下創(chuàng)建登錄成功和失敗的顯示頁success.jsp沟优、error.jsp:

success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'success.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    登錄成功!<br>
  </body>
</html>

error.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'error.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

</head>

<body>
    賬戶名或密碼錯誤
    <br>
</body>
</html>

??9涕滋、打開剛才創(chuàng)建好的struts.xml文件,開始配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="xxx" extends="struts-default">
        <action name="login.action" class="com.xxx.action.LoginAction">
            <result name="success">/WEB-INF/content/success.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>
    </package>
</struts>    

說明:package的name屬性是自己取的挠阁,用于管理action,必須要繼承extends="struts-default"宾肺。
特別注意:如果你使用的是舊版本的攔截器,那么在配置的時候action的name屬性login.action要寫全(因為后面請求的時候用的就是這個)侵俗,如果你使用的是新版本的攔截器锨用,那么只需要將action的name屬性配置為login就可以了(請求時的action name還是login.action)

??10、創(chuàng)建登錄頁隘谣,在WebRoot目錄下創(chuàng)建login.jsp(因為在web.xml文件在設(shè)置的welcome-file是login.jsp因此輸入網(wǎng)址會直接導(dǎo)航到這個界面)增拥,login.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'login.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    <form action="login.action">
        用戶名:<input type="text" name="userName"><br>
        密碼: <input type="password" name="password"><br>
        <input type="submit" value="登錄">
    </form>
  </body>
</html>

說明:form的action屬性要和struts.xml文件中配置是action的name屬性一致(舊版本啄巧,如果是新版本,在struts配置的時候如果是以.cation結(jié)尾掌栅,那么去掉.action)秩仆,input的name屬性對應(yīng)LoginAction中的userName屬性和password屬性,且名字必須保持一致猾封。

??到此為之澄耍,struts項目就搭建完成了,可以先運行下項目晌缘,測試運行過程是否正常齐莲,如果有問題,在下一步之前磷箕,請確保已經(jīng)解決选酗。

Spring整合Struts

??首先,下載spring岳枷,下載地址http://repo.springsource.org/libs-release-local/org/springframework/spring/星掰。根據(jù)需要下載相應(yīng)的版本,我下載的是5.0.1版嫩舟。
??下載下來后氢烘,解壓并找到libs文件夾,將libs下面的所有jar文件拷貝到項目的WebRoot/WEB-INF/libs目錄下家厌,并且add to build path播玖。
??修改web.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>MyWeb</display-name>
  <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <filter>
    <filter-name>struts2</filter-name>
   <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>
</web-app>

ContextLoaderListener這個監(jiān)聽器負責(zé)查找spring配置文件并啟動spring。context-param用于配置spring配置文件的路徑饭于,如果不配置蜀踏,則默認在WEB-INF下找applicationContext.xml文件。
??然后在WEB-INF/目錄下(請根據(jù)自己在context-param中配置的參數(shù)進行修改掰吕,路徑不對果覆,將找不到spring配置文件),創(chuàng)建applicationContext.xml文件殖熟。
??創(chuàng)建LoginService接口:

package com.xxx.service;

public interface LoginService {
    String doLogin(String userName,String password);
}

??創(chuàng)建LoginServiceImpl類:

package com.xxx.service;

import com.opensymphony.xwork2.ActionSupport;

public class LoginServiceImpl implements LoginService{
    
    private String userName = "xxx";
    private String password = "123456";

    @Override
    public String doLogin(String userName, String password) {
        if (this.userName.equals(userName) && this.password.equals(password)) {
            return ActionSupport.SUCCESS;
        }
        return ActionSupport.ERROR;
    }

}

??修改LoginAction類:

package com.xxx.action;

import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.opensymphony.xwork2.ActionSupport;
import com.xxx.service.LoginService;

public class LoginAction extends ActionSupport{

    private String userName;
    private String password;
    private LoginService loginService;
    
    
    
    
    public LoginService getLoginService() {
        return loginService;
    }


    public void setLoginService(LoginService loginService) {
        this.loginService = loginService;
    }


    public String getUserName() {
        return userName;
    }


    public void setUserName(String userName) {
        this.userName = userName;
    }


    public String getPassword() {
        return password;
    }


    public void setPassword(String password) {
        this.password = password;
    }


    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    

    @Override
    public String execute() throws Exception {
        return loginService.doLogin(userName, password);
    }

}

??最終的項目結(jié)構(gòu):


image.png

??現(xiàn)在開始配置spring:在applicationContext中配置bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.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">


    <bean id="loginService" class="com.xxx.service.LoginServiceImpl"/>
    
    <bean id="loginAction" scope="prototype" class="com.xxx.action.LoginAction">
        <property name="loginService" ref="loginService"></property>
    </bean>

</beans>

??修改struts配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <!-- <constant name="struts.objectFactory" value="spring" />
    <constant name="struts.devMode" value="true" /> -->
    <package name="xxx" extends="struts-default" namespace="/">
        <action name="login" class="loginAction">
            <result name="success">/WEB-INF/content/success.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>
    </package>
</struts>    


主要的變化是:login這個action的class屬性改成了在applicationContext中的id局待。這樣action的實例的創(chuàng)建將交由spring來管理。
??到這里就結(jié)束了嗎菱属?當然不是钳榨,我們忘了一件重要的事。在整合的過程中還要加入一個重要的庫struts2-spring-plugin-2.5.14.1.jar纽门,加入方法還是拷貝到WEB-INF/lib下薛耻,并加入到build path(注意:這個庫的版本一定要和struts的版本一致,否則可能出錯)赏陵。好了饼齿,到這里就可以運行程序了饲漾。如果在登錄頁面輸入用戶名xxx密碼123456能成功實現(xiàn)“登錄”功能,那么整合就基本實現(xiàn)了缕溉。
??在這里再補充一點考传,如果按照剛才的配置,應(yīng)該會出現(xiàn)一個ERRO倒淫,意思是說沒有導(dǎo)入log4j。log4j這個包負責(zé)打印日志败玉,對調(diào)試程序很有幫助敌土。導(dǎo)入這個包也比較簡單,首先導(dǎo)入log4j的jar包:

image.png

log4j的包自己網(wǎng)上找一下运翼,這里不多說返干。
然后在src下創(chuàng)建log4j2.xml文件,用于配置log4j:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">
<Configuration status="warn">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5p] %d %c - %m%n" />
        </Console>
        <File name="File" fileName="dist/my.log">
            <PatternLayout pattern="%m%n" />
        </File>
    </Appenders>

    <Loggers>
        <Logger name="mh.sample2.Log4jTest2" level="DEBUG">
            <AppenderRef ref="File" />
        </Logger>
        <Root level="INFO">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>  

重啟應(yīng)用血淌,如果那個ERRO消失了矩欠,那么log4j就配置成功了,如果還是有那個錯誤悠夯,就要根據(jù)錯誤提示癌淮,檢查錯誤可能是什么原因引起的。

整合Hibernate

??到這里真不容易沦补,已經(jīng)過半了乳蓄,再堅持一下。該項目已經(jīng)整合了spring+struts夕膀,現(xiàn)在將hibernate也整合進來就大功告成虚倒!
??首先還是下載hibernate,下載地址(http://hibernate.org/orm/releases/5.2/),點擊最右側(cè)的Download zip archive下載产舞。
??解壓后將...\hibernate-release-5.2.12.Final\hibernate-release-5.2.12.Final\lib\required目錄下的全部jar包拷貝到WEB-INF/lib目錄下魂奥,并且都添加到build path中。
??將...\hibernate-release-5.2.12.Final\hibernate-release-5.2.12.Final\lib\optional\c3p0目錄下的所有jar文件拷貝到WEB-INF/lib下易猫,并添加都build path耻煤。
??在這里,不要忘了還有兩個需要導(dǎo)入的jar包准颓。一個是AspectJ包违霞,下載地址:https://www.eclipse.org/aspectj/downloads.php。Spring的AOP需要依賴這個包瞬场。另外一個是MySql的驅(qū)動JDBC Driver for MySQL 买鸽,下載地址:https://www.mysql.com/products/connector/
??安裝MySql贯被,此處不做相信說明眼五,自行百度妆艘。
??在MySql的test數(shù)據(jù)庫下創(chuàng)建tb_employee表,通過下面的sql創(chuàng)建

CREATE TABLE `tb_employee` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `firstName` varchar(32) NOT NULL DEFAULT '',
  `lastName` varchar(32) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=105 DEFAULT CHARSET=utf8

??創(chuàng)建com.xxx.dao包看幼,創(chuàng)建BaseDao接口:

package com.xxx.dao;

import java.io.Serializable;
import java.util.List;

public interface BaseDao<T> {

    /**
     * 根據(jù)實體加載數(shù)據(jù)
     * @param entityClazz
     * @param id
     * @return
     */
    T get(Class<T> entityClazz,Serializable id);
    /**
     * 保存實體
     * @param entity
     * @return
     */
    Serializable save(T entity);
    /**
     * 更新實體
     * @param entity
     */
    void update(T entity);
    /**
     * 刪除實體
     * @param entity
     */
    void delete(T entity);
    /**
     * 根據(jù)ID刪除實體
     * @param entityClazz
     * @param id
     */
    void delete(Class<T> entityClazz,Serializable id);
    /**
     * 獲取所有實體
     * @param entityClazz
     * @return
     */
    List<T> findAll(Class<T> entityClazz);
    /**
     * 獲取實體總數(shù)
     * @param entityClazz
     * @return
     */
    long findCount(Class<T> entityClazz);
}

??創(chuàng)建BaseDaoHibernate3

package com.xxx.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;

public class BaseDaoHibernate3<T> implements BaseDao<T> {
    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public T get(Class<T> entityClass, Serializable id) {
        return getSessionFactory().getCurrentSession().get(entityClass, id);
    }

    @Override
    public Serializable save(T entity) {
        SessionFactory sf = getSessionFactory();
        @SuppressWarnings("unused")
        Session s = sf.getCurrentSession();
        return getSessionFactory().getCurrentSession().save(entity);
    }

    @Override
    public void update(T entity) {
        getSessionFactory().getCurrentSession().update(entity);
    }

    @Override
    public void delete(T entity) {
        getSessionFactory().getCurrentSession().delete(entity);
    }

    @Override
    public void delete(Class<T> entityClass, Serializable id) {
        getSessionFactory().getCurrentSession()
                .createQuery("delet " + entityClass.getSimpleName() + " en where en.id=?0").setParameter(0, id)
                .executeUpdate();
    }

    @Override
    public List<T> findAll(Class<T> entityClass) {
        return (List<T>) find("select en from " + entityClass.getSimpleName() + " en");
    }

    @SuppressWarnings("unchecked")
    @Override
    public long findCount(Class<T> entityClass) {
        List<Long> list = (List<Long>) find("select count(*) from " + entityClass.getSimpleName() + " en");

        if (list != null && list.size() == 1) {
            return (long) list.get(0);
        }
        return 0;
    }

    /**
     * 分頁查詢
     * 
     * @param hql
     * @param pageNo
     * @param pageSize
     * @return
     */
    @SuppressWarnings("unchecked")
    protected List<T> findBypage(String hql, final int pageNo, final int pageSize) {
        List<T> list = getSessionFactory().getCurrentSession().createQuery(hql).setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize).list();

        return list;

    }

    /**
     * 帶占位符的分頁查詢
     * 
     * @param hql
     * @param pageNo
     * @param pageSize
     * @param params
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected List<T> findBypage(String hql, int pageNo, int pageSize, Object... params) {
        Query query = getSessionFactory().getCurrentSession().createQuery(hql);

        for (int i = 0; i < params.length; i++) {
            query.setParameter(i, params[i]);
        }
        return query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
    }

    @SuppressWarnings("unchecked")
    protected List<T> find(String hql) {
        return getSessionFactory().getCurrentSession().createQuery(hql).list();

    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected List<T> find(String hql, Object... paramas) {
        Query query = getSessionFactory().getCurrentSession().createQuery(hql);
        for (int i = 0; i < paramas.length; i++) {
            query.setParameter(i, paramas[i]);
        }

        return query.list();
    }
}

??創(chuàng)建BaseDaoHibernate4

package com.xxx.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

public class BaseDaoHibernate4<T> extends HibernateDaoSupport implements BaseDao<T>{
    


    @Override
    public T get(Class<T> entityClass, Serializable id) {
        return getHibernateTemplate().get(entityClass, id);
    }

    @Override
    public Serializable save(T entity) {
        return getHibernateTemplate().save(entity);
    }

    @Override
    public void update(T entity) {
        getHibernateTemplate().update(entity);
    }

    @Override
    public void delete(T entity) {
        getHibernateTemplate().delete(entity);
    }

    @Override
    public void delete(Class<T> entityClass, Serializable id) {
        getHibernateTemplate().delete(get(entityClass, id));
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> findAll(Class<T> entityClass) {
        return (List<T>) getHibernateTemplate().find("select en from " + entityClass.getSimpleName() + " en");
    }

    @SuppressWarnings("unchecked")
    @Override
    public long findCount(Class<T> entityClass) {
        List<Long> list = (List<Long>) getHibernateTemplate().find("select count(*) from " + entityClass.getSimpleName()+" en");
        
        if (list != null && list.size() == 1) {
            return (long) list.get(0);
        }
        return 0;
    }


    /**
     * 分頁查詢
     * 
     * @param hql
     * @param pageNo
     * @param pageSize
     * @return
     */
    @SuppressWarnings("unchecked")
    protected List<T> findBypage(final String hql,final int pageNo,final int pageSize) {
        List<T> list =  getHibernateTemplate().execute(new HibernateCallback<List<T>>() {

            @Override
            public List<T> doInHibernate(Session session) throws HibernateException {
                List<T> result = session.createQuery(hql).setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize).list();
                return result;
            }
        });

        return list;

    }

    /**
     * 帶占位符的分頁查詢
     * 
     * @param hql
     * @param pageNo
     * @param pageSize
     * @param params
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected List<T> findBypage(final String hql, final int pageNo, final int pageSize, final Object... params) {
        List<T> list = getHibernateTemplate().execute(new HibernateCallback<List<T>>() {

            @Override
            public List<T> doInHibernate(Session session) throws HibernateException {
                Query query = session.createQuery(hql).setFirstResult((pageNo - 1)*pageSize)
                        .setMaxResults(pageSize);
                
                for (int i = 0; i < params.length; i++) {
                    query.setParameter(i, params[i]);
                }
                 List<T> result = query.list();
                return result;
            }
        });
        return list;
    }
}

??創(chuàng)建實體類Employee

package com.xxx.dao;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tb_employee")
public class Employee {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @Column(name = "firstName")
    private String firstName;
    @Column(name = "lastName")
    private String lastName;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

?emsp;創(chuàng)建EmployeeDao

package com.xxx.dao;

public interface EmployeeDao extends BaseDao<Employee>{

}

這個接口看似沒用批旺,其實暗藏玄機。如果EmployeeDao 有它特定的業(yè)務(wù)時诵姜,可以寫在這個接口中汽煮,一方面滿足面向接口編程的原則,一方面又不污染BaseDao接口棚唆。
??創(chuàng)建EmployeeDaoHibernate

package com.xxx.dao;


public class EmployeeDaoHibernate extends BaseDaoHibernate3<Employee> implements EmployeeDao{
    
}
 

項目結(jié)構(gòu)截圖:


image.png

??BaseDaoHibernate3和BaseDaoHibernate4是兩種不同是實現(xiàn)暇赤,更推薦前者,因為前者的代碼污染更小宵凌。
??現(xiàn)在來添加一個Action:EmployeeAction鞋囊。用于響應(yīng)添加Employee請求。

package com.xxx.action;


import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.ActionSupport;
import com.xxx.dao.Employee;
import com.xxx.service.EmployeeService;

public class EmployeeAction extends ActionSupport {
    @Autowired
    private EmployeeService employeeService;
    private String firstName, lastName;
    private Employee employee;
    

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public EmployeeService getEmployeeService() {
        return employeeService;
    }

    public void setEmployeeService(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    /**
     * 
     */
    private static final long serialVersionUID = -8442995807620521709L;

    @Override
    public String execute() throws Exception {
        Employee employee = new Employee();
//      System.out.println(firstName+lastName);
        employee.setFirstName(firstName);
        employee.setLastName(lastName);
        employeeService.add(employee);
//      System.out.println(id);
        return super.execute();
    }
}

??這個action中真正進行數(shù)據(jù)存儲的是EmployeeService瞎惫,于是接著創(chuàng)建EmployeeService接口和實現(xiàn)類溜腐,實現(xiàn)添加和獲取兩個方法:
EmployeeService

package com.xxx.service;

import java.io.Serializable;

import com.xxx.dao.Employee;

public interface EmployeeService {
    Serializable add(Employee employee);
    Employee get(Serializable id);
}

EmployeeServiceImpl

package com.xxx.service;

import java.io.Serializable;

import com.xxx.dao.Employee;
import com.xxx.dao.EmployeeDao;

public class EmployeeServiceImpl implements EmployeeService {
    private EmployeeDao employeeDao;
    
    

    public EmployeeDao getEmployeeDao() {
        return employeeDao;
    }

    public void setEmployeeDao(EmployeeDao employeeDao) {
        this.employeeDao = employeeDao;
    }

    public Serializable add(Employee employee) {
        return employeeDao.save(employee);
    }

    public Employee get(Serializable id) {
        return employeeDao.get(Employee.class, id);
    }

}

??好了,代碼已寫完瓜喇,下面就來配置挺益。
??首先配置applicationContext:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.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">

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!--基于 <tx> 和 <aop> 命名空間的聲明式事務(wù) -->
    <!-- 配置事務(wù)傳播特性 -->
    <tx:advice id="TestAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" />
            <tx:method name="*" isolation="DEFAULT" propagation="REQUIRED"
                timeout="5" />
        </tx:attributes>
    </tx:advice>

    <tx:annotation-driven />

    <!-- 配置參與事務(wù)的類 -->
    <aop:config>
        <aop:pointcut id="allTestServiceMethod" expression="bean(employeeService)" />
        <aop:advisor pointcut-ref="allTestServiceMethod"
            advice-ref="TestAdvice" />
    </aop:config>




    <!-- *********************************************************** -->

    <!-- hibernate 配置 -->
    <!-- 定義數(shù)據(jù)源bean 使用c3p0數(shù)據(jù)源 并注入相關(guān)參數(shù) -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close" p:driverClass="com.mysql.jdbc.Driver"
        p:jdbcUrl="jdbc:mysql://localhost/test?useSSL=false" p:user="root"
        p:password="194061" p:maxPoolSize="40" p:minPoolSize="2"
        p:initialPoolSize="2" p:maxIdleTime="30" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
        p:dataSource-ref="dataSource">

        <!--annotateClasses用來列出所有持久化類 -->
        <property name="annotatedClasses">
            <list>
                <value>com.xxx.dao.Employee</value>
            </list>
        </property>

        <!-- 定義hibernate sessionFactory的屬性 -->
        <property name="hibernateProperties">
            <props>
                <!-- 定義hibernate方言 -->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <!-- 是否根據(jù)hibernate映射創(chuàng)建數(shù)據(jù)表 -->
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>
    <!-- ************************************************************* -->


    <bean id="employeeService" class="com.xxx.service.EmployeeServiceImpl"
        scope="prototype">
        <property name="employeeDao" ref="employeeDao"></property>
    </bean>

    <bean id="employeeDao" class="com.xxx.dao.EmployeeDaoHibernate">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    
    <bean id="employeeAction" scope="prototype" class="com.xxx.action.EmployeeAction">
        <property name="employeeService" ref="employeeService"></property>
    </bean>

    <bean id="loginService" class="com.xxx.service.LoginServiceImpl" />

    <bean id="loginAction" scope="prototype" class="com.xxx.action.LoginAction">
        <property name="loginService" ref="loginService"></property>
    </bean>

</beans>

??配置struts.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <!-- <constant name="struts.objectFactory" value="spring" /> <constant name="struts.devMode" 
        value="true" /> -->
    <package name="xxx" extends="struts-default" namespace="/">
        <action name="login" class="loginAction">
            <result name="success">/WEB-INF/content/success.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>

        <action name="employee" class="employeeAction">
            <result name="success">/WEB-INF/content/success.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>
    </package>
</struts>    

??在login.jsp中添加一個表單用于測試hibernate整合是否成功:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'login.jsp' starting page</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">

  </head>
  
  <body>
    <form action="login.action">
        用戶名:<input type="text" name="userName"><br>
        密碼: <input type="password" name="password"><br>
        <input type="submit" value="登錄">
    </form>
  </body>
  <br>
  <form action="employee.action">
    FristName:<input type="text" name="firstName"/> <br>
    LastName:<input type="text" name="lastName"><br>
    <input type="submit" value="add">
  </form>
</html>

??到這里就算整合成功了,最后的項目結(jié)構(gòu)如圖:


image.png
image.png

??啟動服務(wù)器乘寒,輸入firstName矩肩、lastName,點擊add會跳轉(zhuǎn)到成功頁面,打開MySQL Workbench查看tb_employee表的記錄可以看到已添加的數(shù)據(jù):

image.png

最后附上項目下載地址:https://github.com/xudefei/WebTest

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肃续,一起剝皮案震驚了整個濱河市黍檩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌始锚,老刑警劉巖刽酱,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瞧捌,居然都是意外死亡棵里,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門姐呐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來殿怜,“玉大人,你說我怎么就攤上這事曙砂⊥访眨” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵鸠澈,是天一觀的道長柱告。 經(jīng)常有香客問我截驮,道長,這世上最難降的妖魔是什么际度? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任葵袭,我火速辦了婚禮,結(jié)果婚禮上乖菱,老公的妹妹穿的比我還像新娘坡锡。我一直安慰自己,他們只是感情好窒所,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布鹉勒。 她就那樣靜靜地躺著,像睡著了一般墩新。 火紅的嫁衣襯著肌膚如雪贸弥。 梳的紋絲不亂的頭發(fā)上窟坐,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天海渊,我揣著相機與錄音,去河邊找鬼哲鸳。 笑死臣疑,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的徙菠。 我是一名探鬼主播讯沈,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼婿奔!你這毒婦竟也來了缺狠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤萍摊,失蹤者是張志新(化名)和其女友劉穎挤茄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冰木,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡穷劈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了踊沸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歇终。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逼龟,靈堂內(nèi)的尸體忽然破棺而出评凝,到底是詐尸還是另有隱情,我是刑警寧澤腺律,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布肥哎,位于F島的核電站辽俗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏篡诽。R本人自食惡果不足惜崖飘,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杈女。 院中可真熱鬧朱浴,春花似錦、人聲如沸达椰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽啰劲。三九已至梁沧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝇裤,已是汗流浹背廷支。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留栓辜,地道東北人恋拍。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像藕甩,于是被迫代替她去往敵國和親施敢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容