通向架構師的道路(第二十一天)萬能框架 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文件。
其內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan" value="org.sky.ssh.dao.impl.*.*" />
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="annotatedClasses">
<list>
<value>org.sky.ssh.model.TLogin</value> <value>org.sky.ssh.model.TStudent</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
<prop key="hibernate.autoReconnect">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.autocommit">true</prop>
</props>
</property>
</bean>
</beans>
<property name=」packagesToScan」value=」org.sky.ssh.dao.impl.*.*」 />
這句就是代表所有的hibernate的sessionFactory自動被注入到我們的myssh工程的dao層中去,即在dao層中我們只要通過BaseHibernateDaoSupport.getSession()就可以進行相關的hibernate的資料庫操作了.
我們還注意到了在src/main/resources/spring/hibernate/hibernate.xml文件中有這樣的hibernate的model的映射:
<property name="annotatedClasses">
<list>
<value>org.sky.ssh.model.TLogin</value>
<value>org.sky.ssh.model.TStudent</value>
</list>
</property>
這就是基於annotation的jpa的hibernate的model層的寫法,這邊的幾個<value>括起來的東西就是一個個java的.class,這些java文件都是基於jpa的annotation寫法。
當然,如果表結構簡單,你可以直接手寫這些java類,但是如果一個表結構很複雜,幾十個欄位主鍵還有組合主鍵這樣的形式存在,那麼手寫這個jpa就會變得有點困難。
一般我們在開發項目時都是通過先建表,再建類的,對吧?
因此在這裡我們其實是可以藉助相關的工具通過資料庫表來生成我們的hibernate的這些model類的。
利用eclipse從表逆向生成java的jpa(hibernate)類
準備工作
必須要有eclipse3.7及升級後的database, jpa feature,如:eclipse wtp版
建立數據源
根據下面操作,請切換到j2ee視圖,然後先打開datasource explorer窗口
下一步
點右上面這個黑白色(黑白配,男生女生配,啊我呸!)的圓形pie一樣的這個按鈕
填入自定義的oracledriver名
點JARList這個tab(需要載入一個oracle的driver,即ojdbc6.jar)
可以去oracleclient端安裝的路徑的jdbclib中找到該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管理,怎麼辦?就是把這個文件打開,找到
<property name=」annotatedClasses」>處
然後看到<List><value>了嗎?自己把一個個JPA加進去吧,然後就可以去爽了。
<property name="annotatedClasses">
<list>
<value>org.sky.ssh.model.TLogin</value>
<value>org.sky.ssh.model.TStudent</value>
</list>
</property>
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<TStudent> 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<TStudent> getAllStudent() throws Exception {
List<TStudent> stdList = new ArrayList<TStudent>();
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,然後點刪除按鈕.
刪除成功。
查看資料庫層記錄
數據刪除也成功了,結束今天的教程。
五、附錄
系列
通向架構師的道路(第一天)之 Apache 整合 Tomcat
通向架構師的道路(第二天)之 apache tomcat https 應用
通向架構師的道路(第三天)之 apache 性能調優
通向架構師的道路(第四天)之 Tomcat 性能調優
通向架構師的道路(第五天)之 tomcat 集群 – 群貓亂舞
通向架構師的道路(第六天)之漫談基於資料庫的許可權系統的設計
通向架構師的道路(第七天)之漫談使用 ThreadLocal 改進你的層次的劃分
通向架構師的道路(第八天)之 Weblogic 與 Apache 的整合與調優
通向架構師的道路(第九天)之 Weblogic 的集群與配置
通向架構師的道路 ( 第十天 ) 之 Axis2 Web Service ( 一 )
通向架構師的道路 ( 第十一天 ) 之 Axis2 Web Service ( 二 )
通向架構師的道路 ( 第十二天 ) 之 Axis2 Web Service ( 三 )
通向架構師的道路 ( 第十三天 ) Axis2 Web Service 安全初步
通向架構師的道路 ( 第十四天 ) Axis2 Web Service 安全之 rampart
通向架構師的道路 ( 第十五天 ) IBM Websphere 的安裝與優化
通向架構師的道路 ( 第十六天 ) IBM Websphere 與 IBM HttpServer 的集成
通向架構師的道路 ( 第十七天 ) IBM Websphere 集群探秘 – WASND
通向架構師的道路(第十八天)萬能框架 Spring ( 一 )
通向架構師的道路(第二十天)萬能框架spring (二)
看完本文有收穫?請轉發分享給更多人
關注「ImportNew」,提升Java技能
TAG:ImportNew |