ibooking項目設計介紹(一個基於SSH的外賣點餐系統)

一、源碼路徑

https://github.com/weiganyi/ibooking

 

二、界面

通過瀏覽器訪問web網站,可以看到界面如下:

 

 

 

三、背景

這兩年來O2O的概念越來越火熱,O2O因爲能夠把線下的資源通過線上的信息溝通渠道進行連接,影響着很多實體行業未來的發展。

這個項目就是爲餐飲店提供線上外賣訂餐服務的web網站,具有O2O網站的特點。網站有顧客和管理員兩類角色,分別對於與餐飲店的顧客和餐飲店自身。用戶在網站上註冊後會留下用戶的地址和聯繫電話,這些信息會作爲送外賣時的用戶信息,然後用戶能夠在網站上看到餐飲店的所有菜品圖片,選中後到購物車下單,就會生成一個訂單,餐飲店後臺可以看到這些訂單,然後完成後續的餐品製作和送達服務。

系統後臺採用的是成熟的SSH框架來搭建服務,前端仍然是用jsp來拼接頁面,所以頁面還是在後臺生成的。由於本人是後臺開發,所以爲了美化界面採用bootstrapcss框架,在js框架方面只是使用了jquery,並沒有使用其他js框架。數據庫方面使用的mysql,對於用戶訪問量大的幾個表採用了redis做爲緩存,提高響應速度。

 

四、功能實現

1、用戶功能

1)菜品預定:菜品展示(主頁)、購物車、訂單列表、訂單詳情

2)註冊登錄:註冊、登錄、用戶信息

2、管理員功能

1)用戶管理

2)訂單管理

3)圖片管理

4)菜品管理

5)菜品類型管理

6)配置管理

 

五、總體設計思路

1、數據庫設計

1)其中ib_menu_type表存儲菜品類型信息,ib_menu表存儲菜品信息,ib_option表存儲配置信息,ib_user表存儲用戶信息,ib_shopping表存儲用戶購物車信息,ib_order表存儲訂單信息,ib_order_detail表存儲訂單詳情信息,這7個表爲關係型表,使用mysql數據庫存儲。它們的具體字段如下:

create table ib_menu_type(

    menu_type_id int(4) not null primary key auto_increment,

    menu_type_name char(255) not null);

create table ib_menu(

    menu_id int(4) not null primary key auto_increment,

    menu_name char(255) not null,

    menu_price int(16) not null,

    menu_pic_addr char(255) not null,

    menu_type_id int(4) not null);

create table ib_option(

    option_id int(4) not null primary key auto_increment,

    option_name char(255) not null,

    option_value char(255) not null);

create table ib_user(

    user_id int(16) not null primary key auto_increment,

    user_name char(255) not null,

    user_passwd char(255) not null,

    user_auth enum('admin', 'customer') not null,

    user_tel char(255) not null,

    user_addr char(255) not null);

create table ib_shopping(

    shopping_id int(16) not null primary key auto_increment,

    shopping_user_name char(255) not null,

    shopping_menu_name char(255) not null,

    shopping_menu_price int(16) not null,

    shopping_amount int(16) not null,

    shopping_remark char(255) not null);

create table ib_order(

    order_id int(16) not null primary key auto_increment,

    order_user_name char(255) not null,

    order_time datetime not null,

    order_admin_name char(255) not null,

    order_accept int(1) not null);

create table ib_order_detail(

    detail_id int(16) not null primary key auto_increment,

    detail_order_id int(16) not null,

    detail_menu_name char(255) not null,

    detail_menu_price int(16) not null,

    detail_amount int(16) not null,

    detail_remark char(255) not null);

2)用戶訪問量大的menumenutypeoption三個表使用redis緩存,因爲這幾個表不會頻繁更新,不會造成緩存頻繁失效,同時對於不同的用戶,都會訪問這幾個表裏相同的字段,所以它們使用緩存是比較有意義的。

3)由於使用了緩存,redismysql之間的數據同步設計是要點。最開始,我採用的讀流程爲在redis啓動時先從mysql讀入表的所有記錄,後續直接從redis查詢記錄,寫流程爲先寫入redis,並將其放入一個隊列,隊列消費者讀取隊列後再寫入mysql,當mysql寫失敗時,要把redis寫入的內容回滾。但經過分析這種設計是有問題的,redismysql數據同步肯定會涉及一個主次問題,之前的設計相當於redis爲主,mysql爲次,這樣當mysql寫失敗時再回滾redis,這時redis可能已經有新數據寫入了,再回滾會造成用戶後寫入的數據被刷掉了。正確的寫流程應該以mysql爲主,先寫入mysql然後設置redis對應的鍵失效,這樣成功寫入mysql後,即便設置redis鍵失效操作失敗,由於緩存可以設置有效期,也只是會在緩存有效期內暫時影響讀到的數據,而數據由於已經寫入了mysql是能夠正確的保存的。

4)在寫操作時redis生成自增id,然後插入mysql,必須保證redis生成的自增id大於mysql表的auto_increment當前值才能成功。所以redis啓動時需要先讀取mysql對應表的auto_increment值並保存,以後每次新增記錄時,把auto_increment值加一併作爲id值,這樣就能夠保證總是大於mysql表的auto_increment當前值。

