Struts+hibernate應用實現頁面操作數據庫

在Struts+hibernate框架的結合應用中,這兩種框架本身提供了操作的思路和對Java J2EE原先一些對servlet,bean的應用的簡化和封裝。

整合Struts和hibernate,基本思路就是把MVC中的Model模型部分使用hibernate來做:
這裏寫圖片描述

這裏先說一下POJO的簡單概念:
POJO的名稱有多種,pure old java object 、plain ordinary java object 等。
按照Martin Fowler的解釋是“Plain Old Java Object”,從字面上翻譯爲“純潔老式的java對象”,但大家都使用“簡單java對象”來稱呼它。
POJO的內在含義是指那些沒有從任何類繼承、也沒有實現任何接口,更沒有被其它框架侵入的java對象。

解釋一下上面這個圖的涵義:
Struts實現控制層,分別連接model層和view層,view層的實現方法可以通過JSP實現,或者像hibernate+spring框架那樣使用html+javascript實現也可以,至於model層,可以直接使用hibernate或者mybatis框架。

下面直接給最終的實現頁面和源碼:
這裏寫圖片描述
最終效果圖如上:提供三個連接可以進行修改,刪除,和編輯,並且在提交操作後立刻刷新查詢頁面。

運行環境:eclipse;
數據庫:MySQL;
引用包(jar):Struts+hibernate,具體版本省略

首先看M層(Model層)的hibernate框架怎麼實現:
1、 先創建個數據庫:
Creat database freestyle;
2、 接下來創建pojo,也就是實體類對象product.java:
Product有id,name,price3個字段:

product.java:

package com.how2java.pojo;

public class Product {

    private int id;
    private String name;
    private float price;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }

}
//如上,實體類的三個屬性及其setter,getter方法;

接下來,處理hibernate框架兩個核心問題:映射和數據庫連接配置:
映射Product類對應數據庫freestyle中的product_表,這個表不必自己創建,因爲hibernate框架在設置了updata後會自己創建該表。
映射表:

Product.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 package="com.how2java.pojo">
    <class name="Product" table="product_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
        <property name="price" />
    </class>

</hibernate-mapping>

數據庫配置文件:
hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/freestyle?characterEncoding=GBK</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        <mapping resource="com/how2java/pojo/Product.hbm.xml" />

    </session-factory>

</hibernate-configuration>

接下來,創建DAO層,DAO即是用來控制對象對數據庫的訪問,並且封裝數據庫操作的訪問控制層,ta使得任何對數據庫CRUD的操作都交由DAO對象進行操作控制,即我們需要通過new DAO的實例來實現數據庫操作。

ProductDAO.java:

package com.how2java.dao;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.how2java.pojo.Product;

public class ProductDAO {

    public void add(Product p) {
        List<Product> result = new ArrayList();

        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();

        s.save(p);

        s.getTransaction().commit();
        s.close();
        sf.close();
    }

    public Product get(int id) {
        Product result = null;

        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        Session s = sf.openSession();

        result = (Product) s.get(Product.class, id);

        s.close();
        sf.close();
        return result;
    }

    public void delete(int id) {
        List<Product> result = new ArrayList();

        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();

        Product p = (Product) s.get(Product.class, id);

        s.delete(p);

        s.getTransaction().commit();
        s.close();
        sf.close();
    }

    public void update(Product p) {
        List<Product> result = new ArrayList();

        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();

        s.update(p);

        s.getTransaction().commit();
        s.close();
        sf.close();
    }

    public List<Product> listProduct() {
        List<Product> result = new ArrayList();

        SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        Session s = sf.openSession();

        Query q = s.createQuery("from Product p");

        result = q.list();

        s.close();
        sf.close();
        return result;
    }
}

這裏注意會話和線程服務的創建:

SessionFactory sf = new Configuration().configure()
                .buildSessionFactory();
        Session s = sf.openSession();
        s.beginTransaction();

如果有BaseDAO層則可以把這裏寫入更基本的BaseDAO層以減少代碼的耦合度。

接下來交給Struts框架:
Struts框架主要用於傳輸過程中攔截和加工處理對象,其核心文件web.xml:

<web-app>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>        
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

攔截後按照struts.xml的邏輯執行:
分別爲增加,刪除,獲取,修改,查詢配置Action
爲了便於理解,這裏沒有使用通配符,可以查看struts的通配符匹配簡化配置
struts.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <constant name="struts.i18n.encoding" value="UTF-8"></constant>

    <package name="basicstruts" extends="struts-default">
        <action name="addProduct" class="com.how2java.action.ProductAction"
            method="add">
            <result name="list" type="redirect">listProduct</result>
        </action>
        <action name="deleteProduct" class="com.how2java.action.ProductAction"
            method="delete">
            <result name="list" type="redirect">listProduct</result>
        </action>
        <action name="editProduct" class="com.how2java.action.ProductAction"
            method="edit">
            <result name="edit">/product/edit.jsp</result>
        </action>
        <action name="updateProduct" class="com.how2java.action.ProductAction"
            method="update">
            <result name="list" type="redirect">listProduct</result>
        </action>
        <action name="listProduct" class="com.how2java.action.ProductAction"
            method="list">
            <result name="listJsp">/product/list.jsp</result>
        </action>
    </package>

