亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

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

JDBC數(shù)據(jù)庫訪問與DAO設(shè)計(jì)模式:從代碼失控到分層治理的實(shí)戰(zhàn)指南

JDBC數(shù)據(jù)庫訪問與DAO設(shè)計(jì)模式:從代碼失控到分層治理的實(shí)戰(zhàn)指南 接手一個老項(xiàng)目打開代碼庫第一眼最容易讓人崩潰的永遠(yuǎn)是數(shù)據(jù)訪問這一層。幾百個類、上千行SQL有的直接用字符串拼有的用預(yù)編譯有的返回List有的返回Map還有個別方法把ResultSet直接甩給上層業(yè)務(wù)代碼讓Servlet層自己去遍歷游標(biāo)。這不是編出來的極端案例見過類似的代碼越多越覺得很多人不是不會寫數(shù)據(jù)庫訪問而是從入行開始就沒人告訴他一套統(tǒng)一的約束應(yīng)該長什么樣。今天要聊的JDBC數(shù)據(jù)庫訪問與DAO設(shè)計(jì)模式本質(zhì)就是解決這個問題的。它能讓你把數(shù)據(jù)庫的存取細(xì)節(jié)封裝在固定的一層里業(yè)務(wù)代碼不用再關(guān)心那些Connection、ResultSet、SQLException也能讓一個團(tuán)隊(duì)寫出來的數(shù)據(jù)訪問代碼長成一個樣子可讀、可測、可替換。1. 為什么數(shù)據(jù)庫訪問層總成為項(xiàng)目的黑洞1.1 一段真實(shí)到有點(diǎn)尷尬的失控代碼先把最容易踩的坑擺出來。很多老項(xiàng)目里都能看到這類代碼看起來只是幾句普通的數(shù)據(jù)庫操作實(shí)際上處處是雷Class.forName(com.example.jdbc.Driver); Connection conn DriverManager.getConnection( jdbc:你的廠商標(biāo)識://127.0.0.1:你的端口/demo, 你的用戶名, 你的密碼); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery( SELECT * FROM t_user WHERE name name ); while (rs.next()) { // 手工取值、手工拼對象 } conn.close();這段代碼第一次跑通的時候很爽可它隱藏了至少四個問題第一用戶輸入直接拼進(jìn)SQL等于把語句結(jié)構(gòu)暴露給了外部輸入一旦有人傳入帶有攻擊性質(zhì)的片段整個表的數(shù)據(jù)都可能被拖走第二try-catch里如果只打了異常棧卻沒有在finally中關(guān)閉連接查詢一報錯連接就永久泄漏第三Statement每次執(zhí)行都要讓數(shù)據(jù)庫重新解析一遍SQL在高頻訪問下白白浪費(fèi)數(shù)據(jù)庫的解析時間第四ResultSet被直接暴露給上層以后業(yè)務(wù)代碼不得不了解JDBC的游標(biāo)機(jī)制改字段、換數(shù)據(jù)結(jié)構(gòu)時牽一發(fā)而動全身。1.2 失控的根因不是能力而是缺少邊界我復(fù)盤過很多次這類問題結(jié)論是寫壞代碼的人不一定水平差而是JDBC這套API給了太大的自由。JDBC本身是一個能力非常完整的接口標(biāo)準(zhǔn)但它把決定權(quán)完全交給了調(diào)用者。連接要不要復(fù)用字段怎么映射異常怎么處理事務(wù)邊界劃在哪里這些在API層面沒有強(qiáng)制約束也沒有統(tǒng)一的默認(rèn)規(guī)范于是十個人就能寫出十種數(shù)據(jù)訪問風(fēng)格。業(yè)務(wù)少的時候風(fēng)格差異還看不出來等表多了、方法多了、團(tuán)隊(duì)大了壞味道會隨著業(yè)務(wù)量一起放大。一個查詢從Service層拼SQL拼到DAO層人手一份ResultSet遍歷模板改一個公共字段要在幾十個類里搜索替換。這時候你真正缺的不是某個新的數(shù)據(jù)庫框架而是一層約定的邊界。DAO設(shè)計(jì)模式就是這條邊界它把“怎么存取數(shù)據(jù)”這件事的所有細(xì)節(jié)關(guān)在一個籠子里業(yè)務(wù)層只和籠子外面那張穩(wěn)定接口打交道。2. JDBC是接口標(biāo)準(zhǔn)不是某個具體實(shí)現(xiàn)2.1 驅(qū)動JAR才是真正干活的人很多人把JDBC當(dāng)成一個具體的庫其實(shí)它是Java平臺上訪問數(shù)據(jù)庫的一組接口標(biāo)準(zhǔn)定義在java.sql包里。真正實(shí)現(xiàn)這些接口的是數(shù)據(jù)庫廠商提供的驅(qū)動JAR。你換一種數(shù)據(jù)庫只要換掉驅(qū)動JAR和連接URL業(yè)務(wù)代碼里用到的Connection、PreparedStatement、ResultSet這些類名統(tǒng)統(tǒng)不用變。這就是接口標(biāo)準(zhǔn)的威力上層面對統(tǒng)一抽象底層負(fù)責(zé)各自方言。驅(qū)動加載通常通過Class.forName(驅(qū)動類全限定名)完成在新一點(diǎn)的JDBC版本里驅(qū)動JAR通過ServiceLoader機(jī)制自動注冊這句有時可以省略。但為了兼容老環(huán)境我還是習(xí)慣在連接工具類的靜態(tài)代碼塊里顯式加載一次花不了幾個字符能省掉不少詭異的環(huán)境問題。2.2 Connection、Statement、ResultSet各自扮演什么角色用一個電話類比來理解這三個核心接口會非常直觀Connection就是一條撥通的電話線路代表與數(shù)據(jù)庫的一次會話線路要在通話結(jié)束后掛斷。Statement是你在電話里說出去的一句話。PreparedStatement更特殊它像一張預(yù)先寫好底稿、只留出空檔往里面填內(nèi)容的臺詞好處是數(shù)據(jù)庫先解析框架后面每次只要填參數(shù)就行。ResultSet是電話那頭一句一句返回的答復(fù)。它內(nèi)部維護(hù)著一個游標(biāo)初始位置在第一行之前調(diào)用next()才會向下移動移動到哪一行那一行的數(shù)據(jù)才可讀讀完之后游標(biāo)不會自動回到開頭。這三個接口加一個DriverManager就是JDBC最小可用的全部骨架。理解了它們你后面看任何持久層框架的源碼都不會覺得陌生因?yàn)闊o論外面包了多少層薄紗核心仍然是這套東西。2.3 一次完整查詢的底層生命周期把一次最普通的查詢拆開看它的完整路徑是這樣的// 1. 獲取連接這一步可能來自DriverManager也可能來自連接池 Connection conn DBUtil.getConnection(); // 2. 預(yù)編譯SQL數(shù)據(jù)庫端先解析結(jié)構(gòu)?是參數(shù)占位符 PreparedStatement ps conn.prepareStatement( SELECT id, name, age FROM t_user WHERE name ?); // 3. 綁定參數(shù)參數(shù)只作為數(shù)據(jù)傳給數(shù)據(jù)庫不參與SQL結(jié)構(gòu)拼接 ps.setString(1, userName); // 4. 執(zhí)行查詢返回結(jié)果集游標(biāo) ResultSet rs ps.executeQuery(); // 5. 游標(biāo)逐行移動每一行通過RowMapper轉(zhuǎn)換成業(yè)務(wù)對象 while (rs.next()) { User user new User(); user.setId(rs.getLong(id)); user.setName(rs.getString(name)); // 這里每換一張表都要重新寫一遍模板 } // 6. 釋放資源順序是ResultSet - Statement - Connection rs.close(); ps.close(); conn.close();你會發(fā)現(xiàn)第2步和第3步的組合已經(jīng)優(yōu)于Statement拼字符串SQL結(jié)構(gòu)在數(shù)據(jù)庫端被鎖定參數(shù)永遠(yuǎn)只是參數(shù)這是防注入的根本原因。但更刺眼的還是第5步——每張表、每個查詢都要重復(fù)寫“游標(biāo)移動、按列名取值、set進(jìn)對象”的模板代碼而且要小心翼翼保證第6步在異常路徑上也能執(zhí)行到。如果不幸漏了一行close連接就會被一直占著數(shù)據(jù)庫的連接數(shù)很快被吃光。這也是為什么原生JDBC“能用但不好用”痛點(diǎn)非常具體。3. 原生JDBC為什么“能用但不好用”裂縫在哪3.1 連接獲取是一次昂貴的“重會話”每次調(diào)用DriverManager.getConnection都會讓數(shù)據(jù)庫重新完成一次網(wǎng)絡(luò)握手、身份認(rèn)證、會話資源分配。想象一下你每說一句話都要重新?lián)芤淮坞娫?、等對方接聽、寒暄兩句才進(jìn)入正題這顯然不可持續(xù)。在高并發(fā)場景下頻繁創(chuàng)建連接會讓數(shù)據(jù)庫端線程調(diào)度壓力暴增更嚴(yán)重的是如果應(yīng)用層沒有及時關(guān)閉連接連接數(shù)會一直漲直到數(shù)據(jù)庫拒絕新的會話。解決連接復(fù)用問題的手段是連接池但連接池不是JDBC之外的東西它只是實(shí)現(xiàn)了DataSource接口對外仍然返回Connection對象。換連接池的時候上層取連接的寫法甚至不用變DriverManager.getConnection換成dataSource.getConnection而已。DAO層如果從一開始就面對DataSource而不是DriverManager后面做連接池更換幾乎零成本。3.2 樣板代碼累積起來就是技術(shù)債說句實(shí)話JDBC里最讓人頭疼的不是API難懂而是重復(fù)。每個方法都要經(jīng)歷“拿連接、建語句、設(shè)參數(shù)、執(zhí)行、映射結(jié)果、關(guān)資源”這條流水線而且每個環(huán)節(jié)還都可能出錯。有人試過用try-with-resources簡化釋放邏輯但一旦連接來自連接池close()的語義變成了歸還連接而不是真正關(guān)閉很多人在這里會愣一下。更隱蔽的是異常處理。很多項(xiàng)目的DAO方法里只有空catch日志里什么都看不到數(shù)據(jù)庫報錯就像被黑洞吞掉。等線上出問題你連是哪條SQL失敗都查不出來。這些樣板代碼帶來的不是單點(diǎn)故障而是集體性的可維護(hù)性惡化。3.3 SQL和業(yè)務(wù)邏輯糾纏不清的連鎖反應(yīng)原生JDBC沒有強(qiáng)制數(shù)據(jù)訪問層的位置于是SQL經(jīng)常直接出現(xiàn)在Servlet、Service甚至工具類里。最直接的問題是SQL里的字段名寫錯、表名寫錯編譯期完全察覺只有運(yùn)行到那一行才知道。數(shù)據(jù)庫改個字段名你要在整個項(xiàng)目里搜索字符串一個查詢被復(fù)用了三次值被改了一處另外兩處還跑在老邏輯上。我把這些痛點(diǎn)整理成一張表方便你對號入座原生JDBC的痛點(diǎn)典型后果連接頻繁創(chuàng)建銷毀高并發(fā)下連接耗盡、性能抖動SQL散落在業(yè)務(wù)代碼改表結(jié)構(gòu)要全局搜索漏改一處就出錯手寫結(jié)果集映射大量重復(fù)模板代碼空值、列缺失難發(fā)現(xiàn)異常處理隨意關(guān)鍵錯誤被吞掉線上排查無從下手事務(wù)邊界混亂跨多表操作部分成功、部分失敗數(shù)據(jù)不一致4. DAO設(shè)計(jì)模式的核心思想把存取細(xì)節(jié)關(guān)進(jìn)籠子4.1 單一職責(zé)與依賴倒置DAO到底在保護(hù)誰DAO的全稱是Data Access Object數(shù)據(jù)訪問對象。它的核心思想其實(shí)就一句話把數(shù)據(jù)存取的全部細(xì)節(jié)關(guān)在這一層其他層不允許碰數(shù)據(jù)庫API。這樣做有兩個層面的保護(hù)。物理層面連接獲取、SQL執(zhí)行、結(jié)果集映射、資源釋放全都在DAO實(shí)現(xiàn)類內(nèi)部完成業(yè)務(wù)層看不到任何Connection和ResultSet。邏輯層面業(yè)務(wù)層只依賴DAO接口不依賴具體實(shí)現(xiàn)。依賴倒置的好處立刻顯現(xiàn)測試的時候可以替換成內(nèi)存樁實(shí)現(xiàn)數(shù)據(jù)庫遷移時只改DAO實(shí)現(xiàn)類上層業(yè)務(wù)一行不動。4.2 一個標(biāo)準(zhǔn)DAO族的組成與分工一個規(guī)范的DAO族通常由四部分組成實(shí)體類也叫PO或DO一張表對應(yīng)一個Java類字段與表字段保持映射關(guān)系。DAO接口定義這張表所有對外可用的操作方法簽名里不出現(xiàn)SQL和JDBC類型。DAO實(shí)現(xiàn)類真正寫SQL、操作JDBC的地方也是全文唯一允許出現(xiàn)SQL片段的位置。連接工具類或數(shù)據(jù)源給所有實(shí)現(xiàn)類提供統(tǒng)一的連接獲取和資源釋放入口。比如用戶表的接口可以長這樣public interface UserDao { User findById(Long id); User findByName(String name); ListUser findByAgeRange(int minAge, int maxAge); Long insert(User user); int update(User user); int delete(Long id); }實(shí)現(xiàn)類里要做什么就很明確了把findById翻譯成一條SELECT把insert翻譯成一條INSERT同時保證用完的資源被正常釋放。業(yè)務(wù)層看到的是“查用戶”“新增用戶”這樣業(yè)務(wù)化的語義而不是“打開連接、拼SQL、遍歷游標(biāo)”這樣的技術(shù)步驟??赡苡腥藭栃№?xiàng)目是不是可以不寫接口直接用一個類搞定我的經(jīng)驗(yàn)是如果有測試需求或者預(yù)期這張表的存儲方式未來可能變化接口帶來的收益就很大。哪怕目前只有一種實(shí)現(xiàn)“接口 實(shí)現(xiàn)類”這個結(jié)構(gòu)本身也在提醒你這條邊界是存在的不能越過它去訪問數(shù)據(jù)庫。5. 手把手搭一套可復(fù)用的DAO基礎(chǔ)設(shè)施5.1 先用DBUtil把連接的獲取和釋放統(tǒng)一起來DAO層最底下的地基是一個連接工具類。它負(fù)責(zé)兩件事提供連接以及安全地釋放資源。下面是一個簡化版的樣子public final class DBUtil { private static DataSource dataSource; private DBUtil() { } // 實(shí)際項(xiàng)目中這里通過配置文件初始化數(shù)據(jù)源 // 比如讀取配置后創(chuàng)建連接池實(shí)例這里用占位示意 public static void init(DataSource ds) { dataSource ds; } public static Connection getConnection() throws SQLException { if (dataSource null) { throw new IllegalStateException(數(shù)據(jù)源尚未初始化); } return dataSource.getConnection(); } public static void close(ResultSet rs, Statement stmt, Connection conn) { if (rs ! null) { try { rs.close(); } catch (SQLException ignored) { } } if (stmt ! null) { try { stmt.close(); } catch (SQLException ignored) { } } if (conn ! null) { try { conn.close(); } catch (SQLException ignored) { } } } }注意幾點(diǎn)。第一關(guān)閉順序一定是ResultSet先、Statement其次、Connection最后雖然現(xiàn)代JDBC驅(qū)動在關(guān)閉Statement時通常會連帶關(guān)閉ResultSet但顯式關(guān)閉能讓日志和監(jiān)控更清楚。第二當(dāng)連接來自連接池時close()不是真正斷開而是把連接歸還給連接池復(fù)用。第三異常即使想忽略也建議打一條trace級日志完全不理會讓連接泄漏問題無法追蹤。5.2 泛型BaseDao把查詢模板和結(jié)果映射分開有了連接工具類下一步是消滅重復(fù)的模板代碼。核心思路是用一個泛型基類把“執(zhí)行查詢、遍歷游標(biāo)、關(guān)閉資源”這些公共流程抽出來把“每行怎么轉(zhuǎn)成對象”留給調(diào)用方通過回調(diào)傳入。這個回調(diào)就是常說的RowMapper。先定義一個函數(shù)式接口FunctionalInterface public interface RowMapperT { T mapRow(ResultSet rs, int rowNum) throws SQLException; }再寫一個泛型基類public abstract class BaseDaoT { protected ListT queryForList(String sql, RowMapperT rowMapper, Object... params) throws SQLException { Connection conn null; PreparedStatement ps null; ResultSet rs null; try { conn DBUtil.getConnection(); ps conn.prepareStatement(sql); setParameters(ps, params); rs ps.executeQuery(); ListT result new ArrayList(); int rowNum 0; while (rs.next()) { result.add(rowMapper.mapRow(rs, rowNum)); } return result; } finally { DBUtil.close(rs, ps, conn); } } protected T queryForObject(String sql, RowMapperT rowMapper, Object... params) throws SQLException { ListT list queryForList(sql, rowMapper, params); if (list null || list.isEmpty()) { return null; } return list.get(0); } protected int update(String sql, Object... params) throws SQLException { Connection conn null; PreparedStatement ps null; try { conn DBUtil.getConnection(); ps conn.prepareStatement(sql); setParameters(ps, params); return ps.executeUpdate(); } finally { DBUtil.close(null, ps, conn); } } protected Long insertReturnKey(String sql, Object... params) throws SQLException { Connection conn null; PreparedStatement ps null; ResultSet rs null; try { conn DBUtil.getConnection(); ps conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); setParameters(ps, params); ps.executeUpdate(); rs ps.getGeneratedKeys(); if (rs.next()) { return rs.getLong(1); } return null; } finally { DBUtil.close(rs, ps, conn); } } private void setParameters(PreparedStatement ps, Object... params) throws SQLException { if (params null) { return; } for (int i 0; i params.length; i) { ps.setObject(i 1, params[i]); } } }這個基類一出來80%的樣板代碼就消失了。queryForList負(fù)責(zé)搞定“連接、預(yù)編譯、綁定參數(shù)、遍歷游標(biāo)、關(guān)閉資源”調(diào)用方只需要關(guān)心兩件事SQL里占位符的順序以及RowMapper里一行數(shù)據(jù)怎么變成對象。insertReturnKey特別注意一下它通過Statement.RETURN_GENERATED_KEYS讓數(shù)據(jù)庫返回自增主鍵避免插入之后還要再查一次。5.3 落地一個真實(shí)的UserDao有了BaseDao之后寫UserDao的實(shí)現(xiàn)類會變得非常輕快public class UserDaoImpl extends BaseDaoUser implements UserDao { Override public User findById(Long id) { String sql SELECT id, name, age, create_time FROM t_user WHERE id ?; return queryForObject(sql, (rs, rowNum) - toUser(rs), id); } Override public User findByName(String name) { String sql SELECT id, name, age, create_time FROM t_user WHERE name ?; return queryForObject(sql, (rs, rowNum) - toUser(rs), name); } Override public ListUser findByAgeRange(int minAge, int maxAge) { String sql SELECT id, name, age, create_time FROM t_user WHERE age BETWEEN ? AND ?; return queryForList(sql, (rs, rowNum) - toUser(rs), minAge, maxAge); } Override public Long insert(User user) { String sql INSERT INTO t_user(name, age, create_time) VALUES (?, ?, ?); return insertReturnKey(sql, user.getName(), user.getAge(), user.getCreateTime()); } Override public int update(User user) { String sql UPDATE t_user SET name ?, age ? WHERE id ?; return update(sql, user.getName(), user.getAge(), user.getId()); } Override public int delete(Long id) { String sql DELETE FROM t_user WHERE id ?; return update(sql, id); } private User toUser(ResultSet rs) throws SQLException { User user new User(); user.setId(rs.getLong(id)); user.setName(rs.getString(name)); user.setAge(rs.getInt(age)); user.setCreateTime(rs.getTimestamp(create_time)); return user; } }這段代碼讀起來順眼多了。每個方法一眼就能看出在做什么SQL只有這一層有參數(shù)按順序填資源統(tǒng)一由基類釋放RowMapper把數(shù)據(jù)庫行轉(zhuǎn)換成業(yè)務(wù)對象。業(yè)務(wù)層調(diào)用時只需要拿到UserDao接口不用知道背后有BaseDao、有DBUtil這些東西。6. 規(guī)?;飞系娜竭B接池、事務(wù)邊界、批量與分頁6.1 連接池只是換了連接來源DAO接口紋絲不動數(shù)據(jù)庫連接池的標(biāo)準(zhǔn)做法是通過DataSource對外提供連接。你只需要在項(xiàng)目啟動時初始化一次連接池實(shí)例再把它交給DBUtil.init。連接池的核心參數(shù)有這些參數(shù)名稱含義備注初始連接數(shù)啟動時就創(chuàng)建好的連接數(shù)量啟動較慢但第一波請求更穩(wěn)最大活動連接數(shù)同時最多能分配的連接數(shù)量設(shè)置太小會排隊(duì)太大浪費(fèi)資源最小空閑連接數(shù)長期保持的空閑連接數(shù)量與最大活動數(shù)配合控制回收最大等待時間請求連接排隊(duì)超過此時長則報錯單位毫秒避免請求無限等待連接校驗(yàn)查詢?nèi)〕鲞B接前檢查是否可用常見寫法是執(zhí)行一條輕量查詢一旦連接池接入DBUtil.getConnection()內(nèi)部返回的就是池里分配的連接close()變成歸還連接。DAO接口本身完全不動ServiceImpl也不動這就是前面強(qiáng)調(diào)封裝的價值——底層存儲來源怎么換上層用起來沒有任何感知。6.2 事務(wù)邊界歸Service層連接傳遞用ThreadLocal連接池解決的是連接復(fù)用可它管不了事務(wù)。一個業(yè)務(wù)方法往往要調(diào)用多個DAO方法比如轉(zhuǎn)賬要“扣A賬戶”和“加B賬戶”這兩個操作必須在同一個數(shù)據(jù)庫連接上完成、要么一起成功、要么一起回滾。如果每個DAO方法都自己拿連接、自己提交就會出現(xiàn)A扣款成功但B加款失敗的尷尬局面。業(yè)界比較通用的方案是事務(wù)邊界劃在Service層DAO層不做提交和回滾事務(wù)所需的連接通過ThreadLocal綁定在當(dāng)前線程上。偽代碼如下public class ConnectionHolder { private static final ThreadLocalConnection HOLDER new ThreadLocal(); public static void bind(Connection conn) { HOLDER.set(conn); } public static Connection get() { return HOLDER.get(); } public static void unbind() { HOLDER.remove(); } }Service層的典型寫法是public void transfer(Long fromId, Long toId, BigDecimal amount) { Connection conn DBUtil.getConnection(); boolean oldAutoCommit; try { oldAutoCommit conn.getAutoCommit(); conn.setAutoCommit(false); ConnectionHolder.bind(conn); accountDao.decrease(fromId, amount); accountDao.increase(toId, amount); conn.commit(); } catch (Exception e) { conn.rollback(); throw new RuntimeException(轉(zhuǎn)賬失敗, e); } finally { conn.setAutoCommit(true); ConnectionHolder.unbind(); conn.close(); } }對應(yīng)的DAO實(shí)現(xiàn)里取連接時先看ConnectionHolder有沒有綁定有就用綁定的沒有再新取Connection conn ConnectionHolder.get() ! null ? ConnectionHolder.get() : DBUtil.getConnection();要點(diǎn)在于DAO層的update方法絕不自己commit或rollback提交時機(jī)完全由Service層決定。這樣事務(wù)的粒度才夠大跨多表操作才能保持一致性。6.3 批量寫入與分頁查詢的注意點(diǎn)批量插入如果要一條條執(zhí)行數(shù)據(jù)庫往返次數(shù)多到讓人心疼。JDBC提供了一套批量接口把命令攢到一定數(shù)量再一次發(fā)送String sql INSERT INTO t_order(user_id, amount) VALUES (?, ?); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { for (Order order : orderList) { ps.setLong(1, order.getUserId()); ps.setBigDecimal(2, order.getAmount()); ps.addBatch(); if (batchCount % 500 0) { ps.executeBatch(); } } ps.executeBatch(); }分頁查詢則是另一個容易埋坑的地方。最粗暴的寫法是SELECT * FROM t_user然后把所有數(shù)據(jù)load進(jìn)內(nèi)存再在Java里分頁數(shù)據(jù)量一大內(nèi)存就被打爆。正確做法是讓數(shù)據(jù)庫只返回當(dāng)前頁需要的那幾行但不同數(shù)據(jù)庫分頁方言不同正好可以由DAO實(shí)現(xiàn)類把這種差異消化掉對外部接口完全透明。7. 實(shí)戰(zhàn)中我踩過的深坑與排查要點(diǎn)7.1 ResultSet是一條會過期的游標(biāo)不是結(jié)果集合新手最容易犯的錯誤是把ResultSet當(dāng)成普通集合返回給上層// 錯誤示范DAO方法返回ResultSet public ResultSet queryByName(String name) { Statement stmt conn.createStatement(); return stmt.executeQuery(SELECT * FROM t_user WHERE name name ); }危險在于ResultSet默認(rèn)綁定在Statement上Statement關(guān)閉后游標(biāo)就失效了。等你把ResultSet交到Service層連接可能已經(jīng)關(guān)閉要么報“ResultSet closed”要么拿到一堆看不出時機(jī)的怪異異常。正確做法就是在DAO方法內(nèi)部完成映射把數(shù)據(jù)轉(zhuǎn)換成實(shí)體對象或DTO列表然后返回普通Java集合。一句話游標(biāo)不過DAO的邊界。7.2 預(yù)編譯與參數(shù)綁定的真正價值參數(shù)是數(shù)據(jù)不是語句結(jié)構(gòu)SQL注入的本質(zhì)是把外部輸入?yún)?shù)當(dāng)成了SQL語句的一部分去解析。很多書本說“用了PreparedStatement就能防注入”但沒有把為什么講透。關(guān)鍵在兩點(diǎn)一是prepareStatement時數(shù)據(jù)庫已經(jīng)完成了SQL結(jié)構(gòu)解析結(jié)構(gòu)被鎖定二是setXxx綁定參數(shù)時參數(shù)永遠(yuǎn)以數(shù)據(jù)的形式傳給數(shù)據(jù)庫不會重新參與結(jié)構(gòu)拼接。所以我在DAO層立了一條死規(guī)矩所有SQL一律用?占位符加預(yù)編譯任何情況下不允許用字符串拼接參數(shù)。哪怕參數(shù)看起來非?!鞍踩北热缫粋€整數(shù)ID也堅(jiān)持走占位符。習(xí)慣一旦養(yǎng)成就不會在某個緊急修復(fù)時手滑拼出一個漏洞。7.3 空值、時間類型與自增主鍵的三個細(xì)節(jié)結(jié)果集映射里最容易翻車的是空值。getInt(age)在數(shù)據(jù)庫值為NULL時返回0你以為用戶年齡是0其實(shí)人家年齡壓根沒填。如果業(yè)務(wù)里需要區(qū)分“沒填”和“填了0”就要用包裝類型// 最好用Integer接收null和0能區(qū)分開 Integer age rs.getObject(age, Integer.class);時間類型也是個經(jīng)典坑。數(shù)據(jù)庫的DATETIME、TIMESTAMP映射到Java通常是java.sql.Timestamp而業(yè)務(wù)里常用java.util.Date。取值時直接rs.getObject(create_time, Timestamp.class)再把Timestamp轉(zhuǎn)成Date千萬別把Timestamp和Date混著用Date持有的毫秒數(shù)對不上會出各種詭異偏差。自增主鍵回填我上面已經(jīng)寫了insertReturnKey這里補(bǔ)充一句判斷邏輯主鍵列必須是數(shù)據(jù)庫自增列且prepareStatement時傳了RETURN_GENERATED_KEYS這樣getGeneratedKeys()才有值。有些JDBC驅(qū)動對“返回主鍵”的支持不太一樣實(shí)測時如果拿不到檢查一下表和驅(qū)動兩邊的配置。7.4 排查問題時的習(xí)慣把最終SQL和參數(shù)打出來一個讓我少熬好幾次夜的調(diào)試習(xí)慣是在DAO基類里把SQL主體和參數(shù)數(shù)組一起打成日志if (log.isDebugEnabled()) { log.debug(SQL: {}, params: {}, sql, Arrays.toString(params)); }這樣線上搜索日志時直接按方法名或表名就能定位到某條請求實(shí)際執(zhí)行的SQL是什么、參數(shù)是什么不需要一行行看代碼猜。很多人排查慢查詢時跑到數(shù)據(jù)庫那邊抓SQL卻沒有應(yīng)用側(cè)參數(shù)兩邊對不上白白折騰半天。先在DAO層把上下文信息打印全比什么工具都好使。8. 吃過虧之后我給自己定的幾條DAO規(guī)矩這幾條規(guī)矩是我在幾個項(xiàng)目里踩坑踩出來的不復(fù)雜但每一條都對應(yīng)過真實(shí)事故。所有SQL只出現(xiàn)在DAO實(shí)現(xiàn)類里業(yè)務(wù)層不出現(xiàn)任何SQL片段。每張表對應(yīng)一個DAO一個方法只做一件事。不要搞一個萬能方法接收一堆開關(guān)參數(shù)。連接、Statement、ResultSet統(tǒng)一走工具類關(guān)閉不允許在DAO實(shí)現(xiàn)類里散裝管理資源。參數(shù)綁定一律使用?占位符加預(yù)編譯永遠(yuǎn)不做字符串拼接。事務(wù)入口放在Service層DAO層不主動提交、不主動回滾。結(jié)果集必須在DAO方法內(nèi)部轉(zhuǎn)換成實(shí)體或DTO絕不返回游標(biāo)對象。關(guān)鍵SQL和執(zhí)行參數(shù)要打日志線上敢查、查得到比事后猜強(qiáng)一百倍。如果你現(xiàn)在的項(xiàng)目正處于“SQL滿天飛、改表結(jié)構(gòu)要滿項(xiàng)目搜索”的階段我的建議是先別急著換重型框架。把DAO這一層梳理清楚劃定邊界、統(tǒng)一模板、規(guī)范事務(wù)和連接管理成本最低收益卻立竿見影。等以后再接觸那些主流的持久層框架你會發(fā)現(xiàn)自己早就理解了它們想解決的核心問題。JDBC這套底層接口沒有過時DAO這種設(shè)計(jì)思想也沒有過時它們?nèi)匀皇抢斫釰ava數(shù)據(jù)訪問世界的最牢固的地基。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
欧美日韩大黄片| 欧美精品1区2区3区| 亚洲精品电影| 久久久久亚洲熟妇熟女| 天操天操夜操夜月月年年操操| 欧美午夜熟妇黑人精品91| 亚洲婷婷丁香在线| 99激情| 91草草草| 97网色| ji熟女.com| 亚洲色图 欧美热图 清纯唯美 另类自拍| 香蕉久久精品| 在线播放成人高清免费视频| 丝袜 亚洲 偷拍| 欧美性生活内射| 婷婷爽人人婷婷爽视频| 国产1769在线| 美女骚尻视频| 久久久久久久强迫| 9久综合网| 亚洲少妇在线影音| 日本色日夜干| 国产性刺激| 黑人在线91| 国产区91柔拿会所技师| 97丝袜亚洲在线播放| 99在线精品视频| 欧美精品久久久久久久久88| 97精品视频免费| 91综合无码| 99热亚洲| 人爽不卡视频| 中文在线视频| 92人人操人人| 神马久久久久久| 无码日韩网站| 99热伊人| 日韩美女,国产传媒,视频一区| 超碰在线欧美性爱激情| 国产97色在线 | 亚洲| 99热精品在线观看| 久久的免费性爱视频| 欧美A√综合网 | 久久人体一区二区| 亚码激情| 中文字幕在线观| 99无码视频| 变态综合色| 色综合色| 色黄污美女啪啪啪免费网站| 你草精品在线视频| 国产超碰人人爽人人做| 超碰免费人妻在线| 亚洲色图欧美色图制服诱惑| 女人被男人桶爽视频网站| 四虎av在线| 啊啊啊啊一区| 久久产精品一区二区三区电影| 熟妇最新先锋一二三区| 黄色人人| 日韩本不卡视频在线观看| 很很干很很操| 九九人人操| 69精品| 男人的天堂在线| 日逼逼免费看| 天天综合站| 91青视频| 久久久久久电影| 熟妇高潮一区二| 六月丁香久久| 日本丝袜人妻内射| 干少妇视频| 嗯~啊~快点 死我视频免费看网站| 国产又大又硬又长又粗| 69av一区二区三区| 色欲天香天天综合网-成年人三级片网站-欧美乱妇狂野-日韩国产专区-久久久久久 | 俺去俺来也在线www| 蜜臀久久99精品久久久久久无删减 | 26uuu性物| 亚洲av青草久久一区二区| 少妇二级| www99热| 国产一区二区三区视频在线看| 亚洲人天堂| 熟女熟妇一区二区三区视频| 99∨VTV| 91动漫操逼视频| 九九九一二三| 国偷自 一区| 日日爽夜夜爽| 丁香六月综合激情| 丁香九月激情啪| 国产真乱mangent| 欧洲小说色图视频另类| 久操九九九九| 黄片免费看黄片免费看| A 在线网址| 天天综合91| 国产精品电| 亚州色图欧美| 欧美婷婷久久| 蜜桃精品一区二区三区ww| 天天日天天色| 九九久久首页| 影音综合网| 校园春色制服丝袜中文字亚洲| 粉嫩av在线一区二区| http://qxhbdz.com| 少妇久久久久久| 色97欧美| 伊人96在线| 午夜AV污污污| 天天拍天| 久久99久久99精品天美传媒棢·纸:. | 91中文字幕| 人人澡人人干| 天天日天天干天天操| 久久久久国产精品久久久| 深夜视频| 99e久久国产精品| 蜜臀AV午夜精品久| 久夜视频| 久久人人爽人人爽人人片Ⅴ| 亚洲国产欧美另类自拍| 亚洲AV操| 亚洲第一黄色av网站| 91午夜无码| 99精品成人免费看| 五月天激情小说| 青草青青久久久久久国产| 九九热免费在线国产视频伊人五月| 99国内精品| 美国久久一二三四| 韩国毛片一区二区三区| 97超碰超| 国产成年精品高清在线观看91| 国产一区二区三区久久久精品| 老司机深夜18禁污污网站| 岛国在线免费视频| 亚洲天堂,男人| 天天综合网91入口| 亚洲天堂人人妻| 中文字幕人乱码中文字的预防方法| 久久精品国产久精国产| 久久系列| 人人么人人操| 大香蕉免费乱伦视频| 天天干,天天日| 高潮内射在线| 撸无码不卡免费视频| 中文字幕一区二区三区四区在线视频| 91久久久久久久| 亚洲限制级在线| 蜜臀网址在线| 人人人摸人人| 五月婷婷无码| 激情四射婷婷六月天| 色欲av国内精品久久久久久| 激情五月天插| 丁香五月久久| 日韩精品怡红院| 亚洲丨在线| 日韩熟女操逼| 亚洲激情四射| 欧美后入式| 成人蜜乳小视频网站| 精品久久久中文字幕不| 99青青草国产视频| 欧美色999| 日本东京热加勒比久久| 精品国产乱码久久久久久影片| 天天看特黄的免费网站 | AV在线资源| 欧亚日韩中文在线| 日本欧美国内在线| 福利风月五月天影院| 亚洲欧美综合网站| 午夜亚洲国产理论秋霞| 国产精品九9| 色欲久久99精品久久| 欧美爆乳精品一区二区| 强奸少妇AV导航网| 激情文学88| 婷婷五月天av| 综合五月天| 天天精品| 极品粉嫩少妇视频| 神马久久69| 无码9区| 欧美在线播放aaaa| 色五月天AV| 啊啊啊用力在线观看| 在线观看成人性爱免费小视频| 老熟女综合网| 久久天堂网| 亚洲 另类 丝袜 自拍 动漫| 美女的肌被草喷水视频| 国产强奸超碰AV| 性饥渴少妇av无码毛片| 色网色网色网色网色网色| 欧美手机在线综合| 午夜精品久久久久久久| 午夜精品久久久久久久99热影院| 性色国产东北露脸精品视频| 伊人一区二区三区| 日本五十路在线| 亚洲91网。| 色婷婷在线视频精品导航| 日韩pv中文| 中文字幕 码 自拍 视频 区| 亚洲 日本 一 二 三| 色狠狠综合| 中文字幕在线免费观看视频| 天天操夜夜操| 精品美女在线视频| 伊人精品视频| 91欧美巨乳| 国产视频97| 国产精品69久久久久孕妇欧美| 久久久久久久六六| 久草这里只有精品 | 亚洲欧美人妻| 亚洲人体视频在线观看| 岛国片在线播放| 国产A v无码专区| 97人人操人人摸人人爱| www.av在线观看| 亚洲精品三| 久久草草欧美精品| 日韩精品99久久久久久中文字幕 | 加勒比综合88| 青娱乐亚洲自拍| 东北丰满熟女国产一区| 啊视频在线| 国产精品一二三免费网站| 亚洲AV乱码专区国产噜噜亚洲| 97se综合网| 日韩精品系列| 大香蕉中文| AV天堂国产| 精品一区二区人妖| 亚州操操穴网| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 密臀成人视频久久久| 久久久久久久97| 天天懆天天日| 六月色婷婷| 日韩ab网 | 成人乱人伦一区二区| 日本 欧美 国产一区| 色婷婷久久| 国产精品久久久999| 五月天精品| 在线午夜成人无码视频| 黄aaaaaaaaaaaaaaaaaa色网站| 东京热激情视频一二三区 | 免费作爱一级视频| 国模吧 一区二区三区| 亚洲情色第一页| 欧美性爱一区| 久久久久久99AV无码免费网站| 亚洲无线码一区国产欧美国| AV一二区| 东北熟女91| 国产黄色 A 片免费看| 久久99黄色卞西瓜| 精品久久97| 老熟女乱子伦中文字幕一区二区| 亚码激情| 亚洲影院成人| 91人妻视频在线| 东京热91| 国产原创剧情在线丝袜| 亚热日本熟女| 国产精品久久天天干| 久久久久久国产精品| 久草热制服丝袜在线观看| 婷婷久月| 天天综合亚在线| 久男人久久| 日本不卡高清视频| 久久人爽| 超碰成人公开| s片在线观看| 欧美片第一页| 国内毛片无码一级毛片| 中文字幕、久久精品国产2020、久久综合久久自在自线精品自、亚洲 | 国产浮力影院第1页| 青娱乐大香蕉| 日本一区二区三区免费观看| 久操99| 天堂综合网| 99超级碰免费视频| 玖玖爱影院| 日韩精品.久久精品.AV女优.天美传媒| 超碰在97| www.99热| 天天躁日日躁狠狠躁| 亚洲激情综合| 日韩免费中文字幕视频| 91在线免费观看处女| 久草新在线| 久久天天摸| 久久久久久九九九九| 婷婷丁香五月综合| 中文字幕精品免费一区二区| 日韩亚洲美女一区久久| 人妻夜夜爽天天爽三区麻豆AV网站| 日本3级一区二区免费| 日本亚欧爱爱| 久久久久人妻| 日韩操啪| 日本熟妇精品九九| 婷婷性爱| 乱伦熟妇一区二区| 粉嫩久久久久| 天天添天天干电影| 天天视频网站黄| 中文字幕av一区二区三区人妻少妇 | 久久熟妇五十路一区| 草草影院日本第一页| 亚洲精品1区| 天天操天天舔| 午夜性刺激视频免费观看| 中文字幕一区 二 区 三 四 五 区日 日 骚| 国产女人视频三四五区| 97免费免费视频网| 欧美刺激色黄片免费看| 亚洲天堂男人的天堂| 色综合加勒比四四季| 日韩人妻 中文字幕| 超碰社区97| 嗯嗯啊中文字幕| 婷婷在线视频在线观看| 欧美97在线欧| 九七人妻在线| 中文字幕片| 久久一区二区三区入口| 在线视频免费观看午夜| 蜜臀va69| 蜜屁Av| 思思99热| 韩国午夜理伦三级好看| 亚洲欧美另类小说| 97av,com| 国产偷仑| 97亚洲综合电影| 一区二区三区 日韩欧美| 色综合久久88色综合久久天天| 91美女视频。| 试看60秒| 欧美综合 站| 少妇免费视频| 综合色图亚洲欧美| 国产精点久久久成人| 91色综合| 999999精品| 国产精品动态一区二区三区四四| 少妇69中文| 天美传媒国产原创中文字幕亚洲欧美另类| 极品尤物自安慰| 久久草草亚洲蜜桃臀| 视频在线97| 无码人妻精品一区二区三区九九| 久99久视频精选| 成人看片网站| 大伊香蕉在线视频免费| 久操网线| 一级aaaaa欧美中文字幕录像片| 另类天堂| 久久久新亚洲AV| 欧美精品激情| 中文字幕一区二区无码成人| 超碰在线综合97| 国产精品视频播放| 欧美人妻中出| 少妇内射视频| 97超碰伊人| 蜜桃香蕉久草精品在线| 高清无码学生妹高潮| 亚洲青青草| 伦理日韩国产久久| 美女网站黄页| 白嫩白嫩的午夜九久久久久久久久久久久成人剧场 | 丁香五月性爱| 99精品在线| 婷婷在线播放| 日本韩国一本产品小视频日本韩国一本产品久久久产品小视频日本韩国一本产品久 | 婷婷尹人大香蕉免费| 日韩成人网址| 中文字幕在线播放2中文字幕在线观看2| 熟女乱伦二区| 蜜臀久久久久久999| 狠狠色婷婷| 狠狠干狠狠干| 后入人妻一区| 大乔未久88一区| 国产后入内射| 中国91AV| 欧美爆乳精品一区二区| 免费观看国产小粉嫩喷水精品午| 高清成年美女黄网站免费大全| 日韩探花精品在线视频| 日本一级性爱| 日韩 人妻 精品| 女人的天堂大香蕉网| 大二网站亚洲| 色综合av男人天堂| 日韩婷婷| 久久久久一本一区二区青青蜜月| 天操天操夜操夜月操月年年操操| 四方色播| 无码国产Av| 国产一区二区三区影片| 婷婷伊人一区| 夜夜青青无码影院| 亚洲色天| 日韩一级成人毛片免费观看| 丁香五月激情综合| 91 综合 色| 91国产丝袜白虎| 成人小说另类在线| 性色av网站| 狠狠操夜夜操蜜桃视频三区| 久久草视频污视频| 亚洲欧美首页| 91黑人无码激情在线| 成人贴图日韩欧美| 欧美日韩精品久久久久东北老熟妇| 麻豆成人影音在线| 丁香五月综合| 一区二区首页| 亚洲人妻爽爽爽| 国产一区二区三区久久久精品| 亚洲操逼视频网站| 人妻 欧美 中文| 日日不卡av| 狠狠中文字幕| 综合久欧洲| 蜜臀Av一区二区三区| 天天激情综合站| 欧美操逼一二三区| 国产精品69久久久久孕妇欧美| 亚洲国产精品无码AV久久| 大香蕉专区| 熟妇一区二区三区| 五十路熟女人妻一区二区在线观看| 国产高清无码一区三区二区| 欧美爆操91| 欧美日韩久久精品爱爱| 柠檬AV导航| 午夜精品人妻二区三区| 97在线视频观看| 久久婷婷精品| 欧美后入式| 欧美成人AⅤ大片在线观看| 久久理论字幕视频| WWW.操逼.COM| 亚洲色图加勒比| 国产一区在线播放| 九九九九九九九精品视频| 色综合 加勒比| 伊人久久综合精品欧美| 婷婷美人网| 奇米四色网| 国产精品经典一卡久久久| 午夜传煤十二区精品| 亚洲aV性爱| 欧美日韩国产色五月综合在线| 日本日逼高清| 久久人妻无码毛片A片麻豆| 国产乱伦亚洲| 激情文学 亚洲图片| 久久riav中文精品| 天天摸天天舔天天操| 欧美日韩电影成人在线| 日日夜夜草草草| ji熟女.com| 小骚逼被操的爽不爽| 99精品欧美一区二区三区桃色| 色婷婷婷五月天激情四射| 18禁在线视频| 性爱AV天堂| 午夜福利视频在线一区| 亚洲人妻五月丁香婷婷| 97视频免费在线| 一级啊性爱在线视频| 九九亚洲色在线观看| av资源在线观看少妇| 偷偷人人精品女女久久| 天堂av2019| 色在线综合| 大香蕉之青青草原| 国产无马av| 91人妻人人澡人人爽人人精品| 日韩在线视频1234| A一区片| 精人妻无码一区二区三区伊人直播| 黄色高清无码无码破解免费暗网 | 亚洲精品官网在线观看| 51一区二区三区| 夜夜操二区| 精品黑人一区二区| 精品成人av一区二区三区在线| 人人操超碰在线| 日韩欧美麻豆大片| 久久人人舔人人爽舔人人av片| 熟妇女伦乱视频视频| 精品久久久久久亚洲| 最新国内自拍av免费| 中文字幕第二页| 四虎影库国产精品免费| 久久高清欧美国产| 国产午夜精品在线观看| 久热99999| 精品网站9999| 色色色欧美| 涩涩涩综合| 97国产|免费| 久久久久9999妇女| 校园春色制服丝袜中文字亚洲| 午夜一级免费毛片| 99re免费| 国产97/欧美| 青青草男人天堂| 色色色综合| 国产欧美岛国精品一区| 国产粉嫩蜜臀av一区二区三区 | 无码高清少妇久久| 久久久人妻| 97久久精品不卡| 欧美 青青草| 色综合五月天| 天天爽人人综合免费7799| WWW啪啪的com| 欧美18老人禁| 亚洲成a人v欧美综合天堂下载| 人妻 欧美亚洲| 亚洲色91C| 超碰97男人| 色五91| 婷婷五月在线视频| 国内毛片无码一级毛片| 日韩丝袜二区| 亚洲最大的综合性av| 中文字幕人成乱码熟女香港| 久久的免费性爱视频| 四方色播| 好属操| 一区二区高清视频| 日本506070| 日韩射精| 一级一性爱免费视频| 97操b| 九热久| 狠狠躁伊人中文字幕| 骚货操死你| 麻豆色约约| 国产一区二区在线看| 97在线亚洲| 欧美女同在线| 这里只有精品97| 精品久久97| 中文字幕熟女人妻丝袜| 富女玩鸭子一级毛片| 欧美一区二区男人天堂| 国产精品久久久久久亚洲色欲| 深夜福利黄片| 国产一区二区免费福利片| 国产精品高清2021在线| 国产精品无码av在线| 91在线视频观看国产| 国产熟女乱论| 欧美色五月| 天天综合AV| 97超碰色屌| 神马久久69| 人妻丰满熟妇av无码区蜜桃| 骚女天天综合网| 国产捆绑一区| 唐山老熟妇露脸啪啪叫| 亚洲五月婷婷| 大香蕉色网| 伊人精品国产| 久久久久久久久一区二区三区| 狠狠超| 亚洲图片婷婷五月天| 国模吧 一区二区三区| 日韩精品 资源| 婷婷情色五月天| 黄色一区三区| 国产1024在线播放| 精品毛片久久久精品毛片| 欧美色图天堂在线| 一本久久精品中文字| 亚洲情色 自拍| 波多野结衣AV无码一区| 最新日韩黄片| 91欧美长吊| 超碰偷拍| 九月激情婷婷| 91人人爽人人爽人人人,gav福利视频导航,日韩欧美亚洲国产字幕四区 | 2000亚洲男人天堂| 97亚洲欧美日韩| 国产亚洲色婷婷久久99精品91葵花宝典 | 69精品人人人人| 亚洲精品欧洲精品| 国产尤物在线三区| 亚洲国产精品无码AV久久久| 国产在线视视频有精品| 9热9热综合网| henhen91| 日本性爱不卡视频| 亚州成人A√| 久久超碰天天| 国产51色综合久久免费| 97精彩视频网站| 天堂av最新电影网| 久久黄色性爱视频| 久久免费看高潮毛片韩国| 激情小说激情视频| 欧美一级黄色18片免费看| 中文字幕视频2区| 日逼97| 三级片网站在线播放| 妇人噜噜| 国产精品爱欲| 亚洲欧美性生活| 99re超碰| 欧美综合自拍成人自拍第二十页| 超碰在线1234区| 午夜无遮挡男女啪啪视频| 91丨国产丨白浆| 久久97精品久久久久久久不卡| 亚州AV无码国产精品| 欧美日韩国产电影| 亚洲欧洲中文日韩女优乱码| 青娱乐亚洲热| 一级一性爱免费视频| 中文字幕老熟妇黄色视频| 在线洲亚线| 国产小u女在线观看| 我爱搞逼综合网| 久久美女国产| 老熟女中文字幕高清| 国产成人综合在线播放| 97一区二区三区视频| 涩涩涩综合| 亚洲国产精品久久久男人的天堂| 亚洲熟女精品| 亚洲十八禁止| 性爱1区| 亚洲欧美综合图片| 狠狠躁天天躁日日躁| 亚洲男人综合| 欧美 熟女 日韩| 天天看天天在线精品| 欧美日韩人妻婷婷一区| 乱伦av.com| 精品免费成人久久| 91在线色综合| 国产乱伦搜索结果91P| 美女的肌被草喷水视频| 人妻81p| 四虎影视国产精品| 久久久久精| 91成人高清在线观看| 9长久久精品| 日本日逼视频网| 91综合在线| 人妻社区男人天堂| 日韩欧美经典在线观看| 国产精品片| 欧美一级专区免费大片| 婷婷五月天成人网| 欧美gv在线观看| 屁股久久久久久久久| 97人人草| 隔壁邻居波多野结衣中文字幕 | 久久久久久久久久久久97| 欧美拳交在线播放| 国产 日韩 欧美高清| 一本一道久久综合久久| 夜夜高潮夜夜爽高清视频一| 亚洲最新av无码成人精品区| 久夜操| 91高跟美女在线播放| 婷婷中文网| 国产精品女aA片爽爽视频| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 97超碰亚洲| av九九| 日本三级A片网站com| 久久久青草青青国产亚洲免观精品高清完整版_97久久综合区小说区图片区,国精品 | 久久久久久久久久黄色网| 1769精品一区二区三区| 囯产精品久久久久久久久久梁医生 | 欧美线天码中字| 国内精品久久国产,www香蕉久久五月丁香,亚洲欧美日韩精品永久在线,日本精品一 | 91jk色拍| 黄污污污污| 日韩欧美tv一区二区在线观看| 人人妻人人爽一区二区三区| 欧洲与亚洲欧美精品中文字幕| 亚洲人妻av| 草草影院最新网址| 97精品久久| 亚洲第一页色网| 欧美亚洲高清不卡| 成人无码专区精品视频| 婷婷五月天小说| 亚洲综合中文字幕有码| 国产一区自拍欧美日韩| V A在线| 97色综合中文网| 啊啊啊操死我了| 伊人精品国产| 成人在线永久| 精品免费国产二区三区| 按摩中文字幕| 2020中文字幕| 青青草日韩无码| 免费黄色片子| 色色色99| 东京热免费视频| 亚洲综合色婷婷| 欧美性爱另类综合| 久久亚洲精品成人av| 秋霞久久亚洲精品成人| 无码高清国产AV| 久操网址| 日韩一区二区三区四区五区| 国产精品无码久久久久2025| 都市久久精品激情亚洲| 最新av中文字幕高清| 91啦人妻| 99这里只有精品国产| 级做a爱无码性色永久免费| 亚洲欧美日韩制服另类| 亚洲一区日韩精品| 亚洲激情综合另类男同| 欧美性爱无码一区二区三区| 久久久亚洲Av| 久久精品店| 黄aaaaaaaaaaaaaaaaaa色网站| 澳门特级毛片免费观看| 丁香五月天啪啪| 中文字幕老熟妇黄色视频| 成人在线视频二区| 99啪啪视频| 97精品久久久久中文字幕| 久久视频,这里只有精品| 91综合天天看| 1240青青草一区二区三区视频天爱| 99re在线| 岛国激情视频软件| 曰韩成人免费视频| 吻戏激情性巴克| 99re不伦| 国产亚热在线久久| 777超碰| 熟妇xxxxx性春色| aaaa黄片| 中文字幕视频在线观看一区二区| 少妇极品熟妇人妻无码| 亚洲在线A| 亚洲无 码A片在线观看麻豆| 8x福利精品第一福利视频导航| 欧美日韩国产高清在线一二三区 | 黑人黄片在线免费观看| 亚洲人妻一区二区三区| 日日干夜夜操视频h| 精国久久一区二区三区98| 九九九精品一区二区无码| 无码二级三级| 免费家庭乱伦视频| 午夜寂寞欧美| 亚洲国产精品久久久久婷婷青年| 欧美综合加勒比在线| 啊啊啊啊好疼视频| 天天影视亚洲| 久久激情亚洲精品无码?V| 国产欧美日韩在线不卡第一页| 中文字幕av色| 九九久久国产精品怡红院| 97天天| 极品尤物女神在线观看| av天堂影视中文在字幕在线中文| 欧美日韩亚洲五月天婷婷| 国产精品一区在线播放| 男人天堂黄片| 人妻少妇色综合| 亚洲综合69| 美女诱惑久久| 人人插人人搞人人操| 熟女中出视频| 精品夜夜澡人妻无码AV| 欧美操逼熟女| 青青11操操操操操操操操| 91熟女少妇| 日本影视久久免费| 婷婷久久五月天| juliaann丝袜大战黑鬼| 一区二区三区国产在线播放| 黄色免费一级在线毛片| 欧美刺激色黄片免费看| 日韩不卡网操逼中文字幕日韩| 日本精品一区二区不卡| 深夜激情无码| 欧美性暴力猛交XXXX | 成人看片网站| 欧美天堂亚洲电影院一区在线播放| 超碰91在线| 女人被添高潮免费视频| 99热日| 久久丁香久草综合网| 精品四五区| 国产精选视频| 亚洲砖码砖专无区2023| 亚洲欧美日韩电影网站一区 | 久99久视频| 中文日韩欧美熟| 大香蕉AV在线| 死我十八禁| 丝袜美腿制服人妻二区中文字幕| 操香逼| 偷拍 欧美 日韩| 密乳无码| 国产青青美女玩逼视频| 少妇一级婬片免费放一级a性色.| 青青草九九九九九| 91综合色噜噜| 天美国产三级传媒| 色激情综合网站| julia高潮后不停追击中出| 日本一线产区和二线产区伦理片| 女人被添高潮免费视频| 久久精品成人一区二区三区蜜臀| 午夜无码精品免费看性色| 蜜臀久久在线视频| 亚洲成人一区二区精品| 97精品久久久久中文字幕| 人人操人人叉人人插人人| 欧美中字二区| 国产亚洲美日韩Aⅴ中文字幕无码成人| 蘋果手機免費看成人Av| 中文字幕日韩人妻视频| 偷拍片久久| 蜜乳性色无码专日粉嫩骚逼AV| 久草线上视频免费看| 亚洲乱熟女一区二区三区大香蕉| 后入式999| 久久久久人妻| 中日韓欧美高清| 人妻精品一区二区全免费| 久久精品国产欧美日韩亚洲欧美日韩中文久久国产一区 | 欧洲射精91| 黄色视频60分钟| 久久伦理视频久久大香蕉视频| 国产激情av女片自拍| 91熟女丨91老女人| 国产精品91一样| 影视综合无码少妇| 欧洲亚洲天堂精品| 五月丁香婷婷啪啪| 五月天亚洲网| 97九色人妻| 亚洲精品性爱片| 国产热av| 日本淫色网| 久久青青草原免费视频| 中文字幕黄色一起草| 日韩久久超碰色| 欧美人与性动交a美精品| 日产精品久久久一区二区| 五月天色综合| 逼操网站| 97操| 欧美日韩天堂| 97干日韩| 无码日韩人妻av一| 天天看天天日| 91嫩草在线| 精精夜夜| 熟女乱伦二区| 日本成熟少妇A∨网站| 精品少妇人妻一区二区三区| 色色亚洲| 高清国产成人无码| 国产一线二线三线av| 久久m| 骚货| 五月丁香社区婷婷日韩欧美精品影院 | 超碰精品人妻狠狠干| 97超碰碰碰| 99久久精品国产高潮| 久久狠狠色噜噜狠狠狠狠97| 一级免费精品| 99热这里只有精品8| 九九久久一区二区伦理| 黄片视频观看| 久久亚洲日韩熟女精品| 超碰地址97| 天天综合亚在线| 九月婷婷久久| 无色无码| 人妻丰满熟妇一区二区三| 国产女人视频三四五区| 成人一级二级| 中文字幕视频免费| 裸模AV女优| 67914亚洲精品| 久久婷婷视频| 69麻豆天美| 亚洲视频精选| 深喉吞精| 五月天亚洲网| 国偷自 一区二区| 天美传媒在线一区| 91精品电影18| 精品无码一区二区| 久久久久9| 大香蕉免费乱伦视频| 久久毛卡| 性爱乱伦视频免费| 国产亚洲精品无码三区| 亚洲国产精品久久AV| 熟女人妻精品一区二区视频 | 超碰人妻97| 中文无线日韩一区| 国产乱不卡| 丰满熟妇大乳做爰| 98福利在线视频| 美女91av| 91爱看| 九九免费影片| 精品少妇一区二区| 97资源站久久| 久久久无码精品人妻二区 | 久久东京热久久| 夜夜嗨一区| 久久内射| 青青草一区二区高清无码视频| 天天天堂影视日韩亚洲91| 日本黄色XXX| 色悠久久久av| 97爱爱官网| 我想要 啊 啊 啊| 欧美性夜| 91视频伊人| 精品国产乱码久久久A| 国产久久久久久| 日韩啊V| 亚洲电影中字一区二区| 国产日韩区| 在线精品福利免费播放| 国产做?爰片久久毛片?片美国| 激情五月丁香五月| 亚洲精品男人的天堂| 四虎永久在线精品免费网址| 9精品在线| 日韩天天本| 大茄子熟女AV导航| 国产精品精品系列在线观看| 色波多| 黄色性爱网网| 校园春色之综合网| 欧美日韩国产中文超碰| 亚洲少妇在线影音| 国产又长又大又粗的视频| 九色黄站| 免费精品中文字幕| www.av在线观看| 肉丝网站91| 99999这里都精品| 夜夜夜夜久久久久| 性爱乱伦视频免费| 欧美探花网| 五月天激情小说网| 男人久久精品| 欧美在线大香999| 久久 国产 无码| 插欧洲美女欧美精品| 91久久久久免| 亚洲日本天堂| 国产91影院| 欧美系列在线一区二区| 中文字幕一区 二 区 三 四 五 区日 日 骚 | 亚洲国产一级精品毛一级精品看免费视频 | 水野优香在线观看| 高潮综合网| 一区二区视频在看| 日本高清_区二区三区| 久草综合京东| 成人一级二级| 色在线综合| 综合网欧美在线| 国产有码一区| 白嫩白嫩的午夜九久久久久久久久久久久成人剧场 | 欧美激情一区二区| 国产sv美女内射| 日本高清视频xxxx| 欧美午夜精品久久久久久超碰| 制服丝袜第二页| www.av家庭乱伦| 人人操AV| 亚洲区小说| av强奸乱轮| 久草资源在线视频官方总站日韩丝袜美腿 | 国产欧洲精品亚洲午夜拍精品| 中文久久久| 日韩成人电影AV| 亚洲人综合| 中文字幕日韩精品久久| 极品丝袜无码| 97伊人| 久久国内| 美女91av| 亚洲精品无码久久AV| 日韩专区数据列表-第3230页-精品国产一区二区三区香蕉 久久99熟女人妻中文字 | 国产午夜视频| 超碰97护士| 青青操青娱乐| 快灬快灬 一下爽蜜桃在线观看| 色操逼网| 麻豆一区二区三区精品| 欧美成人A√在线一区二区| 思思热在线| 夜夜高潮夜夜爽夜夜爱爱一区| 亚洲女毛多水多21P| 久久久久亚洲一区女同性恋中文字幕| 操逼网站网站| 大香蕉天天看妹子| 曰韩中文人妻视频| 大香蕉AV丝袜| 国产乱子伦一区二区三区在线观看| 操逼操操操91| 欧美丝袜91| 啪啪一区| 日韩本不卡视频在线观看| 久久久com| 葡萄牙性视频一二区| 午夜男人一级A片7777| 极品人妻少妇综合| 亚洲高潮少妇| 色区97| 天天射,天天操,天天爽-国内精品一区二区三区-成人AV | 加勒比AV天堂| 乱伦av.com| 97网站在线观看 | 天天操女人| 亚洲欧洲自拍图片专区满春格| 麻豆天美传媒在线视频天堂| 婷婷伊人五月| 人妻酒店出差被中出免费在线播放| 人人操人人插人人摸人人干| 久久久久亚洲精品| 亚洲欧美日韩精品久| 天天干人人乐| 精品视频免费在线一区| 国产精品69久久久久孕妇欧美 | 天天天堂影视日韩亚洲91| 激情啪啪拍91| 亚洲资源站| 丁香六月激情| 91亚洲欧洲| 密臀视频一区二区三区| 日韩久久激情精品| 啊啊啊啊嗯嗯在线久久久| 蜜桃传媒一区二区亚洲| 亚州免费啪啪视频| 女人天堂网| 99re6久热只有精品6在线直播 | 五月天色五月| 婷婷干黄色| 亚洲人精品久久久| av九九| 国产亚洲精品美女久久久| 中文字幕第7页| 内射黑人| 亚洲日韩美女中文字幕乱| 91n欧美| 热热色色综合| 色婷婷五月综合| 日韩图区 偷拍| 日本一区二区三区四区五区六区七区八区九区| 日韩人妻操B| 3p国产色噜噜一区| 久草精品国产99| 久久久99999久网站| 精品超碰国产| 亚川综合视频| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区 | 青青青国产| 全球成人中文在线| 老熟女乱伦一区| 久久精品无码不卡| 97资源欧美| 五月激情天| 波多野结衣一级视频| 加勒比海色香蕉婷婷| 欧美日韩97在线| 粉嫩少妇自慰在线| 国产精品青草综合久久| 国产女人与拘做受视频免费| 久肏视频字幕| 老熟乱一区二区三区四区| av大香蕉网站| 七久久久| 99久久9| 亚洲一区日韩精品| 香蕉99秘 一区精品蜜桃臀| 久久久久斤小| 亚 欧 美 综合| 偷窥自拍亚洲天堂网爆| 性久久| 欧美色亚洲色| 人妻熟女一区二区| 欧美情色贴图| 成人熟女视频一区二区三区| 亚洲无码一区二区三区三州| 丰满人妻无码一区二区三区| 亚洲最新Av| 久热最新在线杭州| 亚洲情色 自拍| 亚洲成人AB| 欧美日韩精品久久久久东北老熟妇| 欧亚第一综合网| 夜夜操老骚逼视频网站| 91亚洲黑人| 中文字幕交换人妻| 亚洲自拍天堂| 园内精品自拍视频在线播放| 男女做爰猛烈动高潮A片免费应用| 亚洲色婷婷综合久久一区二区三区| 国产精品在线一区二区| 2026国产精品视频| 天堂国产AV| 青久操| 亚洲欧美setu| 91强在线播放| silk lablo在线观看一区二区| 又摸又舔在线观看网站| 国产天天看| 人人喜人人妻| 台湾佬中文娱乐自偷自拍| 夜夜狼人妻| 欧美 日韩 另类 亚洲| 久插综合| 97频视在线| 日本熟妇自慰性高潮一区二区三区| 国产中文日韩欧美一区二区三区人妻丝袜美腿| 欧美曰韩国产精品| 高潮综合网| 中日韩久久久免费看| 91 天天综合| 97视频播放| 91福利网在线观看|