5)在事務可靠性方面,當需要同時修改兩個表的記錄時,redismysql需要各自使用事務。redis自身有事務機制可以使用,而mysql可以使用SSH框架的aop聲明式事務機制。

6redis的數據格式爲了對應mysql表,需要有一條記錄表示mysql表的索引,如set/get "ib_menu:test:id" "6",這裏test是菜品名稱,也是ib_menu表的索引是菜品名,這樣就可以通過這條記錄取得test菜品的id值,然後對應這個id值有系列記錄表示mysql表的各個字段,如set/get "ib_menu:6:menu_price" "13",這裏就表示id6的記錄的menu_price字段值爲13

2Web前端設計

1)在html頁面的構造上,採用jsp腳本來完成。根據後臺servlet邏輯處理完後生成的java bean對象,在jsp文件內,通過java腳本或者jstljsp技術,獲取java bean對象拼裝成所需要的html頁面。

2)採用bootstrap來美化界面,採用bootstrap封裝的一些組件。

3)界面按鈕觸發ajax請求,頁面刷新方式有兩種,一種響應只更新頁面具體元素值,另一種是響應更新除了頁頭外的其餘部分。

3Java後臺服務設計

1)後臺整體模塊採用MVC經典分成架構,分爲如下5層:

表現層:jsp頁面。

MVC Action層:每個頁面對應一個Action

業務邏輯層:負責後臺業務邏輯實現。

DAO層:負責數據庫和緩存的讀寫邏輯實現。

數據對象層:對數據庫或緩存做對象映射。

2)對struts包含組件和特性的使用情況:

action:實現主要控制器邏輯。

國際化:使用全局國際化資源文件。

標籤:主要使用s:text, s:property, s:fielderror和控制標籤,structss:form比較弱,所以使用原生的並用bootstrap來增強。

類型轉換:請求參數解析和響應參數構造由類型轉換來實現,可能需要自定義轉換器。

輸入校驗:文本輸入需要增加校驗,使用全局校驗文件。

文件上傳:使用封裝的文件上傳框架,包括攔截器文件過濾功能。

攔截器:實現一個自定義的管理員訪問權限控制攔截器。

3)對hibernate數據庫的封裝的使用情況:

單表映射:ib_option使用單表映射。

關聯映射:ib_menuib_menu_type使用無連接表的單向N-1關聯。

hql查詢:使用hibernate特有的hql查詢語法,便於與HibernateDaoSupport框架集成。

開啓二級緩存:由於使用了redis做緩存,所以不使用hibernate內置的二級緩存功能。

4)對spring特性的使用情況:

ioc依賴注入:如果採用spring來注入struts action會造成xml冗餘,所以不使用這種方式,

使用spring啓動hibernatesessionFactory,並用ioc注入的dao對象方式來進行數據庫表訪問。

aop切面注入:對多表操作使用xml方式聲明式事務機制。

5)線程安全方面的考慮,因爲HibernateTemplate是線程安全的,所以mysql訪問不需要加鎖,而redis訪問需要加鎖。

6)在服務部署上,使用nginx做反向代理,把請求轉發到後端的tomcat服務器上進行處理。這也是常用的部署方式,因爲目前系統文件比較少,所以沒有把圖片等靜態資源放到nginx下這種動靜分離的做法。

 

六、文件目錄介紹

bin:系統腳本,如重啓腳本

res\pic:圖片資源文件

res\tmp:刪除圖片時的臨時存放目錄

WEB-INF\jsp:jsp文件

WEB-INF\jsp\manager:後臺管理模塊的jsp文件

WEB-INF\lib:依賴的jar

WEB-INF\src\ibooking\action:action的實現

WEB-INF\src\ibooking\action\authority:攔截器實現

WEB-INF\src\ibooking\action\base:action的父類

WEB-INF\src\ibooking\action\manager:後臺管理模塊的action實現

WEB-INF\src\ibooking\dao:dao層的父類

WEB-INF\src\ibooking\dao\impl:dao的實現

WEB-INF\src\ibooking\po:數據對象映射類

WEB-INF\src\ibooking\service:業務邏輯層父類

WEB-INF\src\ibooking\service\impl:業務邏輯層實現

WEB-INF\src\ibooking\util:輔助類實現

WEB-INF\src\ibooking\vo:視圖層對象

WEB-INF\src\ibooking\vo\manager:後臺管理模塊的視圖層對象

 

七、部署方法

1、源碼下載後,用eclipse編譯服務端源碼。

2、在服務器上安裝部署nginxtomcat,配置nginx把所有請求轉發到tmcat,同時安裝部署好mysqlredis

3、在tomcat/webapps下建立項目目錄ibooking,然後把編譯生成的目錄和文件拷貝到ibooking下。

4、把根目錄下的數據庫備份文件ibooking_mysql_db.sql導入mysql

5、通過瀏覽器也可以訪問系統的Web部分,使用顧客和管理員角色相關功能。

(完)

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