最近檢查作業,雖然我們反覆強調三層架構就是:表示層、業務邏輯層、資料訪問層,每個層只做自己應該做的事情,但是,部分同學的作業還是不理想啊~~~
你以為的三層架構是這樣的:
而實際上你的三層架構是這樣的:
如果我們尚不能完全瞭解把握各個層的邊界,那麼我們首先僅需要記住下面兩句話:
1:除了UI層,任何其它層不要出現System.out;
2:除了DAO層,任何其它層不要出現SQL;
1.除了UI層,任何其它層不要出現System.out
在三層架構的作業中,我們寫到:
這句話本來說的是service層應該是和具體的資料儲存無關的,但是反過來說,service同時也應該是和具體的頁面展示無關的。這是什麼意思呢?
先來看趙同學的這個專案結構:
Very清晰,沒有任何問題(其實有問題)。但現在讓我們開啟biz下的一個檔案:
可以看到,在Service層的ScoreService相關方法中,出現了很多接受使用者輸入的程式碼。
這是不能接受的,如果是在BS程式中,相當於我們把網頁寫到了service層。
接受使用者輸入一定是在UI層完成的,修改之後的這兩個方法,應該長成這樣才行:
仔細比對下之前的save。在呼叫save方法之前,name和pwd和grade應該在UI層就已經得到了。另外,我也去掉了id,為什麼呢?如果你的id在資料庫中是自增的,那麼根本不需要得到它。當然存在一種情況,我們不需要id由資料庫自己生成,而是由程式碼根據業務特點自己生成,那麼確實就應該放在Service的當前方法來生成。但是看這段程式碼,顯然不需要,因為趙同學首先從資料庫取id的max值,然後+1,然後再insert回去,那不就是資料庫的自增欄位嗎?所以這樣做又是何必呢。
上面的save還可以繼續改造
也就是說,service所要引數是UI層已經構造好的物件。到了web階段,尤其使用了各種MVC框架後,這些物件可以直接由框架構造好,故service層用到的引數是這些實體物件才是更常見的。
2.除了DAO層,任何其它層不要出現SQL
接著來看第二個同樣重要的問題
怎麼可以這樣呢,趙同學,你傷我的心了~~~
你可是一個月寫了6篇部落格的同學,然而到了這個作業一下子坍塌了,是不是太驕傲導致你看都不看什麼是三層架構?
請把所有見得到的sql丟到dao層去。
3.Dao層返回什麼?
趙同學的作業簡直慘不忍睹,把所有能犯的錯誤全部犯了,如下:
在這個queryall的dao方法中,它返回了一個void,然後列表直接在方法中遍歷輸出,我只能說一個大大的服
而正常的做法是,返回List<Score>,然後在UI層輸出。
除了select,CRUD中的CUD返回什麼呢?
Insert、update、delete語句JDBC都會返回一個int值,表明在資料庫中影響的行數,舉例來說,
如果新增一條記錄,則jdbc返回的就是1;
如果更新了10條記錄,則jdbc返回的就是10;
而dao就是要真實反映資料庫操作,故以趙同學的delete為例
應該修改為:
看到沒,我連方法名都改了(哼哼,還有SQL隱碼攻擊哦)。
4.Service怎麼處理dao層返回的int值?
Service層不應該再反映資料庫的狀態了,所以,以deleteByName為例,service應該這麼寫:
或者這麼寫:
如果是第一種寫法,得有一個全域性處理異常的地方,如果是後一種寫法,則UI層自己展示刪除結果資訊給使用者。
5.其它問題
A:SQL隱碼攻擊。這個問題就不多說了,用引數化SQL解決之;
B:分層不應該用package,而應該是project,這是作業裡面要求的;
C:命名不規範;
暫時就這些吧,如果寫多了估計會打擊趙同學的積極性,畢竟,我們還要趙同學笑著活下去呢~~