</struts>

Struts核心部分是action,那action的作用是什麼?

1、可以進行一些表單數據的檢查,這裏面的檢查一般和頁面的檢查是不一樣的,頁面的檢查都是客戶端的一些數據格式規範的檢查,這裏的檢查而與業務相關的檢查一般放到這裏面檢查,比如與JavaBean相關的一些操作。也可以說它是一個業務邏輯的管理分發的地方。

2、執行必要的業務邏輯,不如存取數據庫,調用實體bean等。它會直接調用業務邏輯層的javabean去處理數據庫的操作,比如增刪改查等。

3、根據處理的結果決定程序的去向,並以ActionForward對象的形式傳遞給ActionServlet,這樣ActionServlet通過配置文件,決定返回的數據到達那個頁面。

4、Action是一個抽象類,必須實現以後才能執行,執行的方法是execute方法。

接下來需要對action準備對應的方法:
ProductAction.java:

package com.how2java.action;

import java.util.List;

import com.how2java.dao.ProductDAO;
import com.how2java.pojo.Product;

public class ProductAction {

    ProductDAO pdao = new ProductDAO();
    Product product;
    List<Product> products;

    public List<Product> getProducts() {
        return products;
    }

    public void setProducts(List<Product> products) {
        this.products = products;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public String add() {
        pdao.add(product);
        return "list";
    }
    public String edit() {
        product =pdao.get(product.getId());
        return "edit";
    }
    public String delete() {
        pdao.delete(product.getId());
        return "list";
    }
    public String update() {
        pdao.update(product);
        return "list";
    }
    public String list() {
        products = pdao.listProduct();
        return "listJsp";
    }


}

//先初始化Product product和Product<list>product,在爲Action 準備對應的方法並返回string

接下來需要用jsp編寫頁面顯示,注意jsp作爲一種網頁顯示技術可同時嵌套Java和html;

我們先編寫list.jsp提供增加和顯示功能以及刪除和修改的超鏈;

list.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8" isELIgnored="false"%>

<%@ taglib prefix="s" uri="/struts-tags"%>

<html>

<body>
<table align="center" border="1" cellspacing="0" width="500px">

    <tr>
        <td>id</td>
        <td>name</td>
        <td>price</td>
        <td>edit</td>
        <td>delete</td>
    </tr>

    <s:iterator value="products" var="p">
        <tr>
            <td>${p.id}</td>
            <td>${p.name}</td>
            <td>${p.price}</td>
            <td><a href="editProduct?product.id=${p.id}">edit</a></td>
            <td><a href="deleteProduct?product.id=${p.id}">delete</a></td>
        </tr>
    </s:iterator>
</table>

<br/>

<form action="addProduct" method="post">
<table align="center" border="1" cellspacing="0">
 <tr>
    <td>
        name:
    </td>
    <td>
        <input type="text" name="product.name" value="">
    </td>
 </tr>
 <tr>
    <td>
        price:
    </td>
    <td>
        <input type="text" name="product.price" value="0">
    </td>
 </tr>
 <tr>
    <td colspan="2" align="center"> 
        <input type="submit" value="submit">
    </td>
 </tr>
</table>

</form>

</body>
</html>

然後在編寫edit.jsp用於編輯列表信息:
edit.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8" isELIgnored="false"%>

<%@ taglib prefix="s" uri="/struts-tags"%>

<html>

<body>

<form action="updateProduct" method="post">
<table align="center" border="1" cellspacing="0">
 <tr>
    <td>
        name:
    </td>
    <td>
        <input type="text" name="product.name" value="${product.name}">
    </td>
 </tr>
 <tr>
    <td>
        price:
    </td>
    <td>
        <input type="text" name="product.price" value="${product.price}">
    </td>
 </tr>
 <tr>
    <td colspan="2" align="center">
        <input type="hidden" name="product.id" value="${product.id}"> 
        <input type="submit" value="submit">
    </td>
 </tr>
</table>

</form>

</body>
</html>

最後創建Index.jsp:用於跳轉:
index.jsp:

<jsp:forward page="listProduct"/>

注意這個程序並沒有用到客戶端的跳轉傳參,而是用type=”redirect”直接進行客戶端的跳轉,在每次修改或添加時重新跳轉到list.jsp並且使用STRUTS特有標籤S:Interator進行遍歷輸出,這樣是有區別與AJAX的即時顯示,在每次進行操作時都會與數據庫交互一次,並且在list.jsp更新輸出。

關於數據從頁面傳入數據庫,Struts本身可以通過new productdao創建實體類DAO層對象,並且在方法中直接調用賦值的方法進行頁面和通過更新跳轉list.jsp的方式進行數據庫表內容的即時顯示。

PS:最後,如果要實現運行需要導入正確的jar包

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章