最課程階段大作業04:毫無用處的學生管理系統
前面幾期就業班學生知道,我在做簡歷指導時說過:如果你的簡歷中專案經歷寫的是“學生管理系統”、“**辦公自動化”這樣的系統,那麼就等於告訴面試官:你沒有專案經驗。
對於面試找工作,學生管理系統這樣的專案簡直毫無用處,甚至是減分項。如果你一定要說你實現了一個NB的學生管理系統,那麼就需要拿出你在GITHUB上的原始碼來,並對面試官說:我已經把它做成了一個框架,以後所有的使用者管理系統都可以基於這個框架進行擴充套件~~
學生管理系統對於找工作毫無用處,但對於當前的我們來說,倒是一個好的案例。如果說HelloWorld是我們學習Java的第一個程式,那麼學生系統則應該說是我們在做專案時的HelloWorld。
它,簡單,直觀。即使再笨,我們也能切身知道其中的業務邏輯。
為什麼?因為現階段我們剛學完MySql+JDBC,迫切需要做一個真實的案例來檢驗和鞏固學習的知識,那麼這個簡單的Mis系統再合適不過了。
如果能獨立完成該MIS系統,那意味著我們可以做最基礎的增刪改查(CRUD)了。不過,僅僅用這個案例來完成CRUD的工作,有點太浪費這次練習的時間了,我們不妨稍稍提升下B格:做一個三層架構的CRUD。
實現取資料
先假設資料庫中已經存在學生表,現在要用java程式碼把所有的學生全部取出來並顯示到前臺,該怎麼做?
按照以前的寫法,我們會這樣去實現(使用了c3p0和DbUtils,配置檔案及附屬程式碼略):
package com.zuikc.usermanagement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; public class IndexPage { public staticvoid main(String[] args) throws SQLException { QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); List<User> users = qr.query("select * from user_tb", new ResultSetHandler<List<User>>(){ @Override public List<User> handle(ResultSet rs) throws SQLException { List<User> list = new ArrayList<User>(); while(rs.next()){ User user = new User(); user.setUsername(rs.getObject("username").toString()); System.out.println(user.getUsername()); list.add(user); } return list; }}); } }
順便附上整個專案結構:
但緊接著問題來了,現在需求變更為:將使用者列表從資料庫取出來匯出到檔案中~~。
有同學說,這好辦,讓我們修改程式碼:
List<User> list = new ArrayList<User>(); try { FileWriter writer = new FileWriter("c:\\temp\\temp.txt"); while (rs.next()) { User user = new User(); user.setUsername(rs.getObject("username").toString()); //System.out.println(user.getUsername()); writer.write(user.getUsername() + "\n"); list.add(user); } writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return list;
看上去,問題解決了。但是緊接著問題又來了,讓我們把結果輸出到網頁中或者socket傳輸到另一臺電腦中。怎麼辦?
難道我們只要有新需求,就去改這個while迴圈嗎?
不知道大家有沒有發現,無論我們的輸出怎麼變化,我們的“獲取資料”這部分的程式碼實際上從來沒有變過。
沒有變過的程式碼能不能將它隔離開來放到某個層中呢?答案當然是可以的,這種手法就叫做:分層架構的設計思想。
什麼是三層架構
所謂架構,指的是一種編碼的思想,一種指導我們將程式碼寫的更加優美的思想。三層架構是最早出現的軟體架構設計思想之一,它用於指導我們將程式碼歸置的更整潔,以便我們完成更龐大的系統。
最原始的分層架構,叫做:三層架構(表示層、業務邏輯層、資料訪問層)。每層的作用如下:
01.表示層(User Interface layer):如果光看英文,直譯過來是:使用者介面層。也就是說,這個層專門負責接收使用者的輸入,將輸出呈現給使用者。另外,輸入輸出過程中的訪問安全性驗證、輸入的資料的正確性驗證也由這個層負責。
02.業務邏輯層(Business Logic Layer):負責系統業務邏輯的處理。它也包括對所輸入的邏輯性資料的正確性及有效性的負責。有人可能要問,UI層不是已經負責了正確性嗎,為什麼業務邏輯層也要負責?答案是:因專案而異。在部分專案中,需要將正確性驗證等功能放置在UI層,而在有些專案中,則在業務邏輯層,甚至有些專案,兩個層都要做。
03.資料訪問層(Data Access Layer):資料訪問層的功能較為單一,它負責與資料來源的互動,即資料的插入,刪除,修改,以及從資料庫中讀出資料等操作,但對資料的正確性和有效性不負責,對業務邏輯不負責。
結束了嗎?其實並沒有,以上是最主要的三層,實際還有有些輔助的層,如:
04 工具層
通用類庫,比如一些工具類就可以放在這裡。這些工具類最簡單的可以是檢驗email是否符合規則,也可以是加密解密工具類,同時,資料庫連線幫助類也放在這裡。
05實體層
比如,上文程式碼中的User類,就是一個實體類。它很大程度上是資料庫表字段在Java語言中的對應。
以上,基本上就差不多了。它們的主要依賴關係如下:
接下來,讓我們改造程式碼以便符合三層架構。
其中,
表示層:com.zuikc.usermanagement.ui
業務邏輯層:com.zuikc.usermanagement.biz
資料訪問層:com.zuikc.usermanagement.dao
工具層:com.zuikc.usermanagement.common
實體層:com.zuikc.usermanagement.bean
從上層到下層的程式碼依次為:
表示層,IndexPage:
package com.zuikc.usermanagement.ui; import java.util.List; import com.zuikc.usermanagement.bean.User; import com.zuikc.usermanagement.biz.UserService; public class IndexPage { public static void main(String[] args) throws Exception { UserService service = new UserService(); List<User> users = service.getAllUsers(); for (User user : users) { System.out.println(user.getUsername()); } } }
業務邏輯層,UserService:
package com.zuikc.usermanagement.biz; import java.sql.SQLException; import java.util.List; import com.zuikc.usermanagement.bean.User; import com.zuikc.usermanagement.dao.UserDao; public class UserService { UserDao dao = new UserDao(); public List<User> getAllUsers() throws SQLException{ List<User> users = dao.queryUsers(); return users; } }
資料訪問層,UserDao:
package com.zuikc.usermanagement.dao; import java.io.FileWriter; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import com.zuikc.usermanagement.bean.User; import com.zuikc.usermanagement.common.C3P0Util; public class UserDao { public List<User> queryUsers() throws SQLException { QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); List<User> users = qr.query("select * from user_tb", new ResultSetHandler<List<User>>() { @Override public List<User> handle(ResultSet rs) throws SQLException { List<User> list = new ArrayList<User>(); while (rs.next()) { User user = new User(); user.setUsername(rs.getObject("username").toString()); list.add(user); } return list; } }); return users; } }
工具層,C3P0Util:
package com.zuikc.usermanagement.common; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class C3P0Util { // 得到資料來源 private static DataSource dataSource = new ComboPooledDataSource(); public static DataSource getDataSource() { return dataSource; } // 得到連線物件 public static Connection getConnection() { try { return dataSource.getConnection(); } catch (SQLException e) { throw new RuntimeException("獲取連線失敗"); } } public static void release(Connection conn, Statement stmt, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (Exception e) { e.printStackTrace(); } rs = null; } if (stmt != null) { try { stmt.close(); } catch (Exception e) { e.printStackTrace(); } stmt = null; } if (conn != null) { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } conn = null; } } }
實體層,User:
package com.zuikc.usermanagement.bean; public class User { String username; String password; public User() { } public User(String username, String password) { super(); this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
最後放上一個c3p0的配置檔案c3p0-config.xml,
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3317/test</property> <property name="user">root</property> <property name="password">root</property> <property name="initialPoolSize">10</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> </default-config> </c3p0-config>
三層架構的優缺點
優點:
1、在某種架構下,某些開發人員可以只關注整個結構中的其中某一層;
2、可以很容易的用新的實現來替換原有層次的實現(後面要學的動態代理、spring等);
3、可以降低層與層之間的依賴;
4、有利於標準化;
5、利於各層邏輯的複用。
6、擴充套件性強。不同層負責不同層次的程式碼。
7、安全性高。使用者端只能通過邏輯層來訪問資料層,減少了入口點,把很多危險的系統功能都遮蔽了。
8、專案結構更清楚,分工更明確,有利於後期的維護和升級
缺點:
1、降低了系統的效能。分層之後,會增加程式碼,有些地方看上去僅僅就是service層封裝了一下dao層。程式碼增加,意味著效能降低。
2、可能存在級聯的修改。為了增加某個功能,相應的要去增加service和dao。
3、增加了程式碼量,增加了工作量
更進一步的三層架構?
聰明的同學可能已經發現,分層的“層”這個概念在當前這個java專案中對應的就是包(package)的概念。那是不是永遠是這樣的呢?
並不是。層的概念,更多的是project的概念。在大型專案中,一個層就是一個project,就是一個jar包。
我們可以繼續改造我們的三層架構程式碼,看下圖:
在這個過程中,我們將每個層都獨立成為了一個Project了。如果大家仔細觀察,我們會發現,上層service和ui層,壓根就沒有依賴資料庫的那幾個第三方包。在實際的開發中,其實也是這樣:
作為UI層的,可能是一個動態網頁,可能是手機APP端的,對於它們來說,實際上它們不應該,也不需要知道我們的資料是來自於資料庫還是來自於其它地方。對於它們來說,只需要知道:我現在需要一個使用者列表,於是底層就給了它一個使用者列表。仔細回味一下這句話。
上層所依賴的只是下層的包:
UI層,依賴com.zuikc.usermanagement.biz, com.zuikc.usermanagement.bean, com.zuikc.usermanagement.common;
Service層,依賴com.zuikc.usermanagement.dao,com.zuikc.usermanagement.bean,com.zuikc.usermanagement.common;
Dao層,依賴com.zuikc.usermanagement.bean,com.zuikc.usermanagement.common;
Bean層,誰都不依賴(可以依賴common),被誰都依賴;
Common,誰都不依賴,被誰都依賴;
有同學可能對於project依賴另一個project不熟悉,下面給出圖示:
第一步,
第二步,
第三步,
以上,我們完成了一個最徹底的三層架構的解決方案。
作業之用例
有了上面的知識儲備,現在引出我們的大作業。
1.主介面
2.新增使用者
3.使用者列表
4.使用者查詢
5.使用者刪除
作業之要求
華麗分割線
===========================================================
看看吧。你想參加不一樣的培訓班,並且一畢業就NB,那就來加入我們吧;
更多技術文章和開班資訊請加入,
QQ群:
相關推薦
最課程階段大作業04:毫無用處的學生管理系統
前面幾期就業班學生知道,我在做簡歷指導時說過:如果你的簡歷中專案經歷寫的是“學生管理系統”、“**辦公自動化”這樣的系統,那麼就等於告訴面試官:你沒有專案經驗。 對於面試找工作,學生管理系統這樣的專案簡直毫無用處,甚至是減分項。如果你一定要說你實現了一個NB的學生管理系統,那麼就需要拿出你在GITHUB上的
最課程階段大作業06:U度節能平臺控制系統
除了網際網路專案,當今社會還有一個概念非常流行,那就是:物聯網。什麼是物聯網?物聯網是通過感測裝置,按約定的協議,把任意物品與網際網路相連線,進行資訊交換和通訊,以實現智慧化識別、定位、跟蹤、監控和管理的一種網路概念。物聯網是網際網路的一種延伸,將原本使用者與使用者的互動,延伸和擴充套件到物品與物品之間。
最課程階段大作業03:用半天實現淘寶首頁?
每一個在最課程學習的學生,到了最後幾乎都會來問我一個問題:老師,是不是實際的開發中,都會有一個前端開發工程師,把靜態頁面做好了,然後才交給我們後臺開發啊? 我只能說:你想多了。 我知道你這麼問的意思,HTML+CSS+各類前端框架學習起來太繁瑣了,是不是就沒有
最課程階段大作業02:實現自己的利息計算器
上文描述了版本控制後,此篇才真正到了作業本身。我們第一次大作業要完成的是一個利息計算器。 利息計算器或者說融資計算器有自己的圖形化版本,每一個學習的同學如果想要直觀的瞭解下功能,可以管自己的老師要或者加文末的QQ群向老師索取。不過我們今天要實現的是非圖形化的介面,是CS版本的,簡
最課程階段大作業05:汙水處理系統以及百度地圖
吃著火鍋唱著歌,我們的課程已經進行了兩個月了,現在,我們終於有能力進行真正的軟體開發了。 往期學完課程面試歸來的同學,都知道有一句話:“面試造航母,實際工作擰螺絲釘”。 很慶幸的是,到目前為止,你已經掌握了大部分擰螺絲釘需要的知識了,這些知識就是:JavaSE+HTML+CSS+JavaScript+JQ
最課程階段大作業之01:使用SVN實現版本控制
版本控制在友軍那裡都是放在整個培訓的最後階段才開始講的,但我們打算放到SE階段。與其匆匆在專案實戰階段弄個半生不熟,然後進入實際工作中接受他人對你的懷疑,不如……早死早超生~~~。 可是,我們畢竟現在才剛學了Java一個月,程式碼都寫的不溜呢,甚至都不知道目前掌握的知識能做點撒實
高軟作業3:基於原型化系統墨刀的雲筆記應用
產品經理 row 這一 設計 顯示 冗余 targe 圖片 我們 1.基於調研分析的產品原型 在上一次作業中,我們分析了七款各具特色的雲筆記軟件,分別列出了他們的長處和短處。並最終作為這一次作業的原型依據。 2.使用的原型設計工具——墨刀 墨刀是一款在線原
作業系統課程設計(三):Linux程序管理
一、設計內容 實現一個模擬shell:編寫三個不同的程式:cmd1.c, cmd2.c, cmd3.c,每個程式輸出一句話,分別編譯成可執行檔案cmd1, cmd2, cmd3。然後再編寫一個程式,模擬shell程式的功能,能根據使用者輸入的字串(表示相應的命
C++課程設計:學生管理系統
(一)新生基本資訊統計軟體 有新生來報到,要逐個錄入其資訊,如:學生姓名,性別,專業,出生日期,家庭地址,英語入學成績。要求設計連結串列類來實現,並統計學生人數。文字介面為: 1. 新增學生資訊 2. 刪除學生資訊 3. 匯入學生資訊(已經保存於的檔案資訊) 4. 學生資訊搜尋
Django打造在線教育平臺_day_3: 搭建後臺管理系統Xadmin
gis site mode verify 下載源碼 clas type rec pip xadmin是比Django自帶的admin更加強大的系統 1、安裝xadmin的兩種方式: 方式一:pip install xadmin 方式二:github下載最新的源碼(推
Django打造在線教育平臺_day_3: 搭建後臺管理系統Xadmin之其他app的數據表註冊
user cli mode lis mob use lds desc gist courses/adminx.py import xadmin from .models import Course, Lesson, Video, CourseResource class
分享:ERP生產管理系統有什麽好處?
系統說到ERP生產管理系統哪個好?好用的ERP生產管理系統有哪些?相信很多ERP領域專家,或準備上ERP的生產企業,都會認為沒有答案。因為就像買車,不同價位有不同品牌,不同品牌有不同優勢,比如,有的很耐用,有的質感好,有的動力好,有的空間大……很難籠統說哪個好。其實,想知道答案很簡單,選型時多家試用對比,適合
雜項:文件管理系統
無法 雜項 pad log 作者 頂部 分享圖片 borde bsp ylbtech-雜項:文件管理系統 1.返回頂部 1、 文件管理越來越受到企業的重視,但是企業在進行文件管理的過程中,經常會碰到以下的問題:海量文件存儲,管理困難;查找緩慢,
java:學生管理系統
要求:1、新增學生 2、刪除指定學號的學生 3、修改指定學號的成績 4、查詢指定學號的資訊 &n
Python中列表的使用:實現名字管理系統
實現的功能程式碼如下: # 名字管理系統 列表的使用 print("="*50) print("1:新增名字") print("2:修改名字") print("3:查詢名字") print("4:刪除名字") print("5:退出") print("="*50) names = [] w
【C++綜合例項】陣列指標字串以及繼承派生:銀行賬戶管理系統
一個活期儲蓄賬戶包括: 資訊:賬號(id)、餘額(balance)、年利率(rate)等 操作:顯示賬戶資訊(show)、存款(deposit)、取款(withdraw)、結算利率(settle)等。 為此,我們定義了一個SavingAccount類:一開始id和日期date都是使用簡單
實驗三:用雙鏈表、靜態連結串列以及間接定址實現基本的學生管理系統
實驗目的:鞏固線性表的資料的儲存方法和相關操作,學會針對具體應用,使用線性表的相關知識來解決具體問題。 實驗內容:建立一個由n個學生成績的線性表,n的大小由自己確定,每個學生的成績資訊由自己確定,實現資料的對錶進行插入、刪除、查詢等操作。 (1)用雙鏈表實現 源程式: #incl
實驗三:用單鏈表實現基本的學生管理系統
實驗目的:鞏固線性表的資料的儲存方法和相關操作,學會針對具體應用,使用線性表的相關知識來解決具體問題。 實驗內容:建立一個由n個學生成績的線性表,n的大小由自己確定,每個學生的成績資訊由自己確定,實現資料的對錶進行插入、刪除、查詢等操作。 源程式: # ifndef LinkLis
權限管理系統(二):權限管理系統介紹
系統介紹 分享圖片 ole ase sed 數據隔離 破壞 role 需要 為什麽需要權限管理 1、安全性:誤操作、人為破壞、數據泄露等; 2、數據隔離:不同的權限能看到及操作不同的數據; 3、明確職責:運營、客服等不同角色,leader和dev等不同級別 權限管理核心 1
企業內部應用的核心與靈魂:工作流管理系統
工作流是企業內部系統的核心和靈魂,而審批則是工作流中的最基礎的應用場景。在公司管理和運轉中引入審批工作流,替代原本的紙質申請和審批,以期提高公司的運轉效率公司管理制度規範化系統留檔,便於追溯環保。 總結了在企業在實際業務中需求,根據客戶反饋,構建出