99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

SMBMS超市訂單管理系統(tǒng)全流程復(fù)現(xiàn):Servlet/JSP/JDBC實(shí)戰(zhàn)解析

SMBMS超市訂單管理系統(tǒng)全流程復(fù)現(xiàn):Servlet/JSP/JDBC實(shí)戰(zhàn)解析 smbms 這套項(xiàng)目全稱 Super Market Billing Management System也就是超市訂單管理系統(tǒng)網(wǎng)上傳得很廣的那套 JavaWeb 視頻系列的配套項(xiàng)目就是它。很多人學(xué)完 Servlet、JSP、Filter、JDBC 之后面對(duì)的完整體項(xiàng)目就是這套。我當(dāng)年也是一集一集跟著敲敲完發(fā)現(xiàn)一個(gè)很現(xiàn)實(shí)的問(wèn)題跟著視頻能在本地跑起來(lái)合上視頻讓我自己從零寫一遍連包結(jié)構(gòu)都理不清。后來(lái)我把視頻丟到一邊只留題目和功能要求完整地復(fù)現(xiàn)了一遍。這篇文章就是那次復(fù)現(xiàn)的完整記錄環(huán)境、數(shù)據(jù)庫(kù)、分層代碼、登錄權(quán)限、分頁(yè)查詢、增刪改查、部署驗(yàn)證每一步我都盡量把背后的原因說(shuō)清楚。1. 項(xiàng)目定位與拆解這個(gè)經(jīng)典項(xiàng)目到底在訓(xùn)練什么1.1 業(yè)務(wù)模型超市、供應(yīng)商和訂單先理解業(yè)務(wù)。這個(gè)系統(tǒng)模擬的是一家超市的采購(gòu)訂單管理流程超市會(huì)從多家供應(yīng)商進(jìn)貨每筆進(jìn)貨對(duì)應(yīng)一張訂單訂單上記錄商品名、規(guī)格、數(shù)量、金額、是否已付款同時(shí)還要記錄這張訂單對(duì)應(yīng)哪家供應(yīng)商。管理人員打開(kāi)系統(tǒng)能看到所有訂單也能按商品名、供應(yīng)商、付款狀態(tài)篩選還要能新增、修改、刪除訂單。供應(yīng)商和用戶則是輔助管理模塊供應(yīng)商要維護(hù)聯(lián)系人、電話、地址、傳真用戶要區(qū)分角色普通員工和管理員看到的界面、能做的操作不一樣。業(yè)務(wù)不復(fù)雜但剛好能把一套入門級(jí)管理系統(tǒng)的完整鏈路覆蓋到從數(shù)據(jù)庫(kù)表設(shè)計(jì)到后臺(tái)接口再到前端頁(yè)面展示和交互每一環(huán)都不缺。對(duì)于剛學(xué)完 JavaWeb 基礎(chǔ)的人來(lái)說(shuō)它不像電商系統(tǒng)那樣龐大也不像課后作業(yè)那樣單薄是那種跳一跳正好夠得著的項(xiàng)目。1.2 功能清單與學(xué)習(xí)目標(biāo)登錄、退出登錄登錄后根據(jù)角色顯示對(duì)應(yīng)菜單用戶管理新增、修改、刪除、模糊查詢、角色篩選、分頁(yè)供應(yīng)商管理新增、修改、刪除、查看訂單管理新增、修改、刪除、組合條件查詢、分頁(yè)密碼修改校驗(yàn)舊密碼更新新密碼對(duì)應(yīng)到技術(shù)點(diǎn)清單就是下面這張表技術(shù)點(diǎn)在項(xiàng)目里的落點(diǎn)Maven依賴管理、war 打包、目錄規(guī)范Servlet所有請(qǐng)求入口處理參數(shù)、轉(zhuǎn)發(fā)/重定向JSP EL JSTL頁(yè)面展示、列表循環(huán)、分頁(yè)條Filter登錄攔截、字符編碼統(tǒng)一處理JDBC 封裝BaseDao、數(shù)據(jù)庫(kù)連接、增刪改查MySQL四張核心表、多表聯(lián)查這套項(xiàng)目最有價(jià)值的地方就在這里它沒(méi)有引入任何框架你能看到 Servlet 最原始的工作狀態(tài)也能自己動(dòng)手寫出一個(gè)能用的 JDBC 封裝層。之后再學(xué) Spring Boot 或 MyBatis你會(huì)更容易理解框架到底幫你省掉了什么。2. 環(huán)境與開(kāi)局版本組合選對(duì)了后面少踩一半坑我復(fù)現(xiàn)時(shí)用的環(huán)境組合是這批項(xiàng)目最常見(jiàn)的一檔JDK 8、Maven 3.6.3、Tomcat 8.5、MySQL 8.0。說(shuō)實(shí)話現(xiàn)在裝 JDK 17 的人很多但老項(xiàng)目代碼大多是給 JDK 8 設(shè)計(jì)的如果直接上 JDK 17Tomcat 的版本、編譯級(jí)別、依賴的舊 jar 都可能出兼容問(wèn)題第一輪排查就能耗掉半天。所以第一次復(fù)現(xiàn)建議直接按 JDK 8 來(lái)跑通以后再考慮升級(jí)。2.1 我用的那套穩(wěn)定組合JDK 1.8和主流的 Web 容器、視頻教程里的配置完全對(duì)得上Maven 3.6.xIDEA 自帶版本通常也能用注意配好本地倉(cāng)庫(kù)和鏡像源Tomcat 8.5支持 Servlet 3.1對(duì)老項(xiàng)目兼容性好MySQL 8.0需要注意驅(qū)動(dòng)類和時(shí)區(qū)參數(shù)下文會(huì)細(xì)說(shuō)IDEA社區(qū)版就能跑 Web 項(xiàng)目專業(yè)版只是多了框架支持有個(gè)細(xì)節(jié)我想提一下如果本機(jī)已經(jīng)裝了更高版本的 Tomcat比如 Tomcat 10那要特別注意它默認(rèn)使用的是 jakarta.servlet 命名空間老項(xiàng)目里的 javax.servlet 全部要改包名。對(duì)初學(xué)者來(lái)說(shuō)這是個(gè)大坑不建議在第一步就挑戰(zhàn)它。2.2 pom.xml 依賴與兩個(gè)容易出錯(cuò)的點(diǎn)先看依賴。Maven 工程的第一步是創(chuàng)建 war 包結(jié)構(gòu)的 Web 項(xiàng)目然后在 pom.xml 里加上核心依賴dependencies !-- Servlet APITomcat 已提供所以用 provided -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency dependency groupIdjavax.servlet.jsp/groupId artifactIdjavax.servlet.jsp-api/artifactId version2.3.3/version scopeprovided/scope /dependency !-- JSTLJSP 頁(yè)面里做列表循環(huán)和條件判斷 -- dependency groupIdjstl/groupId artifactIdjstl/artifactId version1.2/version /dependency !-- MySQL 驅(qū)動(dòng) -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency /dependencies依賴?yán)镒钊菀壮鰡?wèn)題的就是 MySQL 驅(qū)動(dòng)。MySQL 5.x 用 com.mysql.jdbc.Driver而 MySQL 8.x 必須改成 com.mysql.cj.jdbc.Driver否則啟動(dòng)時(shí)會(huì)報(bào) ClassNotFoundException。第二個(gè)坑是連接串MySQL 8 默認(rèn)要求帶上時(shí)區(qū)參數(shù)所以連接地址通常寫成這樣jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/smbms?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.password123456characterEncodingutf8 這個(gè)參數(shù)也不能漏否則后面插入的中文數(shù)據(jù)到數(shù)據(jù)庫(kù)里全是問(wèn)號(hào)。2.3 IDEA 建 Web 工程時(shí)的 Artifact 問(wèn)題這一步是新手最容易卡住的地方而且卡得很莫名其妙工程建好了代碼寫完了一點(diǎn)運(yùn)行瀏覽器直接 404控制臺(tái)沒(méi)報(bào)錯(cuò)。原因多半是 IDEA 里沒(méi)有配置好 Web Artifact。正確流程是這樣的用 Maven 創(chuàng)建工程時(shí)選 webapp 骨架沒(méi)有骨架也可以后面手動(dòng)加 Web 模塊然后在 Project Structure 里把模塊的 Web Facet 關(guān)聯(lián)上再在 Artifacts 里新增一個(gè) war exploded 類型的啟動(dòng)產(chǎn)物最后在 Tomcat Run Configuration 的 Deployment 頁(yè)面把這個(gè) Artifact 添加進(jìn)去設(shè)置 Application context 為 /smbms。只要這幾步對(duì)齊Tomcat 啟動(dòng)后能直接訪問(wèn) http://localhost:8080/smbms/。實(shí)測(cè)下來(lái)社區(qū)版和新版 IDEA 的界面長(zhǎng)得不太一樣但核心套路沒(méi)變。如果啟動(dòng)后 index.jsp 都訪問(wèn)不了優(yōu)先檢查Artifacts 是否為空、context 路徑是否寫對(duì)、Tomcat 的 application server 是否已經(jīng)配置。3. 數(shù)據(jù)先行四張表的字段設(shè)計(jì)和容易忽略的小細(xì)節(jié)代碼還沒(méi)寫先把數(shù)據(jù)表建好。smbms 的核心是四張表角色表、用戶表、供應(yīng)商表和訂單表。我復(fù)現(xiàn)時(shí)按項(xiàng)目常見(jiàn)的字段結(jié)構(gòu)來(lái)建這也是整個(gè)系統(tǒng)最底層的部分。3.1 四張表的字段設(shè)計(jì)用戶表是最復(fù)雜的字段也比較多字段類型說(shuō)明idint主鍵自增userCodevarchar用戶編碼登錄時(shí)用userNamevarchar真實(shí)姓名userPasswordvarchar密碼建議存 MD5genderint性別1 男 0 女birthdaydate出生日期phonevarchar電話addressvarchar地址userRoleint角色 id對(duì)應(yīng) smbms_role 表createdByint創(chuàng)建人 idcreationDatedatetime創(chuàng)建時(shí)間modifyByint最后修改人 idmodifyDatedatetime最后修改時(shí)間角色表很簡(jiǎn)單id、roleCode、roleName一般就是管理員和普通員工。供應(yīng)商表 smbms_provider 包含供應(yīng)商編碼、名稱、描述、聯(lián)系人、電話、地址、傳真以及創(chuàng)建人、創(chuàng)建時(shí)間。訂單表 smbms_bill 是核心業(yè)務(wù)表包含訂單編碼、商品名、商品描述、計(jì)量單位、數(shù)量、總價(jià)、是否付款、供應(yīng)商 id以及創(chuàng)建和修改相關(guān)字段。字段命名看起來(lái)瑣碎但很有必要。createdBy、modifyBy 這些字段在后面的修改記錄功能里要用很多網(wǎng)上代碼為了省事刪掉了它們結(jié)果后來(lái)要追蹤數(shù)據(jù)變更就只能干瞪眼。3.2 外鍵不建物理外鍵的原因四張表之間有明顯的關(guān)聯(lián)關(guān)系用戶表 userRole 指向角色表 id訂單表 providerId 指向供應(yīng)商表 id。很多新手會(huì)想既然有關(guān)聯(lián)那就加上外鍵約束吧。實(shí)際項(xiàng)目里這套項(xiàng)目的常見(jiàn)做法是不建物理外鍵只做邏輯外鍵也就是字段值存在對(duì)應(yīng)關(guān)系但數(shù)據(jù)庫(kù)層面不強(qiáng)制約束。原因有二第一物理外鍵在刪除和更新時(shí)會(huì)帶來(lái)額外的約束判斷項(xiàng)目里我們刪除供應(yīng)商前要先檢查有沒(méi)有關(guān)聯(lián)訂單這個(gè)邏輯放在 Service 層控制更好提示也更友好第二邏輯外鍵讓拆庫(kù)、遷移、分表都更容易教學(xué)中也能更自然地引出 left join 聯(lián)查。如果你是在自己練手想加物理外鍵學(xué)習(xí)約束概念也沒(méi)問(wèn)題但在 smbms 這個(gè)項(xiàng)目里跟著主流做法走邏輯外鍵更省事。3.3 初始化數(shù)據(jù)與密碼存儲(chǔ)建完表一定要準(zhǔn)備初始化數(shù)據(jù)不然后面聯(lián)調(diào)全是空列表分頁(yè)、篩選都看不出效果。我放了 3 個(gè)用戶、2 家供應(yīng)商和 8 條訂單數(shù)據(jù)量剛好覆蓋兩頁(yè)方便測(cè)分頁(yè)邊界。密碼存儲(chǔ)這里要單獨(dú)說(shuō)一句。網(wǎng)上很多版本的 smbms 代碼里密碼是明文存的演示而已。但你自己做項(xiàng)目時(shí)建議至少封裝一個(gè) MD5Util把密碼加密后入庫(kù)登錄時(shí)先把用戶輸入的密碼 MD5 化再比對(duì)。這不是 smbms 要求的功能但這是一道安全底線練手項(xiàng)目也不能把明文密碼寫死在數(shù)據(jù)庫(kù)里。4. 骨架落地分層目錄、BaseDao 和基礎(chǔ)件先搭好環(huán)境就緒、表也建好了接下來(lái)是最重要的一步把代碼骨架搭起來(lái)。很多新手寫項(xiàng)目不講究包結(jié)構(gòu)所有類全堆在一起前期沒(méi)問(wèn)題寫到訂單模塊自己都找不到 Service 在哪。我建議從一開(kāi)始就按分層結(jié)構(gòu)來(lái)后面每個(gè)模塊的代碼都能精確落到對(duì)應(yīng)位置。4.1 包結(jié)構(gòu)與請(qǐng)求走向我用的包結(jié)構(gòu)是這樣的com.xxx.smbms ├── pojo // 實(shí)體類User、Role、Provider、Bill、PageSupport ├── dao // 數(shù)據(jù)訪問(wèn)接口 impl 實(shí)現(xiàn) ├── service // 業(yè)務(wù)接口 impl 實(shí)現(xiàn) ├── servlet // 控制層LoginServlet、UserServlet、ProviderServlet、BillServlet ├── filter // 過(guò)濾器UniversalFilter、LoginFilter └── util // 工具類JDBCUtil、MD5Util、常量類請(qǐng)求走向也很直白瀏覽器請(qǐng)求某個(gè) Servlet → Servlet 接收參數(shù)、調(diào) Service → Service 調(diào) DAO → DAO 操作 MySQL → 結(jié)果一層層返回 → Servlet 把數(shù)據(jù)塞進(jìn) request 或 session → 轉(zhuǎn)發(fā)到 JSP 頁(yè)面渲染。一開(kāi)始可能覺(jué)得分這么多層太繞但你要理解每一層的職責(zé)Servlet 不寫 SQLDAO 不寫業(yè)務(wù)判斷Service 不直接處理參數(shù)。好處是以后換數(shù)據(jù)庫(kù)、換前端、加緩存只需要?jiǎng)訉?duì)應(yīng)的一層。這套結(jié)構(gòu)其實(shí)就是后面 Spring 分層思想的雛形。4.2 數(shù)據(jù)庫(kù)工具類和 BaseDao 的作用JDBC 最麻煩的就是重復(fù)的加載驅(qū)動(dòng)、建連接、釋放資源。我參考網(wǎng)上常見(jiàn)寫法先寫一個(gè) BaseDao把通用邏輯收斂起來(lái)public class BaseDao { // 加載驅(qū)動(dòng) 獲取連接 public static Connection getConnection() throws Exception { return JDBCUtil.getConnection(); } // 通用增刪改支持可變參數(shù) public static int executeUpdate(Connection conn, String sql, Object... params) throws Exception { PreparedStatement ps conn.prepareStatement(sql); for (int i 0; i params.length; i) { ps.setObject(i 1, params[i]); } int result ps.executeUpdate(); closeAll(conn, ps, null); return result; } // 通用查詢返回 ResultSet 由 DAO 層自行封裝 public static ResultSet executeQuery(Connection conn, String sql, Object... params) throws Exception { PreparedStatement ps conn.prepareStatement(sql); for (int i 0; i params.length; i) { ps.setObject(i 1, params[i]); } return ps.executeQuery(); } // 釋放資源 public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) throws Exception { if (rs ! null) rs.close(); if (ps ! null) ps.close(); if (conn ! null) conn.close(); } }這里有一個(gè)容易被忽略的點(diǎn)查詢返回的 ResultSet 不能立刻關(guān)閉連接和 PreparedStatement因?yàn)榉庋b ResultSet 還需要時(shí)間。所以我一般不在 executeQuery 方法里直接 closeAll而是讓 DAO 層在拿到結(jié)果、封裝成對(duì)象之后再調(diào)用 closeAll 關(guān)閉。很多新手在 BaseDao 里統(tǒng)一關(guān)閉資源結(jié)果一跑就報(bào)ResultSet already closed這個(gè)坑我踩過(guò)。4.3 接口加實(shí)現(xiàn)這個(gè)習(xí)慣值得堅(jiān)持雖然項(xiàng)目很小但我建議 DAO 和 Service 都寫成接口 實(shí)現(xiàn)類的形式比如 UserDao 接口下有 UserDaoImpl。理由不是規(guī)范這種空話而是等你想把 JDBC 換成 MyBatis 的時(shí)候只需要重新寫一套 DAO 實(shí)現(xiàn)類Servlet 和 Service 層完全不用動(dòng)。我后面把 smbms 遷移到 MyBatis 時(shí)深刻體會(huì)到這個(gè)設(shè)計(jì)有多省事。前端 JSP 頁(yè)面里取值依賴實(shí)體類的 getter/setter 規(guī)范pojo 類里字段名和頁(yè)面調(diào)用名要保持一致這里踩過(guò)坑的人不少。5. 登錄主鏈路Session、Filter 和角色控制登錄模塊是整個(gè)系統(tǒng)最先要跑的鏈路也是后面所有模塊的入口。只要登錄和攔截做好整個(gè)系統(tǒng)的骨架就穩(wěn)了。5.1 登錄流程與密碼比對(duì)登錄頁(yè)收集 userCode 和 userPassword提交到 UserServlet 的 login 方法。Servlet 先做簡(jiǎn)單的空值校驗(yàn)然后調(diào)用 Service 層按 userCode 查詢用戶拿回 user 對(duì)象后比對(duì)密碼。這里要注意如果數(shù)據(jù)庫(kù)里存的是 MD5那么比對(duì)前要把用戶輸入密碼也 MD5 化一次不能拿明文直接和密文比較。登錄成功的處理也有講究。我把 user 對(duì)象放進(jìn) session而不是只放一個(gè) userId這樣 JSP 頁(yè)面里可以直接用 ${sessionScope.user.userName} 顯示當(dāng)前登錄人也能隨時(shí)通過(guò) user.userRole 判斷角色。登錄失敗時(shí)向前端返回錯(cuò)誤信息轉(zhuǎn)發(fā)回 login.jsp在頁(yè)面用 EL 表達(dá)式回顯錯(cuò)誤內(nèi)容。5.2 Filter 攔截和靜態(tài)資源放行如果登錄流程寫完了但沒(méi)有加 Filter那么只要知道接口地址不登錄也能直接訪問(wèn)所有頁(yè)面。smbms 里最常見(jiàn)的寫法是建一個(gè) LoginFilter作用于所有請(qǐng)求在 doFilter 里判斷public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; String uri request.getRequestURI(); if (uri.endsWith(.css) || uri.endsWith(.js) || uri.endsWith(.jpg) || uri.endsWith(.png) || uri.endsWith(login.jsp) || uri.endsWith(login)) { chain.doFilter(request, response); return; } HttpSession session request.getSession(false); if (session ! null session.getAttribute(user) ! null) { chain.doFilter(request, response); } else { response.sendRedirect(request.getContextPath() /login.jsp); } }靜態(tài)資源放行這個(gè)細(xì)節(jié)特別容易漏如果你直接攔所有請(qǐng)求登錄頁(yè)的 css、js 全部加載不出來(lái)頁(yè)面會(huì)變成光禿禿的 HTML。判斷關(guān)鍵詞可以再完整一點(diǎn)比如還要放行登錄時(shí)的驗(yàn)證碼接口等。在 smbms 里沒(méi)有注冊(cè)所以放行 login 相關(guān)的路徑就夠了。如果你用的是注解方式配置 Filter比如 WebFilter(/*)注意要和 Servlet 的 URL 映射區(qū)分開(kāi)。Filter 攔的是請(qǐng)求路徑Servlet 的 WebServlet 注解定義的是功能入口兩者配合使用不要互相覆蓋。5.3 退出登錄與角色權(quán)限退出登錄比較簡(jiǎn)單調(diào)用 session.invalidate() 把整個(gè)會(huì)話廢掉然后重定向到 login.jsp。這里不要去手動(dòng) removeAttribute因?yàn)?session 里可能還存了分頁(yè)參數(shù)、條件參數(shù)不清理干凈容易殘留。角色權(quán)限這塊smbms 的常見(jiàn)實(shí)現(xiàn)是JSP 導(dǎo)航菜單里用 JSTL 判斷當(dāng)前登錄用戶的 userRole如果 roleId 是管理員顯示用戶管理入口普通員工則只顯示訂單和供應(yīng)商模塊。后臺(tái)也需要做一個(gè)簡(jiǎn)單的校驗(yàn)比如刪除用戶這個(gè)操作如果不是管理員登錄直接拒絕。雖然在教學(xué)項(xiàng)目里前端隱藏菜單已經(jīng)夠用但補(bǔ)上后臺(tái)校驗(yàn)會(huì)讓你對(duì)權(quán)限控制有更完整的理解。6. 列表頁(yè)與分頁(yè)查詢用戶、訂單共用的一套套路看完登錄接下來(lái)是整個(gè)項(xiàng)目里最肥的一塊列表和分頁(yè)。用戶管理、供應(yīng)商管理、訂單管理都有列表頁(yè)而且都支持條件查詢和分頁(yè)。這一套邏輯想明白了后面三個(gè)模塊可以復(fù)制粘貼著寫。6.1 分頁(yè)參數(shù)和 Page 對(duì)象分頁(yè)本身不復(fù)雜但參數(shù)多理清關(guān)系很重要。需要四個(gè)數(shù)totalCount 總記錄數(shù)、pageSize 每頁(yè)條數(shù)、currentPageNo 當(dāng)前頁(yè)、totalPageCount 總頁(yè)數(shù)。int totalCount userDao.getUserCount(userName, roleId); int pageSize 5; int totalPageCount (totalCount pageSize - 1) / pageSize; int currentPageNo 1; String pageIndex request.getParameter(pageIndex); if (pageIndex ! null !.equals(pageIndex)) { currentPageNo Integer.parseInt(pageIndex); } if (currentPageNo 1) currentPageNo 1; if (currentPageNo totalPageCount totalPageCount 0) currentPageNo totalPageCount; int begin (currentPageNo - 1) * pageSize;總頁(yè)數(shù)的計(jì)算公式 (totalCount pageSize - 1) / pageSize 是向上取整的意思這樣 8 條數(shù)據(jù)每頁(yè) 5 條算出來(lái)就是 2 頁(yè)而不是 1 頁(yè)。這個(gè)邊界細(xì)節(jié)很多人會(huì)在寫代碼的時(shí)候栽一跤。我把這四個(gè)參數(shù)連同查詢列表一起封裝成一個(gè) PageSupport 對(duì)象放回 request 里JSP 頁(yè)面統(tǒng)一取 pageSupport.totalPageCount、pageSupport.currentPageNo 這樣的屬性。這種對(duì)象化封裝的好處是不同模塊的頁(yè)面模板長(zhǎng)得一樣改樣式只需改一處。6.2 動(dòng)態(tài) SQL 拼接與條件回顯列表?xiàng)l件查詢的核心在 DAO 層。以用戶管理為例支持按姓名模糊查詢、按角色篩選SQL 要?jiǎng)討B(tài)拼接StringBuilder sql new StringBuilder( select u.*, r.roleName from smbms_user u left join smbms_role r on u.userRole r.id where 11); ListObject params new ArrayList(); if (userName ! null !.equals(userName)) { sql.append( and u.userName like ?); params.add(% userName %); } if (roleId 0) { sql.append( and u.userRole ?); params.add(roleId); } sql.append( order by u.creationDate desc limit ?, ?); params.add(begin); params.add(pageSize);where 11 這種寫法老項(xiàng)目里很常見(jiàn)好處是不管有沒(méi)有條件后面的 and 都能直接接上去不用費(fèi)心去判斷是否拼接了第一個(gè)條件。條件回顯是另一個(gè)坑。翻頁(yè)的時(shí)候如果只把 pageIndex 傳給后端userName 和 roleId 沒(méi)有傳那么第二頁(yè)的數(shù)據(jù)就變成了沒(méi)有查詢條件的全部數(shù)據(jù)。我最初的實(shí)現(xiàn)就是直接在超鏈接里拼 URL結(jié)果中文姓名在地址欄里會(huì)亂碼。后來(lái)我改成在 JSP 里放一個(gè)隱藏表單分頁(yè)按鈕先用 JS 往隱藏字段里寫入當(dāng)前篩選條件再提交這樣既不會(huì)亂碼也保住了條件。這是一個(gè)很典型的頁(yè)面上沒(méi)報(bào)錯(cuò)數(shù)據(jù)卻不對(duì)的隱蔽 bug排查起來(lái)很費(fèi)神。6.3 訂單模塊的組合查詢訂單管理比用戶管理多兩個(gè)查詢條件商品名、供應(yīng)商、是否付款。邏輯和用戶管理一樣只是 SQL 里多幾個(gè)判斷if (productName ! null !.equals(productName)) { sql.append( and b.productName like ?); params.add(% productName %); } if (providerId 0) { sql.append( and b.providerId ?); params.add(providerId); } if (isPayment 0) { sql.append( and b.isPayment ?); params.add(isPayment); }訂單列表還會(huì)帶出供應(yīng)商名稱所以要用 left join smbms_provider。寫到這里想提醒一句查詢列表和查詢總條數(shù)這兩條 SQL 一定要保持一致。常見(jiàn)情況是列表 SQL 里加了一個(gè)條件統(tǒng)計(jì)總數(shù)的 SQL 忘加結(jié)果就是頁(yè)面頂部顯示共 20 條翻頁(yè)卻只有 10 條。我在復(fù)現(xiàn)時(shí)真真切切踩過(guò)后來(lái)把查 count 和查 list 的兩個(gè)方法放在一起維護(hù)每次改條件都同步改兩個(gè)方法。7. 供應(yīng)商與訂單的增刪改那些容易漏掉的細(xì)節(jié)列表和分頁(yè)打通之后剩下的就是新增、修改、刪除這幾個(gè)動(dòng)作。這幾個(gè)動(dòng)作看起來(lái)是 CRUD 的機(jī)械重復(fù)但里面藏著不少不寫一遍就不會(huì)注意的細(xì)節(jié)。7.1 先查關(guān)聯(lián)再刪除供應(yīng)商數(shù)據(jù)的刪除是最容易破壞數(shù)據(jù)完整性的操作。如果某個(gè)供應(yīng)商下已經(jīng)存在訂單直接 delete provider那么訂單表里這個(gè) providerId 就變成孤數(shù)據(jù)了。所以刪除前一定要先查訂單表int billCount billDao.getBillCountByProviderId(providerId); if (billCount 0) { // 返回該供應(yīng)商下存在訂單不能刪除 } else { providerDao.deleteProviderById(providerId); }這個(gè)邏輯看起來(lái)簡(jiǎn)單但它觸及了一個(gè)非常本質(zhì)的問(wèn)題業(yè)務(wù)層面的完整性校驗(yàn)不能完全依賴數(shù)據(jù)庫(kù)約束。外部系統(tǒng)、批處理腳本、管理后臺(tái)都可能繞過(guò)頁(yè)面直接操作數(shù)據(jù)所以在 Service 層主動(dòng)做約束校驗(yàn)是最通用的兜底方案。7.2 修改時(shí)的 created/modify 字段網(wǎng)上很多版本的表單修改只更新業(yè)務(wù)字段比如用戶名、電話、地址完全不碰 createdBy、modifyBy、creationDate、modifyDate。這會(huì)導(dǎo)致一個(gè)問(wèn)題數(shù)據(jù)明明被改過(guò)了卻沒(méi)有任何痕跡。我建議修改操作至少做到兩點(diǎn)更新 modifyBy 為當(dāng)前登錄用戶 id更新 modifyDate 為當(dāng)前時(shí)間新增操作則要填 createdBy 和 creationDate。這可以說(shuō)是把表設(shè)計(jì)的價(jià)值真正用起來(lái)。用戶表還有一個(gè)特別容易翻車的字段birthday。前端日期選擇器提交的格式是 yyyy-MM-dd后端如果直接往 DATE 字段里 setString有些驅(qū)動(dòng)版本會(huì)報(bào)類型轉(zhuǎn)換錯(cuò)誤。穩(wěn)妥做法是在 Servlet 里先 SimpleDateFormat 解析成 java.util.Date再通過(guò) PreparedStatement.setDate 轉(zhuǎn)成 java.sql.Date 傳入。字符串和日期類型的轉(zhuǎn)換是 CRUD 模塊里新手報(bào)錯(cuò)最多的地方之一。7.3 Ajax 刪除訂單一個(gè)值得嘗試驗(yàn)證的前后端交互smbms 的訂單刪除環(huán)節(jié)很適合用來(lái)演示最簡(jiǎn)單的 Ajax。頁(yè)面點(diǎn)擊刪除按鈕后用 jQuery 發(fā) POST 請(qǐng)求到 BillServlet 的 del 方法后端刪除成功后返回字符串 success前端根據(jù)返回結(jié)果刷新頁(yè)面。function deleteBill(id) { if (confirm(確定刪除這條訂單嗎)) { $.post(${pageContext.request.contextPath}/bill.do, { method: del, id: id }, function (res) { if (res success) { location.reload(); } else { alert(res); } } ); } }對(duì)應(yīng) Servlet 端最后就是response.getWriter().write(success)。這個(gè)動(dòng)作本身不難但它是前端異步請(qǐng)求、后端返回字符串、前端局部刷新的雛形。如果你后面要做前后端分離這個(gè)小小的 Ajax 交互就是第一個(gè)熱身。我遇到的坑是Servlet 跳轉(zhuǎn)和返回普通文本的邊界。刪除成功后如果代碼里不小心寫了response.sendRedirectAjax 拿到的就不是 success 而是頁(yè)面內(nèi)容回調(diào)函數(shù)永遠(yuǎn)走不到正確分支。所以后端在處理 Ajax 請(qǐng)求時(shí)只寫數(shù)據(jù)不做頁(yè)面跳轉(zhuǎn)。8. 部署到 Tomcat從本地到瀏覽器首訪的驗(yàn)證步驟代碼寫完最后一步是把項(xiàng)目部署到 Tomcat 上真正通過(guò)瀏覽器訪問(wèn)。這一步對(duì)新手來(lái)說(shuō)往往比寫代碼更折磨因?yàn)槌鰡?wèn)題的時(shí)候控制臺(tái)不一定會(huì)報(bào)錯(cuò)頁(yè)面就給你一個(gè) 404 或 500。8.1 war 包與 IDEA 集成 Tomcat有兩種部署方式可以選。第一種是直接用 Maven 構(gòu)建 war 包扔到 Tomcat 的 webapps 目錄下啟動(dòng) Tomcat 后會(huì)自動(dòng)解壓部署。第二種是在 IDEA 里配置 Tomcat Servlet用 war exploded 部署開(kāi)發(fā)時(shí)改代碼能更快見(jiàn)效果。我建議先學(xué)會(huì)方式二配合 IDEA 調(diào)試斷點(diǎn)能直接打在 Servlet 代碼上排查問(wèn)題效率高。具體配置路徑前面已經(jīng)說(shuō)過(guò)關(guān)鍵點(diǎn)在于 Artifacts 要和 Web Facet 關(guān)聯(lián)缺了這一步Tomcat 能啟動(dòng)但找不到頁(yè)面。8.2 常見(jiàn)部署報(bào)錯(cuò)對(duì)照表把我在復(fù)現(xiàn)過(guò)程中遇到的幾類高頻問(wèn)題整理成了一張表現(xiàn)象可能原因處理方式ClassNotFoundException: com.mysql.cj.jdbc.DriverMySQL 驅(qū)動(dòng)沒(méi)引入或版本舊檢查 pom.xml 和 war 的 lib 目錄Access denied for user rootlocalhost賬號(hào)密碼不對(duì)或未授權(quán)檢查 jdbc.properties頁(yè)面 404Artifact 配置缺失/context 路徑不對(duì)檢查 IDEA 部署配置和訪問(wèn)路徑中文亂碼缺少字符集過(guò)濾器或數(shù)據(jù)庫(kù)連接串沒(méi)配編碼加 Filter檢查 url 的 characterEncodingPort 8080 already in use端口被占用改端口或結(jié)束占用進(jìn)程ResultSet already closed查詢后提前關(guān)閉了連接按 BaseDao 的關(guān)閉順序調(diào)整字符集這個(gè)問(wèn)題值得展開(kāi)一下。除了數(shù)據(jù)庫(kù)連接串的編碼參數(shù)代碼里通常還會(huì)有一個(gè)字符集過(guò)濾器在 doFilter 里執(zhí)行request.setCharacterEncoding(UTF-8)和response.setCharacterEncoding(UTF-8)。如果漏掉這個(gè) Filter表單提交的中文數(shù)據(jù)會(huì)在進(jìn)入 Servlet 之前就亂掉后面再怎么處理都救不回來(lái)所以它必須放在請(qǐng)求處理的最前面。8.3 每次啟動(dòng)前的小檢查清單部署次數(shù)多了之后我養(yǎng)成了一個(gè)習(xí)慣每次啟動(dòng)前花十秒鐘過(guò)一遍這三項(xiàng)。第一jdbc.properties 里的賬號(hào)密碼是否正確MySQL 服務(wù)有沒(méi)有啟動(dòng)第二Tomcat 端口是否被占用第三數(shù)據(jù)庫(kù)里有沒(méi)有初始化數(shù)據(jù)。八成的問(wèn)題都出在這三件事上。如果你訪問(wèn)的是 login.jsp但頁(yè)面里引用的 css、js 路徑全是 /css/xxx 這種絕對(duì)路徑就會(huì)出現(xiàn)樣式丟失。因?yàn)椴渴鸷箜?xiàng)目名是 smbms正確的路徑應(yīng)該是 /smbms/css/xxx。最穩(wěn)妥的寫法是在所有 JSP 頁(yè)面統(tǒng)一用${pageContext.request.contextPath}拼路徑這樣不管部署在哪個(gè) context 下都不會(huì)錯(cuò)。9. 跑通之后還能怎么走往 MyBatis 與 Spring 生態(tài)遷移smbms 完全跑通以后等于你親手徒手搭了一個(gè) JavaWeb 應(yīng)用。這時(shí)候千萬(wàn)別急著把它丟到一邊它是最好的進(jìn)化素材。9.1 替換 DAO把 JDBC 換成 MyBatis我做的第一個(gè)改造是把原生 JDBC 的 DAO 實(shí)現(xiàn)替換成 MyBatis。因?yàn)榍懊媪袅?DAO 接口所以 Servlet 和 Service 層幾乎不用改只需要寫新的 mapper 文件和實(shí)現(xiàn)類然后把 Service 里 new 出來(lái)的 DAO 實(shí)現(xiàn)類換成 MyBatis 版本。這個(gè)改造過(guò)程會(huì)讓你真正理解 ORM 框架省掉的到底是什么連接管理、SQL 執(zhí)行、結(jié)果集到對(duì)象的映射。寫一遍之后你再去看 MyBatis 的動(dòng)態(tài) SQL會(huì)發(fā)現(xiàn)和你在 smbms 里手寫的 if 拼接邏輯一模一樣。當(dāng)然遷移過(guò)程中也有幾個(gè)容易翻車的點(diǎn)。MyBatis 的if testuserName ! null and userName ! 判斷邏輯要和原 JDBC 版本保持一致比如模糊查詢里是否拼接 like、% 放在哪一邊這些細(xì)節(jié)不對(duì)就會(huì)查出完全不同的結(jié)果。另外分頁(yè)的 limit 參數(shù)在 MyBatis 里要顯式標(biāo)注類型不然某些驅(qū)動(dòng)會(huì)報(bào)參數(shù)類型不明確這類問(wèn)題排查起來(lái)往往要靠翻日志。9.2 前后端分離與 Spring 化smbms 作為腳手架的價(jià)值再進(jìn)一步可以把 JSP 全部換成純前端頁(yè)面后端只提供 JSON 接口。登錄、分頁(yè)、模糊查詢這些功能你已經(jīng)知道怎么做只是把返回格式從 JSP 頁(yè)面變成 JSON 字符串。這個(gè)練習(xí)做完了Spring Boot 里最基礎(chǔ)的 Controller 寫法對(duì)你來(lái)說(shuō)就沒(méi)有任何神秘感。如果還不滿足后面也可以把 Servlet 替換成 Spring MVC把 Service 交給 Spring 容器管理。這樣一套遷移走下來(lái)你等于用 smbms 這個(gè)骨架把整個(gè) JavaWeb 進(jìn)化史重走了一遍。我后來(lái)把這次復(fù)現(xiàn)的代碼給過(guò)幾個(gè)新人參考他們問(wèn)得最多的其實(shí)不是登錄或者分頁(yè)而是動(dòng)態(tài) SQL 拼接那段到底為什么這么寫。遇到這種情況我的建議永遠(yuǎn)只有一個(gè)別急著背把拼接出來(lái)的 SQL 打印到控制臺(tái)對(duì)照日志看一遍比對(duì)著屏幕猜十遍都有用。這一步做完smbms 對(duì)你就不是一個(gè)視頻里跑過(guò)的項(xiàng)目而是真正屬于你自己的第一份 JavaWeb 工程了。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
五月激情基地| 91丨九色丨白浆秘| 五月丁香色色网| 国产人妻人伦精品一区二区| 九色91国产| 超碰在线观看99| 蜜臀A∨在线水帘洞| 刘玥av在线| 亚洲综合五月天婷婷| 99色区| WwW色婷婷| 99热这里都是精品| 婷婷五月天国产| 少妇日麻屄| www.久久9| 性一交一乱一交A片久久四色| 开心五月婷| 99欧州偷拍视频| 中国女人做爰A片| 欧美三日本三级少妇三99| www.俺去也com| 五月丁香久人妻中文| 激情五月婷婷色综合| 欧洲亚洲精品| 九九精品免费| 久久五月丁香| 五月天色五月| 日日操夜夜撸| 婷婷五月色播| 伊人99热| 97精品人人A片免费看| 99精品热| 五月丁香六月色| 六月丁香综合| 婷婷丁香花五月天| 日韩欧美颜射| 免费AV播放| 亚洲秘 无码一区二区三区妃光/1| 亚洲女婷婷五月基地综合久久久| 色欲日日躁| 99色在线| 日韩狠狠色婷婷| 亚洲六月婷婷| 亚洲成人综合在线| 人妻久久久久久| aa久久| 激情五月天小说| 婷婷深爱五月天在线| 五月天色播网| 天天干-天天日| 操笔无码| 五月草影视| 热99视频| 亚洲无码yw| 99国产精品久久久久久久久久久| 天天干天天操天天拍| 激情五月丁香社区| www.91久久| 国产精品色色| 99热在线播放精品| 狠狠五月激情丁香六月| 婷婷放心五日爱| 啪啪啪综合网| 久久欧洲综合网| 丁香五月婷婷在线视频| 天天爱天天狠天天透| 五月天丁香成人社| 欧洲色区| 午夜婷婷久久 | 色婷婷九月| 狠狠干夜夜干| www,五月丁,com| 五月天婷婷日日爱| 狠狠色噜噜色狠狠狠综合久久成人波| 91AV婷婷| 日韩黄在免| 97AV人人插人人操| 人人亚洲| 五月天婷婷基地| 日日干天天| 久久婷五月婷| 91操黄| 九九视频在线观看视频在线播放69| 日韩av高清| 丁香五月天婷婷91| 婷婷深爱五月亚洲综合| 色五月婷婷91| 成人草榴视频| 五月丁香猫咪久久婷婷综合视频激情四射网入口| 91美女被操| 国产五月丁香在线| 婷婷另类小说| 亚洲AV影片在线观看| 丁香久久激情俄| 色日本综合| 婷婷五月天成人在线视频| 操逼福利视频| 99亚州综合精品成人网| 丁香六月激情综合网| 亚洲av综合网| 丁香涩涩爱| 999精品乱码77777| 99热中文字幕久久| 99日韩| 狠狠婷婷日韩| 色国产五月| 情趣视频66| 丁香五月Av| 激情综合丁香六| 久久久久婷婷| 99亚洲精品| 丁香五月天社区| 97超美国视频在线观看| 亚洲色爽| 天天日天天舔| 91综合国免费久入| 97干视频在线| 中文字幕黄色电影网址| 婷婷五月伦理网站| 九色综合网| 国产精品久久99| 婷婷五月色情天| 色婷婷丁香五月| 九月婷婷综合在线| 激情五月天激情综合网| 乱乱av| 九九青青草成人| 激情小说五月欧美亚洲丁香| 91肏肏肏| 久久五月丁香综合17C| 日韩成人AV在线播放| 碰超亚洲| 色久综合天天做视频| 九九视频这里只有精品| 亚洲99热| 2015超碰| 色色丁香五月天| 超碰成人在线免费观看| 激情综合丁香五月| 成人人操| 五月停停色色丁香| 久久婷婷成人| 国产成人99久久亚洲综合精品| 五月丁香婷婷综合网色欲| 国产va在线视频| 九月丁香婷婷| 26uuu.| 操人91| 日韩无码人妻一区二区| 99热精品在线| 色婷婷久久| PORNY九色9l自拍视频成人| 婷婷丁香综合| 996er热| 99热综合在线| 日本一级黄色电影| 婷婷激情丁五月| 国产精产国品一二三在观看| 17.c黄色| 97热精品| 99爱在线视频| 丁香五月网在线观看| 免费无码毛片一区二区A片| 99色激| 九九免费视频| 婷婷深爱五月亚洲综合| 天天爽免费视频| 嫩草极品| 婷婷激情五月| 天天人人综合| 伊人久久婷婷五月综合97色| 99爱在线精品视频免费观看| 亚洲色碰| 九九九九九999999| 五月丁香六月婷婷啪啪| 激情五月婷婷丁香六月| 丁香五月综合狠狠| 丁香激情五月| 丁香婷婷偷拍| 色99免费视频中文| 超碰在线国产| 婷婷久久草| 丁香色影院| 精品久久9| 99久久精| 一本狠婷婷综合| 七七色色综合| 另类小说婷婷色| 伊人天堂婷婷| 天天日夜夜| 天天成人丁香美女AV| 狠狠色噜噜色狠狠狠综合色| 久色资源| www.久热| 99热在线中文字幕| 成人AV免费观看| 色色色热| 91玖玖| 99这里只有精品视频在线| 国产淫熟妇| 久久大大香| 人人爱人人草| 五月天中文网| 色婷婷婷av| 免費观看aV在线网址| 婷婷色导航| 99热这里只有精品268| 丁香8月手机综合| 婷婷色色丁香五月天| 色色色色色级无码| 久久99婷婷| AV大片在线播放| 成人在线视频一区| 五月开心深深爱激情综合| 婷婷五月天堂| 五月丁香综合影院| 久9久视频精品| 色色色色五月| 亚洲天堂大香蕉| 激情综合网,婷婷| 五月丁香婷婷综合网色欲| 99无码黄色视频| 桔色成人在线| 婷婷爱婷婷| 怡红院 久久| 色综合久久8| 九九色婷婷| 日本色色网站| 欧美婷婷综合| 婷婷5月九九| 婷婷五月天在线看| 狠狠综合久久| 中文精品在| 国产一区男女| 亚洲性爱99在线| 九九精品99| 丁香狠狠操| 亚洲av| 国产看真人毛片爱做A片| 五月婷婷久久大香蕉| 好好干av| 99久久九九| 婷婷丁香六月激情综合| 日本在线免费中文com.| 欧美激情五月天在线观看| 色天堂A| 婷婷综合偷拍| 久久免费试看120秒| 伊人久久丁香狠狠婷婷综合香蕉| 色色欧美色色色| 99久久九九| 五月婷婷五月| 婷婷激情五月| 国产精品18久久久| 五月激香蕉网| 一婬一伦一区二区三区| 成人在线综合| 99精品在线| 色九月婷婷综合| 狠狠爱婷婷丁香| 久久9RE热视频精品98| 久久99免费视频| 天天综合区| 激情玖玖综合网| 丁香婷婷AV| 丁香五月婷婷综合啪啪| 99热久久日本| 9l视频自拍9l九色9l成人| 深爱五月激情| 91丨九色丨大屁股| 成人中文网| 99热10在线高清播放| 伊人久久丁香狠狠婷婷综合香蕉 | 91视屏在线观看com.wwwvv| 人妻久久久久久久久妻久久久久久久久 | 五月婷婷六月激情在线| 亚洲国产色色| 日本色色网站| 国产1区2区3区| 香蕉久久国产AV一区二区| 99熟女啪啪视频| 亚洲人人操| 激情丰满熟妇五月| 婷婷五月激情欧美大胆视频| www.minyis.com【JT】国内CDN落地页保证转化QQ2101460746 | 亚洲天堂啪啪| 婷婷五月亚洲综合| 久久九色| 久久五月丁香婷婷| 五月色亭丁香| 色情五月天se| 日日狠夜夜狠| 淑女丝袜bi操逼123| 激情综合六月| 国产密乳av一区二区三区四区| 九九精品在线网| 狠狠色官网| 国产阿姨日皮艹逼内射视频| 先锋男人99资源| 99高级会所久久| tingtingjiqingwuyue| 九九99在线观看视频| 婷婷色六月| 久久婷婷国产| 99色色视频| www.99热| 久草婷妨| 色色色在线观看| 狠狠色97| 5月婷婷综合| va中文资源在线观看| 怡红院院在线导航网| 激情婷婷综合| 丁香月六月| 26uuu精品一区二区| 99这里只有精| 99久re热视频精品98| www久| 久久国产色| 成人做爰高潮A片免费视频| 无码人妻AV久久久一区二区三区| 综合在线观看99| 亚洲激情六月丁香| 99精品国产热久久91色欲| 9999久久久久| 五月天激情国产综合AV| 亚洲第一综合| 爱射综合| 99资源人人| 在线观看av网站| 日本三级中国三级99人妇网站| 亚洲精品网站色视频| 六月丁香射婷婷欧美色图片| 九九热在线观看视频| 91ncm视频| 婷婷伊人綜合中文字幕| 色色草97| 狠狠艹狠狠艹| 五月丁香六月情| 久久99婷婷| 天天在线久久综合 | 激情五月婷婷五月| 色情成人五月天| 久99久视频免费观看| 99久久久国产大片区| 天天舔天天插天天干| 五月丁香成人网| 色99视频| 婷婷欧美激情| 亚洲婷婷丁香五月视频| 婷婷五月丁香91| 欧美激情性做爰免费视频| 日操夜操天天操不卡| 9月色婷婷| 亚洲天天免费| 色呦呦美女| 亚洲成av人影院| 99人人操人人爱久久久| 影音先锋 91工厂| 开心婷婷五月| 五月天丁香久久综合| 内射综合网| 亚洲五月天狠狠| 激情久久久久久久久久| 九九九九热99超碰| 思思热99er在线视频| 国产激情综合五月久久| 曰韩五月丁香色婷婷无码| 色综合久久88色综合天天99| 婷婷色正月| 搡BBBB搡BBB搡18| 九九99热| 人人操五月天| 情色五月天 网站| 亚洲一个色| 综合性爱网| 婷婷色5月天在线。| 99热1| 五月丁香综缴情性爱| 婷婷性爱| 日韩一级片| 99热官网精品在线| 婷婷丁香五月,狠狠综合| 婷婷丁香五月激情| 九九热欧美| 99亚州综合精品成人网| 人人操9| 婷婷丁香色五月天久久88| 五月丁香花视频| 婷婷五月丁香色色| 性做爰1一7伦| 五月天婷婷成人网| 五月色视频| 丁香五月区| 丁香久久九九99| 99免费视频精品| AV中文在线| 99自拍网| 99在线观看| 在线观看欧美| 欧美大香蕉视频| 超碰网站在线观看| 激情九九六月激情免费视频| 亚洲综合在线网站| 夜夜撸夜夜骑| 人妻激情网| www夜夜操com| 五月天婷婷涩涩| 六月丁AV| 久久玖玖综合| 久久五月激情综合| 玖玖综合网| 美女精品一级不卡视频| 久久99操| 婷婷丁香六月| 日日夜夜青青草| 欧美成人精品A片免费一区99| 婷婷六月丁香在线| 国产精品激情AV久久久青桔| 思思热热久久| 中文字幕综合色| 五月天久久丁香| 色播激情婷婷| 99re热在线观看| 国产精品成人AV在线| 欧美日韩成人高清在线| 大香蕉婷婷色| 九月婷婷综合| 久久久五月婷婷| 99色嘟嘟精品网站| 99精品在线观看| 99亚洲视频| 五月天激情图片| 久久伊人大香蕉| 五月婷婷色| 99re这里只有精品免费| 久婷狼色诱惑在线| 色色色网站| AV在线免费播放| 天天精品视频免费观看| 中文aV网| 五月天婷婷亚洲| 婷婷五月丁香综合激情| 99re这里只有精品免费| 日本97人人| 久久婷婷五月综合色丁香| 五月婷婷天堂| 国产在线aaa片一区二区99| 色婷婷先锋| 久久婷婷五月综合色丁香| 人妻AV在线观看| WWW·天天操·视频?| 成人免费黄色短视频| 99爱在线观看视频| av狠狠操| 婷婷激情五月天小说| 久久五月天丁香| 婷婷五月香蕉| 久久婷婷婷婷伊人| www.jiujiujiu| 99热99在线| 五月丁香花激情综合网| 99熟女视频| 国产亚洲精品久久久久苍井松| 天天综合社区| 一起草av| 五月婷婷丁香五月| 婷婷99狠狠| 99热这里全是精品| 激情丁香婷婷五月天| 伊人在线大香蕉网| 日韩aaaaa| 狠狠撸激情综合丁香五月天俺来啦| 殴美日韩成人| 色色色色欧美| 香蕉婷婷| 激情五月天婷婷丁香 | 丁香五月婷婷AV在线| 欧亚洲在线高清视频| 久热久69| 99热9| 五月久视频| 月婷婷亚洲| 538任你爽视频不一样的| 天天爱天天操| 欧洲亚洲免费视频9| 天天综合亚洲综合| 久久只有这里精品免费| 欧美性爱中文字幕| 婷婷福利影院| 99精品国产在热久久| 大香蕉久热| 五月丁香五月天现场视频| 91九色大屁股| 五月婷婷亚洲综合在线| 国产在线aaa片一区二区99| 日韩色五月| 天天舔天天摸视频| 日日射天天射| www.激情五月天.com| 99精品久久久久| 99re8热精品免费视频| 婷婷色六月| 可以看的av| 六月天六月婷| 久久激情综合| 久久久精品视频79| 色综合久久天天综合网| 一二区成人电影| 综合色、色综合| 91日本在线观看| 五月婷婷色影院| 久久视频这里有精品99| 99热这里只有精品最新| 日日夜夜噜噜爽爽| w婷婷五月婷婷w| ss五月天激情| www.天天干.com| 黄网网站在线播放| 92久久| 91婷婷五月丁香碰| 亚洲成人AV在线| 一本到不卡高清DVD| 无码日本精品XXXXXXXXX | 亚洲天天操| 69精品人人人人| Av九九| 超碰日日操| 无码99| 天天爱天天吃狠天天透| 桃色五月天| 激情五月天小说|五月天开心激情网|亚洲精品国产自在现线|黄色五月天 | 丁香五月激情五月| 五月激情婷婷四射| 天天肏天天肏| 激情五月色综合网| 99操无码视频观看| 国产精品久久..4399| 丁香色综合| 97视频.干com| 开心五月婷婷激情| 欧美久草在线日本一级特黄大片做受9在线观看韩国电影《两个女人》未删减-毛片 | 人妻五月天激情开心网| 丁香亚洲婷婷五月| 情婷婷五月天| 人人草人人爱| 97香蕉碰碰人妻国产欧美| 原琪琪色影院| 99无码视频| 久99| 久草丁香婷婷1024| 超碰无码老师| 色婷婷色情| 超碰人人艹| www.zbzhongsen.com| 99综合网| 日日射天天射| 91婷婷五月天嫩女| 99热日韩| 欧美 日韩 人妻 高清 中文| 色欲久久99精品久久久久久| 色婷婷综合电影| 性生活视频98791| 久久婷婷影院| 五月婷婷网久久| 丁香色综合| 色综合伊人网| 99爱在线视频| 日韩av免费版| 91色涩| 五月天色婷好好| 九玖欧洲亚洲| 亚洲婷婷基地| 极品少妇高潮啪啪AV无码| 五月婷婷碰碰| 亚韩在线视频| 天天综合天天玩夜夜玩天天玩夜夜玩| 久久丁香五月天| 五月丁香色色网| 亚洲日韩一页精品发布| 97热超碰| 亚洲第一色网站| 色噜噜狠狠狠综合曰曰曰| 五月花婷婷| 九九久久精品| 色婷婷影| 婷婷综合成人五月天| 深爱激情综合网| 色色网站在线| 在线sebiav精品视频| 伊人久久大香网| 99热综合在线观看| 97热在线精品| 国产av天天插天天操天天爽| 国产脫衣舞一区二区三区| 99热思思在线观看| 九九热最新| 专区无日本视频高清8| 成人一区在线观看| 我要色综合五月婷婷| 丁香婷婷激情五月天无毒不卡蜜桃| 五月丁香六月综合激情| 色五月大香蕉婷婷| 伊人干练久| 亚洲综合视频网| 久久A极片| 激情六月婷婷| 另类综合婷婷五月天欧美视频| 久草大| 日韩专区五月天婷婷丁香| 五月天丁香综合| 婷婷播播五月天| 99热主页日本| 亚洲天堂AV综合网| 華人性愛AV在線| 超碰99热精品| 亚洲九九99精品视频在线播放| 六月激情网| 激情五月综合免费| 成人在线综合| 久久亭亭电影| 天天爽天天弄| 婷婷激情综合| 久久九九国产| 婷婷精品性性性性性性性| 久久婷综合| 五月天狠狠色| 天天干天干| 五月天色综合| 国产综合色婷婷精品久久| VfJxEwPH| 99久久国产宗和精品1上映| 亚洲成人综合在线| 激情六月色| 97成人在线视频| xx色综合| 色五月网址| 99噜噜| 丁香五月色欲| 亚洲中文字幕在线电影| 九月婷婷综合八月丁香在线观看| 夜夜 操无码| 婷婷欧美激情| 久久精品亚洲一级牲爱综合| 大香蕉久久综合网| 婷婷六月激情啪啪| 欧美大肥婆大肥BBBBB| 亚洲、欧美、国产另类笫二区| 欧美色爱五月天| 好吊兆人妻| 色青青五月| 禁欲电影完整版在线播放| 天堂久久精品| www.9797国产| 天天操B| 五月天婷婷综合网| 久久丝袜婷婷| 啪啪黄页网| 色色色婷婷| 五月婷婷香| 大香蕉综合| 五月激情四射婷婷丁香| 亚洲人妻av| 丁香婷婷激情综合五月激情| 婷婷五月天色色| 五月丁香六月婷| 丁香五月激情婷婷婷婷在线观看| 182.t午在线观看| 久热2025无码| 欧美韩国日本| renre人人操国产超碰在线| 思思9久久| 午夜不卡成人一区二区| 色欲AVV| www.亚洲激情| 日本玖玖在线| 啪啪色区| 色综合九九色综合88| 91ncom.色| 六月色色| 国产人妻777人伦精品HD| 五月天婷综合网站| 国产精产国品一二三在观看| 婷婷五月婷婷五月| 最新国产AV| 影音先锋偷偷色男人站| 五月婷婷五月天| www色婷婷| 另类图片五月天婷婷| 1024国产在线| 丁香六月色婷婷| 91嫩草久久| 久操大香蕉| 在线国产精品色| 婷婷五月激情黄色| 亚洲色优| 六月99天天婷婷激情综合| 99无码视频| wwwwww.色| 97成人在线视频精品| 区美毛片子| 五月婷婷五月丁香综合| 婷婷五月久久| 9|无码久久久久久| 美女婷婷六月色| 六月色 亚洲| pom538精品视频| 无码网| 99操九九网| 色婷婷日本| 久久久久久草黄色片AV在线观看| 色欲久久99精品久久久久久| 在线婷婷| 色五月婷婷久久大| 六月丁香综合| 超碰在线免费观看日韩| 97热这里精品在线视频| 丁香五月色综合色播五月| 91碰免费视频| 丁香婷婷影院| 天天综合亚洲| 七七九九色色| 99碰碰中文| 最近中文字幕大全免费版在线| 色欲天天综合| 另类五月婷婷| 加勒比日本一区二区三区| 狠狠干综合| 五月亭亭狠狠| 中文字幕成人| 99热国产婷婷| 精品国产乱码久久久久夜深人妻| 9热精品| 丁香五月第九色| 六月婷欧美| 亚洲色无码A片一区二区麻豆| 香蕉操亚洲| 热久久66| 色色网站免费在线视频| 久久中国毛毛片爱久久| 日本乱子人伦在线视频| www.99热在线观看| 欧美久久婷婷| 五月天无码视屏播放| 免费看无码视频A级| 我淫我色婷婷五月天激情四射| 色婷操逼| 色婷婷五月天久久| 欧美五月丁香在线观看| 激情五月天婷婷直播| 91窝窝| 5月丁香美女影院| 五月婷婷六月丁香综合在线| 狼人婷婷久久| 久久人妻伦理| 国精产品一区二区三区| 天天肏屄夜夜爽| 玖玖爱伊人| 91九色PORNY中文啦| 国外亚洲成AV人片在线观看| 亚洲精品大片| 久9免费视频| 99热手机在线精品| 激情婷婷五月天在线观看| 玖玖在线资源视频| 久操大香蕉| 夜夜大香蕉婷婷丁香| 国成人网| 草榴视频黄色网| 超碰v| 色噜噜狠狠色综无码久久合欧美| 成人国产综合| 久婷| 九九热99免费视频| 色色色五月婷| 婷婷亚洲综合| 五月天激情网图片| 婷婷五月天激情电影小说| 天天色域综合网| 婷婷五月精品在线| 五月天影院婷婷在线观看| 成人色五月天婷婷| 综合狠狠干| 亚洲一级色电影| 99超碰人人| 色www.con| 99久免费视频| 97色在线观看视频| www99在线观看视频| 在线网黄| 婷婷九九| 这里只有精彩小视频视频网站| 婷婷激情综合| 99热这里只有精品26| 玖玖在线视频福利| 熟女激情网| 激情宗合哪里能看| 影音先锋激情网| 六月色狠狠色| av性爱在线| 婷婷五月天成人网站| 国产三级秋霞| 五月天综合久久| 六月婷婷av| 狠狠色丁香| 天天操夜夜操| 日本黄 色 片| 超级碰人人操人人干| 狠狠 久久| 91色在线| 久热九九| 天色综合网站| 99热这里只有精品无码| 99热思思| 99久久婷| 成人精品视频99在线观看免费 | 国产人妻人伦精品一区二区| 综合久久十三| 色婷大香蕉| 97碰| 国产精品久久99| 日韩小视频在线99| 综合久久五月天| 99久久网站| 色优久久| 91久久精品视频| 婷婷久久五月天丁香| 久久久久久天天日天天爱| 99热这里是精品| 婷婷五月天六月| 五月天综合在线观看| 国産精品| 色色色热| 激情九九九九| 影音先锋色婷婷| 丁香五月天欧美| 夜夜撸天天操| 天天插综合| 666555。COm毛片| 综合99视频| 思思视频这里是精品| 五月激情六月宗合| 大香蕉520| 无码字幕中文| 99碰网站| 五月丁香六月情婷婷久久| 欧美黄色AA片哗啦啦啦| 九九RE视频在线精品| 99热午夜精品| 级情九色| 日本婷婷综合精品| 操日视频| 5月丁香综合图区| 色婷婷精品视频| 色五月天综合| 婷婷色在线视频| 99ree6| 97色色综合| 色播五月丁香婷婷| 大香蕉伊人99| 成人丁香婷婷| 伊人91| 激情伊人五月婷婷久久| 色情丁香五月婷婷精品| 26uuu色五月| 99视频内射三四| 99热这| 丁香五月色情| 九九热啪啪| 色噜噜狠狠狠综合曰曰曰| 色五月婷婷老师| 麻豆精品| 狠狠色婷婷六月激情网| 五月激情小说网| 伊人五月综合网| 99综合99| 久久丁香五月天| 五月婷婷av在线| 婷婷色五月综合丁香| www.maotanji.com| 在线综合亚洲欧美65| 九九热这里只有精品556| 99操逼| 久久ri精品| 亚洲艹网| 超碰精品在线| 2013AV天堂| 欧洲第一久色| 专区无日本视频高清8| 91日本在线观看| 五月婷婷69| 欧美97超碰| 久99热| 丁香九月婷婷综合| 特级操b片| 天天天天天久久久久久| 日韩av手机在线观看| 入口五月婷婷六月香| 爽极品色| 91人碰| 强伦轩人妻一区二区电影| 亚洲乱码日产精品BD| mmm1717.6dbm人人爱人人操| 精品婷婷| 色婷婷综合久久久久| 操人久久| 五月色亚洲| 色婷婷久久综合久色综| 99久久综合狠狠综合久久| 内射丰满人妻| 极品少妇高潮啪啪AV无码| 欧亚色色| 91蜜桃婷婷狠狠久久综合9色| 强伦轩人妻一区二区电影| 激情六月婷| 久久91久久精品久久| 狠狠狠狠狠操| 亚洲妇女熟BBW| 五月丁香直播| 男女啪啪做爰高潮无遮挡| 五月婷婷六月激情在线| 色九区| 婷婷色五月亚洲| 亚洲国产精品二二三三区| 五月天天天操天天爽夜夜操| 任你草| 电影《战争与艾拉》免费观看| 婷婷丁香五月综合| 天天舔天天插天天爱| 91九色网| site:wpjngj.com| 国产精品久久久久久久久久| 五月婷婷干| 色网五月婷婷| 九九99一区| AV在线不卡网站| 天天干天天插| 91久久五月天| 99re思思热久久| 五月天婷婷免费| www.五月.com| 情婷婷五月天在线| 亚洲色无码A片一区二区麻豆| 久久草婷婷丁香网站| 91九色偷拍| 天天色天天日| 日本一级特黄大片AAAAA级| 91久操| 婷婷六月综合在线| 丁香六月婷婷缴情欧美| 婷婷六月啪啪| 久久性刺激| 综合色99| 婷婷五月天激情小说网站| 久久久久久久久久久久久久久久久精典| 丁香婷婷色情社区成人小说| 国产亚洲色婷婷久久99精品9j| 九色PORNY自拍成人精彩视频| 欧美精品999| 国产AV一区二区三区日韩| 五月欧美色色五月| 人妻激情视频| 这里只有精品2| 思思综合热| Caop在线| 婷婷伊人网| 婷婷五月久久| 影音先锋天天日| 99在线免费视频| 激情五月激情综合俺也去婷婷小说| 91妻人人爽人人看片| WWW.桔色成人.COM| 99小视频| 激情玖玖综合网| 色综合天堂| 六月婷婷狠狠色在线观看| 五月丁香六月婷婷综合| 久久婷婷五月天懂色| 亚洲瑟瑟精品在线| 97艹| 五月香婷婷| 丁香五月天欧美| 97人人搞| 亚洲狠9| 日韩av在线免费观看| 亚洲综合干| 人人操人人看97干| 亚洲日韩一页精品发布| 五月婷婷丁香六月| 色色影院aaaav| 99人人操人人爱久久久| 裸睡玩奶头(高H)| 少妇人妻人伦A片| 、激情六月天| 免费看片操逼| 99噜噜噜在线播放| 婷婷 伊人 久久| 久久婷婷婷婷伊人| 成人av中文字幕| 五月丁香另类网| 婷婷久久五月| 色色色色色网| 天天色天天噜| 五月天激情影院| 91在线观看www| http:色情日本com| 日本啪啪网| 深爱激情婷| 26UUU成人网| 人伦30P| WWW.开心五月天.COM| 伊人狠狠色婷婷综合丁香一区| 风流少妇A片一区二区蜜桃| 无码动漫av| 26uuu国产激情视频| 青青草a在线| 五月婷激情影院| 色婷婷亚洲综合天堂| 狠狠色噜噜狠狠狠狠综合| 日本九九网| 亚洲色激情| 婷婷五月天日本国产| 九色PORNY自拍成人精彩视频| 91操操| 色欲久久综合| 九九干视频| 丁香婷婷在线| 色香五月天| 亚洲精99| 97在线精品| 五月婷中文字幕| 五月婷婷丁香综合,亚洲天堂| 中文字幕丰满孑伦无码专区| 91色婷婷综合久久中文字幕二区| nvrentiantang av| 日韩在线婷婷五月天综合| 日日干综合| bbwcuckold精品熟妇| 一级黄色影片| 99资源在线视频| 五月婷婷婷| 九九综合图片网| 精品综合网在线| 青青草青青草五月天| 五月丁香成人网| 久久思思热| 色婷久久| 日本一级一级一级一级| 91人碰| 大香蕉婷婷五月| 久久婷丁香五月| 婷婷五月天影院| 天天色粽合合合合合合合| 天天射射夜| 久久只这里有精品| 狠狠色噜噜狠狠狠888了| 五月熟妇婷婷久久| 五月天色婷婷小说| 激情五月天免费视频| 五月婷婷熟女| 激情综合丁| 五月婷婷啪| 丁香五月网站| 超黄亚洲瑟瑟网站| 婷婷五月在线免费| 午夜理论片最新午夜理论剧 | 男女免费视频999| 九九大香视频| 在线观看av网站| 丁香五月天堂| 青青操绿aaa一区日v| 日日操夜夜爽白洁| www·五月天| 99这里有精品视频3| 五月天婷婷色紫薇阁| 亚洲九九九九| 激情五月婷婷中文字幕| 人妻自慰高清合集| 日本色爽| 亚洲色色色| 综合色久| 极品少妇高潮啪啪AV无码| 99精品视频在线观看| 六月色丁香婷婷| 老师把我爽高潮了免费A片| avv在线| 激情综合婷婷| 激情综合五月激情XXXX| 颜射 精品性爱av| 五月婷婷影| 色五月成人| 99热这里只有精品1| 极品人妻XXXXOOOO| 婷婷五月丁香青青草在线| yazhochengrenavwang| 91se在线视频| 天天综合色丁香| 五月丁香狠狠| 五月丁香激情婷婷| 亚洲热视频在线| 91919191919久久成人视频| 99资源在线| 丁香花五月天激情| 婷婷涩涩网| 深爱激情av| 九热视频在线精品15| 9+1视频网址| 婷婷狠狠综合网入口| 手机旧版看人妻1025| 26UUU成人网| 5月丁香六月情| 久久精品系列| 99精品热| 六月婷欧美丁香综合| 99久久婷| 第四色婷婷五月| 热99在线| 亚洲精品成人| 色婷狠狠| 五月色婷婷中文字幕| 先锋资源 996| 亚洲无码11| 成人综合网站| 六月丁香停| 伊人超碰| 婷婷丁香六月天| 99国产精品久久久久久久久久久| 中文字幕第四色.999| 九九热这里只有精品7| 夜丁香五月婷婷| 色五月丁香五月| 亚洲天堂婷婷| site:xiongshengzz.com| 五月激情久久| 久久机热/这里只有精品| 9久热在线视频| 爱之国产色情综合| 野战毛片三一3| 夫妇交换刺激做爰| 亚洲第一成人无码A片| 天天艹天天色| 丁香久久| 9在线9在线婷婷在线国产| 91久久久久久久| 色五月婷婷五月天激情综合| 婷婷综合在线| 丁香五月婷婷99| 插插五月天| 99精色| 色吧99| 六月婷婷深深爱| 青青草轻轻操| 91伦| 噜噜噜噜噜日本视频| 精品99在线| 欧美日韩国产成人在线| 俺也去婷婷五月天第五色| 五月婷婷啪啪| 婷婷五月,综合伊人| 婷婷五月综合在线| 丁香五月激情网| 草榴视频黄色网| 色噜噜伊人| 亚洲黄色影视| 2016日日夜夜操| 五月精品免费XXX| 久99视频| 91丨九色丨东北熟女| 国产综合婷婷| 五月停视频天堂| 五月丁香六月激情网| 婷婷五月天久久久| 国产成人高清| 亚洲色热| 99久久婷婷五月| 啪啪啪五月天| 99热精品免费| 五月色综合| 亚洲综合九九| Caop在线| 天天操天天操天天操天天操天天操天天操天天操天天操天天操 | AAA亚洲AV| 人妻乱码久久久| 婷婷久热| 日韩另类在线观看| 婷婷婷婷婷开心无码播放| 日本欧美成人片AAAA| 伊人干综合| 免费观看亚洲AV片| 亚洲免费99| 婷婷深爱五月| 狠干综合| 日韩啊啊啊| 亚洲中文字幕翔田千里| 五月婷婷狠狠干| 婷婷五月丁香基| 成人在线网| 中文字幕在线观看视频www| 92久久| 亚洲第一黄网| 啪啪六月婷婷| 26UUU欧美激情一区二区| 丁香五月色五月| 丁香婷五月天开心六月| 99碰| 综合婷婷久久| 成人看片网站| 大香蕉啪啪网| site:xiongshengzz.com| 六月激情久久婷婷| 偷偷操99| 激情综合在线观看| 九九碰九九爱97超碰| 五月开心婷婷极品激情| 色5月婷婷| 六月婷婷网| 欧美成人精品A片免费一区99| 国产色色网址网站| 日本人妻伦在线中文字幕| xfplayav在线| 香蕉五月婷婷| 久久这里只有精品8| 激情人妻综合| XX色综合| 国产伊人五月天| 俺也去五月婷婷丁| 天天夜夜爽| 中文字幕97超级碰| 香蕉操亚洲| 亚洲va日| 五月天操逼激情| 久久五月天婷婷| 99热在线资源| 五月婷丁香| 五月丁香色婷| 一级AV片| 噜噜狠狠色综无码久久合欧美| 欧美日本国产欧美日本韩国99| 99热激情| 五月激情另类| 国av网| 久久性爱视频网站| h亚洲| 91久久久久久| 涩婷婷五月天| 亚洲操逼片| 婷婷99狠狠| 另类激情网| 色色激情网| 国产精品第一国产精品| 国产成人+亚洲+欧洲| www.婷婷五月天| 99精品国产在热久久| 91婷婷五月天嫩女| 色色色婷婷五月天| 野战J办公桌椅H| 婷婷色五天| 亚州激情网站无码| 99欧美热| 99久久99九九九99九他书对| renrencaoav| 亚洲色图81p| 婷婷五月天av| 丁香六月婷婷综合缴| 麻豆科斗777| 欧美日韩国产日本精品四虎网网站物 |