在Eclipse下手動搭建SSH框架,並使用Hibernate外掛反向生成實體類和關係對映檔案。
寫在前面:
接觸SSH框架有一段時間了。在整合實戰的過程中遇到了各種各樣的問題,最後都一一解決了。
下面記錄一個SSH框架整合實戰的小演示,這個演示旨在記錄學習SSH框架的艱辛過程。
重點知識:
1,在Eclipse中下手動搭建SSH框架,並把SessionFactory的交由春天來管理。
2,使用休眠外掛反向生成實體類和關係對映檔案。
3,學習SSH框架整合的基本架構。
測試環境:
jdk 1.8.0_74
tomcat 8.0
日食霓虹燈
struts2 2.3.4.1
春天3.2.1
休眠4.1.9
一,建立一個動態的網路專案:
開啟Eclipse,檔案>新建>動態Web專案(如果此處沒有Dynamic Web Project選項的話,在最下方的其他選項裡搜尋一下它就有了)
填寫好專案名稱之後,記得選擇目標執行時為Apache Tomcat v8.0,這裡就用web3.1的版本進行測試吧。點選下一步>
點選下一步>
記得這裡一定要勾選生成web.xml部署描述符選項生成web.xml檔案。點選完成>
這樣我們的專案就基本建立完畢了,大致的目錄結構如下圖:
二,複製SSH框架整合所必需的核心罐包到WEB-INF / lib中資料夾下:
全選複製上圖中所有的JAR包,貼上到下圖中的LIB資料夾下,如圖所示:
三,複製SSH框架所必需的配置檔案到的src資料夾下:
全選複製上圖中所有的配置檔案,貼上到下圖中的SRC資料夾中,如圖所示:
這裡需要說明一點,因為我們把SessionFactory的交由春天來管理了,所以applicationContext.xml的檔案也就取代了hibernate.cfg.xml的檔案,那麼這裡不需要再建立hibernate.cfg.xml的檔案。
四,在WEB-INF / web.xml檔案檔案中配置的Struts2的核心過濾器和彈簧的監聽器:
這裡需要說明一點,因為我們把applicationContext.xml檔案放在了src資料夾下,所以這裡<param-value>classpath:applicationContext.xml</param-value>標籤的classpath:就說明預設去src資料夾下讀取配置檔案。假設我們把applicationContext.xml檔案放在了WEB-INF資料夾下,那麼這裡的標籤內容就要修改為<param-value>WEB-INF/applicationContext.xml</param-value>,這裡需要注意。
這樣我們的SSH框架整合的Demo就建立完畢了。
五、建立資料表結構,並配置資料庫連線引數:
這個小Demo要實現一個搜尋的功能,主要需求如下:
1、實現通過作者搜尋該作者的所有作品。
2、實現詩詞名稱搜尋唐詩全文並顯示。
3、實現通過詩歌的名句搜尋該唐詩的作者、題目和全文。
下面先使用SQLyog工具建立資料表結構。這裡需要說明一點,由於我們後期會使用Hibernate外掛反向生成實體類和關係對映檔案,所以在這裡建立資料庫表結構的時候,鍵與鍵之間關係的正確配置決定了以後反向生成實體類和關係對映檔案的成敗。
資料庫結構如下圖所示,資料庫名稱為tangshi,注意為了防止後期出現中文亂碼,這裡應當設定字元編碼集為utf-8,有兩張資料表分別為:poets、poetries。主鍵id與poet_id有一個關係,這個配置很重要。
資料表結構建立完成以後,我們開啟Eclipse配置資料庫連線引數,Windows>Data Source Explorer,如下圖所示:
在Data Source Explorer視窗中滑鼠右擊選擇new,新建一個數據庫連線。資料庫型別選擇MySQL,name可以自行設定,這裡設定為DemoMySQL。如下圖所示:
點選下一步>,此處點選新驅動程式定義按鈕,新增一個數據庫連線驅動,如下圖所示:
名稱/型別這裡選擇MySQL5.1版本,JAR列表這裡點選新增JAR / ZIP新增一個MySQL的JDBC驅動,屬性這裡配置資料庫連線引數,如下圖所示:
點選OK>,這裡說明一點,如圖所示最下方有兩個選項。第一個選項的意思是在配置完資料庫連線引數以後馬上連線到資料庫,第二個選項的意思是在每次啟動的Eclipse的時候自動連線到資料庫這裡自行設定,如下圖所示:
再檢查一下,確認無誤以後點選完成>,如下圖所示是我們建立好的資料庫連線,依次展開圖示的目錄就可以看到我們事先建立好的資料表結構了:
六,使用Hibernate的外掛反向生成實體類和關係對映檔案:
在Eclipse下載JBoss-Tools外掛,開啟Eclipse,幫助> Eclipse Marketplace,在搜尋框裡輸入JBoss-Tools敲回車進行搜尋,得到結果,如下圖所示:
點選安裝進行安裝。預設下載JBoss-Tools全部的外掛即可,這個過程中會彈出一個詢問是否同意載入的介面,點選我接受,然後一直點選OK直到Eclipse自動重啟即可。
安裝完成後我們依次點選Windows>顯示檢視>其他,在搜尋框裡輸入Hibernate進行搜尋,開啟Hibernate配置視窗,如圖所示:
在Hibernate配置視窗中新建一個Hibernate配置,右鍵選擇新增Configuration.Main這裡設定Hibernate Version為4.0,Project為Demo,資料庫連線為DemoMySQL.Options這裡設定資料庫方言為MySQL,然後點選OK。如下圖所示:
這時我們的Hibernate Configuration窗口裡會多出一個配置,依次展開圖示的目錄就可以看到我們事先建立好的資料表結構了:
接下來我們在工具欄中新增Hibernate按鈕,開啟Eclipse,Windows>Perspective>Customize Perspective,在Action Set Availability選項卡中找到並勾選Hibernate Code Generation按鈕,點選OK。如下圖所示:
這時我們的工具欄就會出現一個與Hibernate相關的按鈕,點選Hibernate Code Generation Configuration選項,在彈出的選單中按如下圖所示的方法依次選擇Main、Exporters、Common進行配置。
這裡說明一點,在reveng.xml選項卡中,需要點選Setup新建一個hibernate.reveng.xml檔案,儲存檔案的目錄選擇對應工程下的src資料夾,如下圖所示:
點選Next>,這裡說明一點,在Datebase schema選項卡的下方點選Refresh按鈕,會刷新出所有的資料表。
依次選定資料表並點選Include按鈕將其新增到Table filters選項卡中,如下圖所示:
點選Finish>,Common選項卡的設定如下圖所示,點選Run>
這時我們的工程src資料夾下會自動生成Hibernate實體類和與其對應的關係對映檔案,如下圖所示:
實體類檔案如下:
Poets.java
簡單來說,Poets類只有兩個屬性,分別為id和name,建立它們的get()、set()方法即可。
- package com.csdn.entity;
- 公共 類 Poets 實現 java.io.Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- 私有 字串名稱;
- 公共 詩人(){
- }
- public Poets(String name){
- 這個 .name =名字;
- }
- public Integer getId(){
- 返回 此 .id;
- }
- public void setId(Integer id){
- 這個 .id = id;
- }
- public String getName(){
- 返回 此 .name;
- }
- public void setName(String name){
- 這個 .name =名字;
- }
- }
Poetries.java
簡單來說,Poetries類有四個屬性,分別為id、poets、title和content,建立它們的get()、set()方法即可。
- package com.csdn.entity;
- public class Poetries implements java.io.Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private Poets poets;
- private String content;
- private String title;
- public Poetries() {
- }
- public Poetries(Poets poets, String content, String title) {
- this.poets = poets;
- this.content = content;
- this.title = title;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public Poets getPoets() {
- return this.poets;
- }
- public void setPoets(Poets poets) {
- this.poets = poets;
- }
- public String getContent() {
- return this.content;
- }
- public void setContent(String content) {
- this.content = content;
- }
- public String getTitle() {
- return this.title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- }
關係對映檔案如下:
Poets.hbm.xml
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="com.csdn.entity.Poets" table="poets" catalog="tangshi">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <generator class="identity" />
- </id>
- <property name="name" type="string">
- <column name="name" />
- </property>
- </class>
- </hibernate-mapping>
Poetries.hbm.xml
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="com.csdn.entity.Poetries" table="poetries" catalog="tangshi">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <generator class="identity" />
- </id>
- <many-to-one name="poets" class="com.csdn.entity.Poets"
- fetch="select">
- <column name="poet_id" />
- </many-to-one>
- <property name="content" type="string">
- <column name="content" length="65535" />
- </property>
- <property name="title" type="string">
- <column name="title" />
- </property>
- </class>
- </hibernate-mapping>
從以上配置檔案中可以清楚的看出Eclipse已經自動識別出了兩個類之間的多對一關係。
七、在Spring的核心配置檔案applicationContext.xml檔案下配置與Hibernate相關的引數:
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:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
- xmlns:tx="http://www.springframework.org/schema/tx">
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
- <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
- <property name="url"
- value="jdbc:mysql://localhost:3306/tangshi?useUnicode=true&characterEncoding=utf-8">
- </property>
- <property name="username" value="root"></property>
- <property name="password" value="root"></property>
- </bean>
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
- <property name="dataSource">
- <ref bean="dataSource" />
- </property>
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">
- org.hibernate.dialect.MySQLDialect
- </prop>
- </props>
- </property>
- <property name="mappingResources">
- <list>
- <value>com/csdn/entity/Poetries.hbm.xml</value>
- <value>com/csdn/entity/Poets.hbm.xml</value>
- </list>
- </property>
- </bean>
- <bean id="transactionManager"
- class="org.springframework.orm.hibernate4.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory" />
- </bean>
- <tx:annotation-driven transaction-manager="transactionManager" />
- </beans>
八、建立專案所必需的包和類。
SSH框架整合的專案結構一般有三層,分別是Dao層、Service層、Action層。
下面我們依次來建立它們。這裡說明一點,Dao層和Service層需要用介面的方式來寫,然後用實現類去分別實現它們。專案結構圖下圖所示:
com.csdn.dao包,其中包含SearchDao.java介面,用來書寫資料庫查詢的方法。
com.csdn.dao.impl包,其中包含SearchDaoImpl.java類,用來實現SearchDao.java介面。
com.csdn.service包,其中包含SearchService.java介面,用來書寫業務邏輯。
com.csdn.service.impl包,其中包含SearchServiceImpl.java類,用來實現SearchService.java介面。
com.csdn.action包,其中包含SearchAction.java類,用來書寫控制跳轉邏輯。
九、編寫具體程式碼實現:
SearchDao.java
這裡說明一下,Dao層書寫了三個方法,分別是findByName、findByTitle、findByContent,分別實現了三個我們的主要需求。
- package com.csdn.dao;
- import java.util.List;
- public interface SearchDao {
- public List<String> findByName(String name);
- public List<String> findByTitle(String title);
- public List<String> findByContent(String content);
- }
SearchDaoImpl.java
分別實現findByName、findByTitle、findByContent三個方法。
- package com.csdn.dao.impl;
- import java.util.List;
- import org.hibernate.Query;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.Transaction;
- import com.csdn.dao.SearchDao;
- public class SearchDaoImpl 實現 SearchDao {
- private SessionFactory sessionFactory;
- private List <String>列表;
- public List <String> getList(){
- 返回 清單;
- }
- public void setList(List <String> list){
- 這個 .list = list;
- }
- public SessionFactory getSessionFactory(){
- return sessionFactory;
- }
- public void setSessionFactory(SessionFactory sessionFactory){
- 這個 .sessionFactory = sessionFactory;
- }
- @SuppressWarnings({ “unchecked” })
- @覆蓋
- public List <String> findByName(String name){
- 會話會話= sessionFactory.openSession();
- 交易ts = session.beginTransaction();
- String sql = “select b.title from poetries b left join poets a on b.poet_id = a.id where a.name =?” ;
- 查詢query = session.createSQLQuery(sql).setString(0,name);
- list = query.list();
- ts.commit();
- session.close();
- 返回 清單;
- }
- @SuppressWarnings(“未選中”)
- @覆蓋
- public List <String> findByTitle(String title){
- 會話會話= sessionFactory.openSession();
- 交易ts = session.beginTransaction();
- String sql = “從title =?的poetries中選擇內容” ;
- 查詢query = session.createSQLQuery(sql).setString(0,title);
- list = query.list();
- ts.commit();
- session.close();
- 返回 清單;
- }
- @SuppressWarnings(“未選中”)
- @覆蓋
- public List <String> findByContent(String content){
- 會話會話= sessionFactory.openSession();
- 交易ts = session.beginTransaction();
- String sql = “選擇a.content作為內容,a.title作為標題,b.name作為名稱來自poetries a inner join poets b on a.poet_id = b.id where acontent like?” ;
- Query query = session.createSQLQuery(sql).setString(0, "%" + content + "%");
- list = query.list();
- ts.commit();
- session.close();
- return list;
- }
- }
SearchService.java
- package com.csdn.service;
- import java.util.List;
- public interface SearchService {
- public List<String> findByName(String name);
- public List<String> findByTitle(String title);
- public List<String> findContent(String content);
- }
SearchServiceImpl.java
- package com.csdn.service.impl;
- import java.util.List