歡迎光臨
每天分享高質量文章

通向架構師的道路(第二十一天)萬能框架 Spring ( 三 ) 之 SSH

(點選上方公眾號,可快速關註)


來源:袁鳴凱,

blog.csdn.net/lifetragedy/article/details/8173933

一、前言

我們有了Spring+JdbcTemplate和Spring+iBatis並結合maven的基礎,搭建一個SSX這樣的框架現在就和玩一樣的簡單了,今天我們將搭建一個使用Struts1.3,Srping3, Hibernate3的SSH1的開發框架,大家跟著我一步步走,會發覺在程式跑通後自己再動手搭建一遍這個框架,只需要30分鐘。

二、SSH框架

仔細看這個框架,稍微有點不一樣了。

1) Spring3是透過一個hibernate template來和hibernate的dao層結合起來並且管理起hibernate的相關事務的。因此我們自己寫了一個BaseHibernateDaoSupport來用spring統一管理hibernate的事務。

2) Hibernate和Spring的結合非常方便,我們只需要寫一個hibernate.xml就可以了,datasource.xml中把原先的iBatis的相關配置全部去掉它,什麼都不需要加事務還是維持原有的配置不變即可,對於我們來說需要改動的是dao層,還有把service層稍微做些小調整(一兩句話的調整,非常簡單),可能是我看到過的最簡單的一種SSX的結合方式,遠比iBatis和spring的結合要easy多了。

3) Hibernate3開始可以使用jpa或者還是傳統的hbm.xml檔案這樣的描述方式,在此我們堅持使用JPA的Annotation方式來宣告我們的model而不是使用*.hbm.xml這樣的方式。

註意:所有的包(package name)都要從原來的org.sky.ssi變成org.sky.ssh嘍?

三、搭建SSH框架

3.1建立工程

我們還是使用maven來建立我們的工程,我們工程的名字叫myssh。

建完後照著翻外篇《第十九天》中的“四、如何讓Maven構建的工程在eclipse裡跑起來”對工程進行設定。

3.2 maven庫設定

嘿嘿嘿嘿,不需要任何設定,直接把beta工程中的pom.xml檔案複製入myssh工程中就可以用了,裡面相關的spring,struts, hibernate的包我都已經事先配合了。

如果你是個圖完美的的,你可以把pom.xml檔案中的iBatis相關的jar給去除。

3.3 開始配置Hibernate與spring結合

開啟/src/main/resources/spring/datasource下的datasource.xml,把所有的關於iBatis的設定全部去除,把org.sky.ssi這樣的包名全部改成org.sky.ssh。

我們在myssh工程中需要增加一個工具類,一個xml和幾個用到的hibernate的model的對映,下麵來看。

src/main/resources/spring/hibernate/hibernate.xml檔案

我們在src/main/resources/spring目錄下增加一個目錄叫hibernate,在這個hibernate目錄下我們建立一個hibernate.xml檔案。

其內容如下:

 

 

    xmlns:p=”http://www.springframework.org/schema/p” 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-3.0.xsd

 

 

http://www.springframework.org/schema/beans

 

 

http://www.springframework.org/dtd/spring-beans.dtd”>

 

 

 

     class=”org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean”>

 

     

 

       

 

           

 

       

 

       

 

           

 

                org.sky.ssh.model.TLogin      org.sky.ssh.model.TStudent                                                                                           

           

 

       

 

           

 

           

 

               org.hibernate.dialect.Oracle9Dialect

 

               true

 

               true

 

               auto

 

               true

 

               update

 

                true

 

           

 

       

 

     

 

這句就是代表所有的hibernate的sessionFactory自動被註入到我們的myssh工程的dao層中去,即在dao層中我們只要透過BaseHibernateDaoSupport.getSession()就可以進行相關的hibernate的資料庫操作了.

我們還註意到了在src/main/resources/spring/hibernate/hibernate.xml檔案中有這樣的hibernate的model的對映:

   

    org.sky.ssh.model.TLogin

    org.sky.ssh.model.TStudent                                                       

   

這就是基於annotation的jpa的hibernate的model層的寫法,這邊的幾個括起來的東西就是一個個java的.class,這些java檔案都是基於jpa的annotation寫法。

當然,如果表結構簡單,你可以直接手寫這些java類,但是如果一個表結構很複雜,幾十個欄位主鍵還有組合主鍵這樣的形式存在,那麼手寫這個jpa就會變得有點困難。

一般我們在開發專案時都是透過先建表,再建類的,對吧?

因此在這裡我們其實是可以藉助相關的工具透過資料庫表來生成我們的hibernate的這些model類的。

利用eclipse從表逆向生成java的jpa(hibernate)類

準備工作

  1. 必須要有eclipse3.7及升級後的database, jpa feature,如:eclipse wtp版

  2. 建立資料源

根據下麵操作,請切換到j2ee檢視,然後先開啟datasource explorer視窗

下一步

點右上面這個黑白色(黑白配,男生女生配,啊我呸!)的圓形pie一樣的這個按鈕

填入自定義的oracledriver名

點JARList這個tab(需要載入一個oracle的driver,即ojdbc6.jar)

可以去oracleclient端安裝的路徑的jdbc\lib中找到該JAR,註意上圖中兩個紅圈處標出的路徑與jar名

點OK傳回下麵這個對話方塊

填入servername, username, password等資訊,你懂的(別忘了勾上save password)

選TestConnection

點OK,NEXT, FINISH完成

看,這邊一下子把所有的schema都列出來了,但是我們知道oracle的schema就是username,因此我們用bookstore(這個只是示例,這邊因該用你連線資料庫的username)的schema只需要顯示bookstore的相關資料庫object就夠我們用了。

看,右鍵點選你的connection選Properties然後在下麵的對話方塊中選DefaultSchema Filter

在上面的對話方塊中把Disablefilter放開,然後在Startswith the characters填入你的oracle使用者名稱(schema名),必須大寫。

點OK

傳回後右鍵點connection選Refresh,看,是不是隻列出來就是你要的東西了(相當於pl/sql裡從all objects切換成my objects)

這個東西還可以在沒有安裝oracle客戶端的情況下,拿ECLIPSE來當oracle的客戶端用。

建立JPA(Hibernate)工程

在hibernate3裡我們把hibernate的annoation方式稱為全註解即JPA,因此我們不需要使用hibernate3以前的那種xml檔案的配置的方式。

新建JPA工程

這邊我們使用的工程名為myssh_model

工程名起名規範,比如說你的工程叫MyProject,那麼你的HIBERNATE是ForMyProject工程的,因此你的hibernate即JPA工程就應該叫MyProject_model

根據上圖勾選後NEXT,NEXT到下麵這一步(千萬不要手快然後直接去點那個FINISH按鈕啊,我們還沒完呢)

根據上圖勾選

點FINISH

在彈出框時選Yes

生成的JPA工程

右鍵單擊工程,在JPATools裡選GenerateEntities from Tables,這個你懂的。。。

下麵,靈的東西要來了。。。

點一下Connection下的這個有“黃色鉸鏈”的按鈕(connection),這時下方的下拉串列會顯示你當前的jpa工程使用的dbconnection中的Table,看到米有?

註意,把這個Updateclass list in persistence.xml去掉,因為我們用的是純annotation,不希望再用xml配置方式了,要不然生成出來的工程會出錯的,點Next

如果表與表之間有foreignkey的關係,它都能幫你識別出來

Next

保持所有的CLASS的主鍵為none,我們在後面為每個表分別指定主鍵的形勢,因為有些主鍵是用的是sequence,有的主鍵是要透過介面手輸進來的,不是sequence,有的主鍵甚至是複合主鍵。

別忘了把package填上,註意package的命名規範(規則)養成良好習慣

點NEXT

下麵為每個CLASS指定主鍵的生成方式。

對於T_LOGIN表來說我們的PK讓它保持為預設。

對於T_STUDENT表來說,我們的主鍵是用一個oracle的 sequence來生成的,這個oracle的sequence命為:

因此當你為一個jpa指定了sequence的PK時,在做插入動作時,該表的PK會自動從在這一步指定的sequence中去讀取nextval值,相當於執行了一步:select  SEQ_STUDENT_NO.nextval from dual;這樣的操作.

把每個JPA的主鍵指定完畢後可以點Finish了

Look,快來看上帝哦,JPA類被自動生成了,但編譯有問題,因為我們沒有給工程指定lib包,jpa工程需要用到以下lib包

我已經同時上傳到我的部落格的資源上了。

於是,在工程下建一個檔案夾叫lib,把這些jar全放lib目錄裡然後加入classpath

編譯透過後,我們就可以把這些java拷入我們需要用到hibernate工程的project裡了,拷進去後別忘了改一處地方:

以下是我原有工程中有一個jpa,因此我在spring/hibernate/hibernate.xml檔案中需要把一個jpa納入spring的管理,但現在我拷進去一堆jpa都要納入spring管理,怎麼辦?就是把這個檔案開啟,找到

然後看到了嗎?自己把一個個JPA加進去吧,然後就可以去爽了。

 

   

 

        org.sky.ssh.model.TLogin

 

        org.sky.ssh.model.TStudent                                                 

 

   

 

org.sky.ssh.dao.BaseHibernateDaoSupport.java檔案

package org.sky.ssh.dao;

 

import javax.annotation.Resource;

import org.hibernate.SessionFactory;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

 

public class BaseHibernateDaoSupport extends HibernateDaoSupport {

 

    @Resource(name = “hibernateSessionFactory”)

 

    public void setSF(SessionFactory sessionFactory) {

 

        super.setSessionFactory(sessionFactory);

    }

}

四、SSH框架的使用

我們現在可以開始使用我們的SSH框架了。

4.1修改DAO層程式碼

org.sky.ssh.dao.LoginDAO

package org.sky.ssh.dao;

 

public interface LoginDAO {

 

    public long validLogin(String loginId, String loginPwd) throws Exception;

 

}

org.sky.ssh.dao.impl.LoginDAOImpl

package org.sky.ssh.dao.impl;

 

import org.sky.ssh.dao.BaseHibernateDaoSupport;

import org.sky.ssh.dao.LoginDAO;

import org.springframework.stereotype.Repository;

import org.hibernate.Query;

 

@Repository

 

public class LoginDAOImpl extends BaseHibernateDaoSupport implements LoginDAO {

 

    public long validLogin(String loginId, String loginPwd) throws Exception {

 

        Long count = new Long(0);

 

        String sql = “select count(tl.loginId) from TLogin as tl where tl.loginId=:loginId and tl.loginPwd=:loginPwd “;

 

        Query query = super.getSession().createQuery(sql);

 

        query.setString(“loginId”, loginId);

 

        query.setString(“loginPwd”, loginPwd);

 

        count = (Long) query.list().get(0);

 

        return count;

 

    }

}

org.sky.ssh.dao.StudentDAO

package org.sky.ssh.dao;

 

import org.sky.ssh.model.TStudent;

import org.sky.ssh.dbo.StudentDBO;

import org.sky.ssh.student.form.*;

import java.util.*;

 

public interface StudentDAO {

 

    public List getAllStudent() throws Exception;

    public void addStudent(String studentName) throws Exception;

    public void delStudent(TStudent std) throws Exception;

 

}

org.sky.ssh.dao.impl.StudentDAOImpl

package org.sky.ssh.dao.impl;

 

import java.util.ArrayList;

import java.util.List;

import org.hibernate.Query;

import org.sky.ssh.dao.BaseHibernateDaoSupport;

import org.sky.ssh.dao.StudentDAO;

import org.sky.ssh.model.TStudent;

import org.springframework.stereotype.Repository;

 

@Repository

public class StudentDAOImpl extends BaseHibernateDaoSupport implements StudentDAO {

 

    public List getAllStudent() throws Exception {

                    List stdList = new ArrayList();

                    String sql = “from TStudent as s”;

                    Query query = super.getSession().createQuery(sql);

                    stdList = query.list();

                    return stdList;

 

    }

 

 

    public void addStudent(String studentName) throws Exception {

 

                    TStudent std = new TStudent();

                    std.setStudentName(studentName);

                    this.getHibernateTemplate().save(std);

 

    }

 

 

 

    public void delStudent(TStudent std) throws Exception {

                    this.getHibernateTemplate().delete(std);

    }

}

對Service層的介面作相應的調整,把原來在iBatis中使用Map傳值的地方改一下即可,對吧?

Hibernate的DAO是我看到過的最簡單的DAO寫法,連腦子都不需要多動。

4.2 啟動我們的框架

確保我們的StudentServiceImpl類中有如下陳述句:

public void delStudent(String[] stdNo) throws Exception {

 

    for (String s : stdNo) {

 

        TStudent std = new TStudent();

 

        std.setStudentNo(Long.parseLong(s));

 

        studentDAO.delStudent(std);

 

        throw new Exception(“force system to throw a exception”);

 

    }

}

在eclipse中啟動tomcat

在IE中輸入:http://localhost:8080/myssh/,頁面自動跑到登入介面

輸入alpha/aaaaaa登入成功後我們增加兩個使用者:test2與test3

在主介面上勾選test2與test3點刪除按鈕。

頁面出錯

看資料庫層面

資料記錄還在,說明我們的springservice層與hibernatedao層已經結合成功。

在StudentServiceImpl類中將:throw new Exception(“force system to throw a exception”);這句註釋掉.

重新啟動tomcat後登入並勾選test2與test3,然後點刪除按鈕.

刪除成功。

檢視資料庫層記錄

 

資料刪除也成功了,結束今天的教程。

五、附錄

系列


看完本文有收穫?請轉發分享給更多人

關註「ImportNew」,提升Java技能

贊(0)

分享創造快樂