久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

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

面試官:MyBatis你只寫(xiě)了接口為啥就能執(zhí)行SQL?。?/h1>

一、面試現(xiàn)場(chǎng)一個(gè)讓無(wú)數(shù)人卡殼的問(wèn)題1.1 面試對(duì)話還原面試官翻了翻簡(jiǎn)歷看到熟練掌握 MyBatis抬起頭問(wèn)了一句你說(shuō)你熟悉 MyBatis那我問(wèn)你你的UserMapper只是一個(gè)接口沒(méi)有實(shí)現(xiàn)類為什么調(diào)用userMapper.selectById(1L)就能執(zhí)行 SQL 呢候選人開(kāi)始回憶因?yàn)椤璏yBatis 用了動(dòng)態(tài)代理面試官追問(wèn)什么動(dòng)態(tài)代理JDK 還是 CGLIB代理對(duì)象是什么時(shí)候生成的selectById又是怎么映射到 XML 里的 SQL 的候選人這個(gè)……應(yīng)該是啟動(dòng)的時(shí)候掃描 XML 吧……面試官那你說(shuō)說(shuō)如果 Mapper 接口有兩個(gè)同名方法MyBatis 能區(qū)分嗎如果 XML 的 namespace 寫(xiě)錯(cuò)了會(huì)怎樣到這里很多候選人已經(jīng)答不上來(lái)了。這個(gè)問(wèn)題看似簡(jiǎn)單實(shí)則是一道分水嶺題——它能一次性考察你對(duì)JDK 動(dòng)態(tài)代理、MyBatis 初始化流程、MapperRegistry 注冊(cè)機(jī)制、MapperProxy 調(diào)用鏈、MapperMethod 方法映射、SqlSession 執(zhí)行流程、Executor 執(zhí)行器體系的理解深度。1.2 為什么面試官愛(ài)問(wèn)這道題這道題的價(jià)值在于看你是不是只會(huì)用很多人用 MyBatis 幾年但從來(lái)沒(méi)想過(guò)接口為什么能執(zhí)行 SQL看你能不能講清原理從接口到代理從代理到 SQL這條鏈路涉及多個(gè)核心組件看你能不能延伸到實(shí)戰(zhàn)Mapper 重載為什么不支持、namespace 寫(xiě)錯(cuò)會(huì)怎樣、二級(jí)緩存與代理的關(guān)系看你能不能對(duì)比技術(shù)和 Spring Data JPA 的接口自動(dòng)實(shí)現(xiàn)有什么區(qū)別本文結(jié)構(gòu)一句話結(jié)論從使用場(chǎng)景到實(shí)現(xiàn)原理JDK 動(dòng)態(tài)代理基礎(chǔ)MyBatis 初始化流程Mapper 是怎么被注冊(cè)的MapperProxyFactory代理工廠MapperProxy方法調(diào)用的攔截器MapperMethod方法到 SQL 的映射SqlSession 與 ExecutorSQL 真正執(zhí)行的地方為什么 Mapper 接口不支持方法重載實(shí)戰(zhàn)問(wèn)題排查高頻追問(wèn)與回答模板總結(jié)二、一句話結(jié)論MyBatis 在啟動(dòng)時(shí)通過(guò) JDK 動(dòng)態(tài)代理為每個(gè) Mapper 接口生成了一個(gè)代理對(duì)象。你調(diào)用的userMapper.selectById(1L)實(shí)際上調(diào)用的是這個(gè)代理對(duì)象的invoke()方法。代理對(duì)象內(nèi)部根據(jù)接口全限定名 方法名找到對(duì)應(yīng)的 SQL 語(yǔ)句MappedStatement然后交給 SqlSession 執(zhí)行。一句話總結(jié)接口不能執(zhí)行 SQL能執(zhí)行 SQL 的是 MyBatis 生成的代理對(duì)象。三、從使用場(chǎng)景到實(shí)現(xiàn)原理3.1 一個(gè)最簡(jiǎn)單的 MyBatis 使用例子javapublic interface UserMapper { User selectById(Long id); }xmlmapper namespacecom.example.mapper.UserMapper select idselectById resultTypecom.example.entity.User SELECT * FROM user WHERE id #{id} /select /mapperjavaSqlSession sqlSession sqlSessionFactory.openSession(); UserMapper userMapper sqlSession.getMapper(UserMapper.class); User user userMapper.selectById(1L);疑惑UserMapper只是一個(gè)接口沒(méi)有實(shí)現(xiàn)類userMapper.selectById(1L)卻可以執(zhí)行 SQL。這是為什么3.2 核心答案動(dòng)態(tài)代理sqlSession.getMapper(UserMapper.class)返回的并不是UserMapper的某個(gè)實(shí)現(xiàn)類而是MyBatis 通過(guò) JDK 動(dòng)態(tài)代理生成的一個(gè)代理對(duì)象。這個(gè)代理對(duì)象實(shí)現(xiàn)了UserMapper接口因此可以賦值給UserMapper類型的變量。但它所有的方法調(diào)用都會(huì)被攔截到MapperProxy.invoke()方法中在invoke()里完成找到 SQL、執(zhí)行 SQL、返回結(jié)果的全流程。四、JDK 動(dòng)態(tài)代理基礎(chǔ)4.1 什么是 JDK 動(dòng)態(tài)代理JDK 動(dòng)態(tài)代理是 Java 原生提供的代理機(jī)制位于java.lang.reflect包下。它要求目標(biāo)對(duì)象必須實(shí)現(xiàn)接口這是 JDK 動(dòng)態(tài)代理的硬性要求代理對(duì)象與目標(biāo)對(duì)象實(shí)現(xiàn)相同的接口方法調(diào)用會(huì)被InvocationHandler.invoke()攔截4.2 JDK 動(dòng)態(tài)代理的核心 APIjavapublic interface InvocationHandler { Object invoke(Object proxy, Method method, Object[] args) throws Throwable; } public static Object newProxyInstance( ClassLoader loader, Class?[] interfaces, InvocationHandler h)4.3 一個(gè)簡(jiǎn)單的 JDK 動(dòng)態(tài)代理示例javapublic interface UserService { void sayHello(String name); } public class UserServiceImpl implements UserService { Override public void sayHello(String name) { System.out.println(Hello, name); } } public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target) { this.target target; } Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(before method: method.getName()); Object result method.invoke(target, args); System.out.println(after method: method.getName()); return result; } } public class Main { public static void main(String[] args) { UserService target new UserServiceImpl(); UserService proxy (UserService) Proxy.newProxyInstance( target.getClass().getClassLoader(), new Class?[]{UserService.class}, new MyInvocationHandler(target) ); proxy.sayHello(張三); } }輸出textbefore method: sayHello Hello, 張三 after method: sayHello關(guān)鍵點(diǎn)代理對(duì)象實(shí)現(xiàn)了UserService接口但它的所有方法調(diào)用都會(huì)先進(jìn)入InvocationHandler.invoke()。4.4 MyBatis 是怎么用這套機(jī)制的MyBatis 生成的 Mapper 代理和上面的例子類似但有兩點(diǎn)不同目標(biāo)對(duì)象不存在MyBatis 沒(méi)有為接口寫(xiě)實(shí)現(xiàn)類所以代理對(duì)象不需要委托給 target攔截邏輯不同MapperProxy.invoke()不是簡(jiǎn)單地前后加日志而是根據(jù)方法名找到 SQL 并執(zhí)行換句話說(shuō)MyBatis 的代理對(duì)象就是一個(gè)空殼它唯一的作用就是把接口方法調(diào)用轉(zhuǎn)換成 SQL 執(zhí)行。五、MyBatis 初始化流程Mapper 是怎么被注冊(cè)的5.1 從 SqlSessionFactory 的構(gòu)建說(shuō)起MyBatis 啟動(dòng)時(shí)會(huì)解析mybatis-config.xml和所有 Mapper XML構(gòu)建一個(gè)Configuration對(duì)象并封裝成SqlSessionFactory。核心流程textSqlSessionFactoryBuilder.build() → XMLConfigBuilder.parse() → Configuration 初始化 → mapperElement() 解析 mappers 標(biāo)簽 → MapperRegistry.addMapper()5.2 解析 mappers 標(biāo)簽mybatis-config.xml中配置xmlmappers mapper resourcemapper/UserMapper.xml/ package namecom.example.mapper/ /mappersXMLConfigBuilder.mapperElement()會(huì)遍歷這些配置逐一處理。以package為例它會(huì)掃描包下所有.class文件找出所有接口不是類、不是枚舉、不是注解為每個(gè)接口調(diào)用configuration.addMapper(interface)5.3 MapperRegistry接口注冊(cè)中心Configuration內(nèi)部維護(hù)了一個(gè)MapperRegistryjavapublic class MapperRegistry { private final Configuration config; private final MapClass?, MapperProxyFactory? knownMappers new HashMap(); public T void addMapper(ClassT type) { if (type.isInterface()) { if (hasMapper(type)) { throw new BindingException(Type type is already known to the MapperRegistry.); } boolean loadCompleted false; try { // 核心為接口創(chuàng)建 MapperProxyFactory knownMappers.put(type, new MapperProxyFactory(type)); // 解析 XML如果存在同名的 .xml 文件 MapperAnnotationBuilder parser new MapperAnnotationBuilder(config, type); parser.parse(); loadCompleted true; } finally { if (!loadCompleted) { knownMappers.remove(type); } } } } }關(guān)鍵knownMappers的 key 是接口的Class對(duì)象value 是MapperProxyFactory只有接口才會(huì)被注冊(cè)type.isInterface()注冊(cè)后會(huì)立即解析注解和 XML把MappedStatement放進(jìn)Configuration5.4 XML 的 namespace 必須等于接口全限定名這一點(diǎn)非常關(guān)鍵MyBatis 在解析 XML 時(shí)會(huì)讀取mapper namespace...然后嘗試通過(guò)Resources.classForName(namespace)加載這個(gè)類如果成功調(diào)用configuration.addMapper(namespaceClass)如果失敗比如 namespace 拼寫(xiě)錯(cuò)誤不會(huì)拋出異常但Mapper 接口和 XML 就沒(méi)有關(guān)聯(lián)這就是為什么很多初學(xué)者遇到Invalid bound statement (not found)報(bào)錯(cuò)——十有八九是 namespace 寫(xiě)錯(cuò)了。六、MapperProxyFactory代理工廠6.1 作用MapperProxyFactoryT是一個(gè)泛型工廠類負(fù)責(zé)為指定的 Mapper 接口生成代理對(duì)象。它被注冊(cè)在MapperRegistry.knownMappers中等待getMapper調(diào)用。6.2 核心源碼javapublic class MapperProxyFactoryT { private final ClassT mapperInterface; private final MapMethod, MapperMethodInvoker methodCache new ConcurrentHashMap(); public MapperProxyFactory(ClassT mapperInterface) { this.mapperInterface mapperInterface; } public ClassT getMapperInterface() { return mapperInterface; } public MapMethod, MapperMethodInvoker getMethodCache() { return methodCache; } // 核心方法生成代理對(duì)象 protected T newInstance(MapperProxyT mapperProxy) { return (T) Proxy.newProxyInstance( mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy); } public T newInstance(SqlSession sqlSession) { final MapperProxyT mapperProxy new MapperProxy(sqlSession, mapperInterface, methodCache); return newInstance(mapperProxy); } }關(guān)鍵點(diǎn)newInstance(SqlSession)中創(chuàng)建了一個(gè)MapperProxy然后把SqlSession、接口 Class、方法緩存?zhèn)鬟M(jìn)去Proxy.newProxyInstance傳入的接口數(shù)組只有mapperInterface因此代理對(duì)象只實(shí)現(xiàn)這一個(gè)接口代理對(duì)象不委托任何 target因?yàn)?MyBatis 沒(méi)有實(shí)現(xiàn)類代理對(duì)象自己就是實(shí)現(xiàn)6.3 methodCache為什么需要緩存methodCache是一個(gè)ConcurrentHashMapMethod, MapperMethodInvoker它緩存了方法 - MapperMethod的映射。為什么需要緩存每次調(diào)用mapper.selectById(1L)時(shí)MapperProxy.invoke()需要根據(jù)Method找到對(duì)應(yīng)的MapperMethod如果不緩存每次都要重新解析注解、拼接 statementId性能會(huì)受影響Method對(duì)象在同一個(gè)類中是唯一的作為 key 很合適用ConcurrentHashMap保證線程安全6.4 代理對(duì)象的生命周期代理對(duì)象是SqlSession級(jí)別的還是應(yīng)用級(jí)別的答代理對(duì)象由MapperProxyFactory.newInstance(sqlSession)生成每次調(diào)用sqlSession.getMapper()都會(huì)生成一個(gè)新的代理對(duì)象。但MapperProxyFactory和methodCache是應(yīng)用級(jí)別的由Configuration持有所以代理對(duì)象每次getMapper都新建但 JVM 會(huì)對(duì)相同接口的代理類進(jìn)行復(fù)用代理 Class 只會(huì)生成一次methodCache應(yīng)用級(jí)別共享方法映射只解析一次七、MapperProxy方法調(diào)用的攔截器7.1 作用MapperProxyT實(shí)現(xiàn)了InvocationHandler是所有 Mapper 方法調(diào)用的統(tǒng)一入口。7.2 核心源碼javapublic class MapperProxyT implements InvocationHandler, Serializable { private final SqlSession sqlSession; private final ClassT mapperInterface; private final MapMethod, MapperMethodInvoker methodCache; public MapperProxy(SqlSession sqlSession, ClassT mapperInterface, MapMethod, MapperMethodInvoker methodCache) { this.sqlSession sqlSession; this.mapperInterface mapperInterface; this.methodCache methodCache; } Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { // 1. 如果調(diào)用的是 Object 類的方法toString、hashCode、equals直接執(zhí)行 if (Object.class.equals(method.getDeclaringClass())) { return method.invoke(this, args); } // 2. 如果調(diào)用的是接口默認(rèn)方法Java 8走默認(rèn)實(shí)現(xiàn) if (method.isDefault()) { return invokeDefaultMethod(proxy, method, args); } } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } // 3. 核心獲取或創(chuàng)建 MapperMethod然后調(diào)用 final MapperMethodInvoker mapperMethod cachedMapperMethod(method); return mapperMethod.invoke(proxy, method, args, sqlSession); } private MapperMethodInvoker cachedMapperMethod(Method method) { return methodCache.computeIfAbsent(method, k - new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()))); } }關(guān)鍵點(diǎn)Object 方法toString、hashCode、equals直接被代理對(duì)象自己處理默認(rèn)方法Java 8 的接口默認(rèn)方法走M(jìn)ethodHandles調(diào)用不進(jìn)入 SQL 執(zhí)行流程普通方法走M(jìn)apperMethod執(zhí)行 SQLcachedMapperMethod用computeIfAbsent保證MapperMethod只被創(chuàng)建一次7.3 PlainMethodInvoker 與 DefaultMethodInvokerMyBatis 3.5.x 引入了MapperMethodInvoker接口有兩個(gè)實(shí)現(xiàn)PlainMethodInvoker普通方法走 SQL 執(zhí)行DefaultMethodInvoker默認(rèn)方法走 Java 默認(rèn)實(shí)現(xiàn)這種設(shè)計(jì)讓默認(rèn)方法和接口方法的執(zhí)行路徑分離代碼更清晰。7.4 一個(gè)完整調(diào)用鏈textuserMapper.selectById(1L) → 代理對(duì)象.selectById(1L) → MapperProxy.invoke(proxy, selectById, [1L]) → cachedMapperMethod(selectById) // 從 methodCache 獲取或創(chuàng)建 → PlainMethodInvoker.invoke() → MapperMethod.execute(sqlSession, args) → SqlSession.selectOne(statementId, args) → Executor.query(...) → JDBC 執(zhí)行 SQL八、MapperMethod方法到 SQL 的映射8.1 MapperMethod 的組成MapperMethod是方法到 SQL 的橋梁它由兩部分組成javapublic class MapperMethod { private final SqlCommand command; private final MethodSignature method; public MapperMethod(Class? mapperInterface, Method method, Configuration config) { this.command new SqlCommand(config, mapperInterface, method); this.method new MethodSignature(config, mapperInterface, method); } }SqlCommand負(fù)責(zé)找到對(duì)應(yīng)的 SQL 語(yǔ)句MethodSignature負(fù)責(zé)解析方法的返回值、參數(shù)等信息8.2 SqlCommand從方法到 statementIdjavapublic static class SqlCommand { private final String name; // statementId private final SqlCommandType type; // SELECT / INSERT / UPDATE / DELETE public SqlCommand(Configuration configuration, Class? mapperInterface, Method method) { // 1. 拼接 statementId 接口全限定名 . 方法名 final String methodName method.getName(); final Class? declaringClass method.getDeclaringClass(); MappedStatement ms resolveMappedStatement(mapperInterface, methodName, declaringClass, configuration); if (ms null) { throw new BindingException(Invalid bound statement (not found): mapperInterface.getName() . methodName); } this.name ms.getId(); this.type ms.getSqlCommandType(); } }關(guān)鍵statementId 接口全限定名 . 方法名例如com.example.mapper.UserMapper.selectById用這個(gè) statementId 去Configuration.mappedStatements中查找MappedStatement找不到就拋出BindingException這就是Invalid bound statement的由來(lái)8.3 MethodSignature方法簽名解析MethodSignature負(fù)責(zé)解析返回值類型void、Object、List、Map、Cursor等參數(shù)位置Param注解、RowBounds、ResultHandler是否是MapKey方法返回Map時(shí)用哪個(gè)字段作為 keyjavapublic static class MethodSignature { private final boolean returnsMany; // 是否返回集合 private final boolean returnsMap; // 是否返回 Map private final boolean returnsVoid; // 是否返回 void private final boolean returnsCursor; // 是否返回 Cursor private final Class? returnType; // 返回類型 private final String mapKey; // MapKey 的值 private final Integer resultHandlerIndex; private final Integer rowBoundsIndex; private final ParamNameResolver paramNameResolver; }8.4 execute 方法根據(jù) SQL 類型分發(fā)javapublic Object execute(SqlSession sqlSession, Object[] args) { Object result; switch (command.getType()) { case INSERT: { Object param method.convertArgsToSqlCommandParam(args); result rowCountResult(sqlSession.insert(command.getName(), param)); break; } case UPDATE: { Object param method.convertArgsToSqlCommandParam(args); result rowCountResult(sqlSession.update(command.getName(), param)); break; } case DELETE: { Object param method.convertArgsToSqlCommandParam(args); result rowCountResult(sqlSession.delete(command.getName(), param)); break; } case SELECT: if (method.returnsVoid() method.hasResultHandler()) { executeWithResultHandler(sqlSession, args); result null; } else if (method.returnsMany()) { result executeForMany(sqlSession, args); } else if (method.returnsMap()) { result executeForMap(sqlSession, args); } else if (method.returnsCursor()) { result executeForCursor(sqlSession, args); } else { Object param method.convertArgsToSqlCommandParam(args); result sqlSession.selectOne(command.getName(), param); if (method.returnsOptional() (result null || !method.getReturnType().equals(result.getClass()))) { result Optional.ofNullable(result); } } break; case FLUSH: result sqlSession.flushStatements(); break; default: throw new BindingException(Unknown execution method for: command.getName()); } if (result null method.getReturnType().isPrimitive() !method.returnsVoid()) { throw new BindingException(Mapper method command.getName() attempted to return null from a method with a primitive return type ( method.getReturnType() ).); } return result; }關(guān)鍵根據(jù)SqlCommandType決定調(diào)用sqlSession.insert、update、delete還是selectOneSelect、Insert、Update、Delete注解也是在這一步被識(shí)別的九、SqlSession 與 ExecutorSQL 真正執(zhí)行的地方9.1 SqlSession用戶接口SqlSession是 MyBatis 對(duì)外的核心接口封裝了所有數(shù)據(jù)庫(kù)操作javapublic interface SqlSession extends Closeable { T T selectOne(String statement); T T selectOne(String statement, Object parameter); E ListE selectList(String statement); E ListE selectList(String statement, Object parameter); int insert(String statement); int update(String statement); int delete(String statement); // ... }它的默認(rèn)實(shí)現(xiàn)是DefaultSqlSession內(nèi)部持有一個(gè)Executor。9.2 Executor執(zhí)行器體系Executor是 MyBatis 的核心執(zhí)行器采用裝飾器模式組織textExecutor接口 ├── BaseExecutor抽象類實(shí)現(xiàn)模板方法 │ ├── SimpleExecutor簡(jiǎn)單執(zhí)行器每次新建 Statement │ ├── ReuseExecutor復(fù)用執(zhí)行器緩存 Statement │ └── BatchExecutor批量執(zhí)行器批量提交 ├── CachingExecutor二級(jí)緩存裝飾器 └── ...當(dāng)SqlSession.selectOne()被調(diào)用時(shí)執(zhí)行流程是textDefaultSqlSession.selectOne() → DefaultSqlSession.selectList() → CachingExecutor.query() // 如果開(kāi)啟二級(jí)緩存 → BaseExecutor.query() → 一級(jí)緩存查詢PerpetualCache → 緩存未命中 → queryFromDatabase() → SimpleExecutor.doQuery() → StatementHandler.prepare() → StatementHandler.parameterize() → StatementHandler.query() → ResultSetHandler.handleResultSets() → 返回結(jié)果9.3 StatementHandlerSQL 語(yǔ)句處理器StatementHandler是真正和 JDBC 打交道的地方有四種實(shí)現(xiàn)SimpleStatementHandler普通 StatementPreparedStatementHandler預(yù)編譯 Statement默認(rèn)CallableStatementHandler存儲(chǔ)過(guò)程RoutingStatementHandler根據(jù) MappedStatement 的 statementType 路由9.4 ResultSetHandler結(jié)果集處理器ResultSetHandler負(fù)責(zé)把 JDBC 的ResultSet轉(zhuǎn)換成 Java 對(duì)象主要工作自動(dòng)映射根據(jù)列名和屬性名自動(dòng)匹配手動(dòng)映射根據(jù)resultMap配置映射類型轉(zhuǎn)換調(diào)用TypeHandler把 JDBC 類型轉(zhuǎn)換為 Java 類型十、為什么 Mapper 接口不支持方法重載10.1 MyBatis 的映射規(guī)則MyBatis 的statementId是接口全限定名 . 方法名例如textcom.example.mapper.UserMapper.selectById注意這個(gè)方法名里不包含參數(shù)信息。10.2 重載會(huì)導(dǎo)致什么問(wèn)題如果 Mapper 接口定義了兩個(gè)同名方法javapublic interface UserMapper { User selectById(Long id); User selectById(Long id, boolean includeDeleted); }兩個(gè)方法對(duì)應(yīng)的 statementId 都是textcom.example.mapper.UserMapper.selectById在Configuration.mappedStatements中這個(gè) statementId 只能對(duì)應(yīng)一個(gè)MappedStatement。后注冊(cè)的會(huì)覆蓋先注冊(cè)的導(dǎo)致其中一個(gè)方法找不到 SQL或走錯(cuò) SQL。10.3 官方立場(chǎng)MyBatis 官方文檔明確說(shuō)明Mapper 接口不支持方法重載。這也是為什么 MyBatis 的 Mapper 方法命名通常很具體例如selectById、selectByUserIdAndStatus。10.4 面試加分點(diǎn)如果面試官問(wèn)為什么 Mapper 不支持重載你可以這樣回答MyBatis 的映射規(guī)則是 statementId 接口全限定名 . 方法名不包含參數(shù)信息。所以兩個(gè)同名方法會(huì)映射到同一個(gè) statementId導(dǎo)致覆蓋或沖突。如果要支持重載MyBatis 需要把參數(shù)信息也納入 statementId但這會(huì)破壞現(xiàn)有的 XML namespace id 的唯一性約束因此官方明確不支持。十一、實(shí)戰(zhàn)問(wèn)題排查11.1 常見(jiàn)錯(cuò)誤一Invalid bound statement (not found)現(xiàn)象textorg.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.mapper.UserMapper.selectById排查XML 的namespace是否等于 Mapper 接口的全限定名XML 的select id...是否等于方法名XML 是否在 MyBatis 的掃描路徑下mybatis.mapper-locationsMapper 接口是否被Mapper或MapperScan掃描到如果使用 Spring Boot檢查mybatis-plus或mybatis-spring-boot-starter的自動(dòng)配置11.2 常見(jiàn)錯(cuò)誤二方法重載導(dǎo)致的沖突現(xiàn)象兩個(gè)同名方法只有一個(gè)能正常工作。排查檢查 Mapper 接口是否有重載方法。如果確實(shí)需要重載改為不同方法名。11.3 常見(jiàn)錯(cuò)誤三代理對(duì)象類型轉(zhuǎn)換異?,F(xiàn)象textjava.lang.ClassCastException: com.sun.proxy.$Proxy123 cannot be cast to com.example.mapper.UserMapperImpl排查MyBatis 生成的代理對(duì)象只實(shí)現(xiàn)了 Mapper 接口不能轉(zhuǎn)換為任何實(shí)現(xiàn)類。檢查是否錯(cuò)誤地把代理對(duì)象強(qiáng)轉(zhuǎn)為具體實(shí)現(xiàn)類。11.4 常見(jiàn)錯(cuò)誤四默認(rèn)方法調(diào)用不走 SQL現(xiàn)象Mapper 接口中定義了默認(rèn)方法調(diào)用時(shí)不執(zhí)行 SQL。排查Java 8 的默認(rèn)方法走DefaultMethodInvoker不進(jìn)入 SQL 執(zhí)行流程。如果默認(rèn)方法內(nèi)部調(diào)用了接口方法那些接口方法依然會(huì)走代理執(zhí)行 SQL。11.5 常見(jiàn)錯(cuò)誤五Object 方法被誤用現(xiàn)象在代碼中調(diào)用userMapper.toString()、userMapper.hashCode()返回的是代理對(duì)象的實(shí)現(xiàn)而不是 SQL 執(zhí)行結(jié)果。排查這是正常行為MapperProxy.invoke()對(duì)Object類方法做了特殊處理。不要在 Mapper 中定義toString等方法的業(yè)務(wù)語(yǔ)義。十二、高頻追問(wèn)與回答模板12.1 高頻追問(wèn)MyBatis 的 Mapper 接口為什么能執(zhí)行 SQL動(dòng)態(tài)代理是 JDK 的還是 CGLIB 的代理對(duì)象什么時(shí)候創(chuàng)建的MapperProxyFactory和MapperProxy有什么區(qū)別MapperMethod是怎么找到 SQL 的為什么 Mapper 不支持重載Mapper 接口和 XML 的 namespace 必須一致嗎一級(jí)緩存和二級(jí)緩存在哪個(gè)環(huán)節(jié)生效多個(gè) SqlSession 使用同一個(gè) Mapper 接口代理對(duì)象是同一個(gè)嗎MyBatis 和 Spring Data JPA 的接口自動(dòng)實(shí)現(xiàn)在原理上有什么區(qū)別12.2 回答模板回答Mapper 接口為什么能執(zhí)行 SQL時(shí)可以按這個(gè)結(jié)構(gòu)組織一句話結(jié)論MyBatis 用 JDK 動(dòng)態(tài)代理為 Mapper 接口生成代理對(duì)象調(diào)用走M(jìn)apperProxy.invoke()。講啟動(dòng)階段MyBatis 啟動(dòng)時(shí)解析 XML 和注解通過(guò)MapperRegistry把接口和MapperProxyFactory關(guān)聯(lián)起來(lái)。講調(diào)用階段sqlSession.getMapper()生成代理對(duì)象調(diào)用方法時(shí)進(jìn)入MapperProxy.invoke()通過(guò)MapperMethod找到MappedStatement。講執(zhí)行階段MapperMethod.execute()根據(jù) SQL 類型調(diào)用SqlSession對(duì)應(yīng)方法最終由Executor和 JDBC 執(zhí)行。講約束statementId 是接口全限定名 方法名因此不支持方法重載namespace 必須匹配接口全限定名。12.3 對(duì)比 Spring Data JPA維度MyBatisSpring Data JPA接口實(shí)現(xiàn)方式JDK 動(dòng)態(tài)代理 MapperProxyJDK 動(dòng)態(tài)代理 RepositoryFactorySupport方法映射statementId 接口名 方法名方法名解析 Query 注解SQL 來(lái)源XML / 注解JPQL / 原生 SQL / 方法名派生靈活性高XML 可寫(xiě)復(fù)雜 SQL中復(fù)雜查詢需要 Query學(xué)習(xí)曲線中高十三、總結(jié)13.1 核心結(jié)論MyBatis 的 Mapper 接口能執(zhí)行 SQL是因?yàn)?MyBatis 用 JDK 動(dòng)態(tài)代理為接口生成了代理對(duì)象。完整鏈路text啟動(dòng)階段 解析 XML / 注解 → MapperRegistry.addMapper() → 創(chuàng)建 MapperProxyFactory → 放入 knownMappers 調(diào)用階段 sqlSession.getMapper(UserMapper.class) → MapperProxyFactory.newInstance(sqlSession) → 創(chuàng)建 MapperProxy → Proxy.newProxyInstance() 執(zhí)行階段 userMapper.selectById(1L) → MapperProxy.invoke() → MapperMethod.execute() → SqlSession.selectOne() → Executor.query() → JDBC 執(zhí)行 SQL13.2 關(guān)鍵要點(diǎn)動(dòng)態(tài)代理類型JDK 動(dòng)態(tài)代理因?yàn)?Mapper 是接口代理對(duì)象生成時(shí)機(jī)sqlSession.getMapper()時(shí)方法映射規(guī)則statementId 接口全限定名 . 方法名不支持重載因?yàn)?statementId 不含參數(shù)信息namespace 必須匹配XML 的 namespace 必須等于接口全限定名methodCache 緩存方法映射只解析一次應(yīng)用級(jí)別共享13.3 一句話總結(jié)MyBatis 的 Mapper 接口本身不會(huì)執(zhí)行 SQL能執(zhí)行 SQL 的是 MyBatis 通過(guò) JDK 動(dòng)態(tài)代理生成的代理對(duì)象。代理對(duì)象根據(jù)接口全限定名 方法名找到 SQL再交給 SqlSession 和 Executor 執(zhí)行。理解了這條鏈路你不僅能回答面試題還能在遇到Invalid bound statement、方法重載沖突、代理對(duì)象類型轉(zhuǎn)換異常等問(wèn)題時(shí)快速定位根因。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
午夜精品久久久久久久99热影院| 无码精品蜜桃一区二区三区ww| 久久久噜噜噜久久久| 91性感在线| 日本丝袜美腿人妻九九| 性爱视频无打码在线观看| 亚洲 欧美 综合 91| 嗯嗯啊中文字幕| 久久精品 六十路 熟女 欧美| 国产精品久久久久久久久久久久久久久久| 日本三级黄页| 大香蕉综合在线| 人妻一二三区| 91亚洲色人| 精品一级毛片在线观看| 91殴美| 亚洲人人夜夜澡人人爽| 久久久∴| 好看的久久不射无码影视影院| 日日夜夜干| 一级黄色性爱A级片| A 天堂| 少妇综合| 张柏芝国产一区在线观看| 尤物AV免费网站| 国产精品久久久久久久久久久久久久久久| 亚洲永久永久永久永久一级一级一级精品| 日本淫穴在线| 国产精品毛片| 伊人网一本| 色偷综合| 清纯唯美第一页| AV中文字幕三四五| 99re视频这里只有精品| 久久内射| 中文字幕第9页萱萱影音先锋| 久久久久成人网| 色色九区| 蜜臀99久久| 欧美精品宗合| 欧美强奸乱能| 国产AV超爽| 欧美午夜一区二区三区| 日本在线激情一区二区三区| 美日韩成人| 99热精品在线观看| 后入 亚洲 美女 射| 久久久久无码| 激情文学 亚洲图片| 久久草视频污视频| 欧美色蜜桃97| 中文字幕精品探花视频| 免费自拍三级综合| 国产玖玖| 亚洲和欧美裸体美女双飞视频| 1204av韩国| 国产精品第一页国产大屁股视频免费区| 国内外激情在线| 亚洲日韩天堂| 人人摸人人添人人操| 日本色色色色色视频| 熟女人妻一区二区三区| 成人熟女区| 欧美色图片欧美色图| 日韩一卡二卡三卡| 中国操逼无码| 18禁超污无遮挡无码免费网| 亚洲国产精品久久久久婷婷青年| 婷婷丁香一区二区三区| 九九九999久久久网站| 日韩色香| 国产99精品一区二区三区免费| 国模少妇一区二区三区| 久久黄黄| 熟妇高潮精品一区二区三区下载| 青青久久艹| 99老司机精品视频在线观看| 91色女| 亚州春色| 久久久新亚洲AV| 国产女人高潮嗷嗷嗷叫小说| 色月天AV导航| 精品免费成人久久| 国产又黄又爽又刺激久久久久久 | 深夜啪啪啪视频免费| 麻豆福利视频导航| 亚洲午夜精品久久久中文影院| 黑人娇小av在线播放 | 免费草草草草草视频| 我想要 啊 啊 啊| 久久久久久一日韩字幕无码| 日韩亚洲美女一区久久| 国产精品一二三| 亚洲av无码成电影在线播放| 神马精品视频| 日韩一卡二卡三卡| 强奸乱亚洲| 国产乱弄免费在线视频。 | 富女玩鸭子一级毛片| 日韩激情啪啪| 亚洲第91页| 国产操逼网站亚洲一级黄色| 黄总AV色图| 快灬快灬 一下爽蜜桃在线观看| 中文字幕日韩专区精品系列 | 国产精品久久久久999| 国产精品人妻一区二区| 久jiu久神马影院| 女优大全 - 91n| 高跟丝袜AV专区国产| 国产精品久久久久久夜夜夜| 亚洲无码电影久久久| 丰满人妻av一区二区三区| www.99热在线只有精品| 91超碰在线| 日本三级大片| 百度百度日本操逼| 欧美人妻二区三区| 中文字幕黄片在线| 久久蜜色情在线视频xxx免费观看| 天天做天天爱| 亚洲少妇在线影音| 国产51色综合久久免费| 2019午夜福利视频| 每日更新AV| 941超碰| 亚洲一区二区性爱电影| 噜噜瑟| 色综合久久888| 亚洲熟妇综合久久久久久| 四虎国产精品永久地址入口| 国产精品毛片| 婷婷五月天福利| 欧美翘臀视频网站一区二区三区| 97人妻色| 国产精品盗摄 偷窥盗摄| 超碰综合色| 国产精品女久久久久av爽| 国厂麻豆77q4| 91chinese在线| 97久久超碰日韩精品| 激情综合五月| 欧亚性爱视频免费看| 麻豆区久久久久亚| 久久久无码国精品无码三区三区| 操一操摸一摸| 国桃视频产巨乳精品一区二区在线| 精品v日韩欧美国产| 欧美日韩狠狠爱| 麻豆久久视频在线地址| 亚洲综合另类小说色区亚洲成av人片在www | 超碰色中文| 草草影院日本第一页| 久久久久96| av天堂影视中文在字幕在线中文 | 国产精选三级在线观看| 91人妻在线视频| 大香蕉国产中文自拍| 亚洲最大成人a毛毛片| 密臀成人视频久久久| 日韩草久视频| www.色99| 中文字幕在线观看永久| 国产伦精品| 伊人丝袜美腿高跟在线观看高清| 99热这里只有精品8| 国产精品人妻无码久久久互動交流 | 久久精品国产97欧美精品亚洲 | 久久无码成人| 视频不卡中文字幕| 免费男人的天堂| 亚洲一二三精品久久网| 久久综合激情| 激情综合五月婷婷| 九九性爱网| 中文精品一区二去| 色哟哟 日韩精品| 玖玖爱伊人玖玖爱| 一区二区三区成人| 久久视网78| 色吧综合网| 精品国产乱码| 97超碰久久| 全国男人天堂网| 久久偷拍人| 色爽爽文学| 岛国成人av在线播放网址| www.av在线视频| 国产偷拍网站| 欧美一级美片在线观看免费| 免费岛国一级片| 94色色电影网| 人妻娇喘 激情视频| 成人久久久精品| 亚洲综合113页| 2020中文字幕| 国语人妻精彩刺激| av国产无码| 天堂国产AV| 91看黄片| 极品销魂美女一区二区| 中文字幕蜜乳av| 欧美精品庄| 欧美A√综合网| 亚洲无线码一区国产欧美国| www.久久最新地址| 国产高清精品一区二区三区毛片 | 欧美综合色图网| 午夜精品久久久久久久99| 91丨精品丨国产丨丝袜| 情色五月天网| 亚洲欧美在线综合| 人人操人人精品影片| 亚洲日韩欧美一区二区| 91AV天美在线视频| 色97欧美| 91综合网| 黄片www.| 国产乱弄免费在线视频。| 日韩乱码Av| 啊灬啊灬啊灬好深灬快高潮了动漫-国产字幕国产在线观看-B049AV | 美女淫穴| 日本免费一区二区不卡 | 日韩av影片在线观看| 啪一啪免费视频| 日韩精品中文字幕一| 91艹B视频| 国产亚洲国产超碰| 亚洲熟妇丝袜在线观看| 美女毛片999| 伦理日韩国产久久| 97狠狠| 中文字幕五月婷婷免费| 日韩性爱播放| 手机不卡视频不卡在线一二三区| 亚洲色香| 国语精品av| 一区二区三区国产在线播放| A一区片| 国产强奸超碰AV| 九九这里只有精品| 久久、1234| 99这里都是精品| 亚洲久久久| 宅男影院久久久,99| 手机看av网站在线看| www.91色综合| 国产风韵犹存熟妇三区| 亚洲国产成人综合碰碰三级经典| 欧美精品23| 99热只有这里有精品| 日韩一级二级| 天天干夜夜| 无码久久国产| 激情五月综合网| 安徽熟妇视频| 中文字幕欧美日韩三级| 九九探花视频在线观看| 9久久精品| 一二三四视频中文字幕在线看| 青青草丝袜在线视频| 日韩天堂av电影在线观看| 日本免费二区三区| 国产性爱在线视频一区二区| 亚洲无套久久嗯嗯| 国产9熟妇视频网站| A级在线视频| 秋霞视频一区二区| 超碰 国产熟女精品一区| 亚洲日韩在线a不卡99精品| 亚洲日本韩国在线| 天欧美在线| 国产一级特黄大片处女| 高清不卡一二三区视频......| 视频在线观看青青99国产| 少妇厨房愉情理伦片bd在线观看| 麻豆人妻精品一区二区| 风间由美日韩欧美久久| 精品性爱无码在线播放| 亚洲欧美日韩电影网站一区 | 色噜噜国产在线| 男人的天堂免费| 日韩人妻免费精品| 日影院久久婷婷夜夜网| 蜜乳av一区二区| 超碰天天久久79| 在线观看中文字幕| 综合色图区| 亚洲影视高清三级-草1024榴社区入口-品爱AV| 黑人操一区二区| 97欧美色资源| 国产18精品亚洲精品| 精品久久久不卡一区二区| 日欧操屄| 97就爱干| 91日本在线观看| 丝袜美腿91| 高清无码国产亚洲| 精品女同一区二区三区| 99热只有| 精品人妻一区二区三区四区石在线 | 欧美玖玖爱免费玖玖| 欧美精品一区二区少妇免费A片| 日本免费不卡二区| 亚洲视频1区| 久啪| 午夜精品视频777| 日韩人妻无码不卡网站| 黄页18禁| 熟女字幕| 日夜精品| 久久久熟妇熟女国产| 艹精品| 啊啊啊久久久视频| 国产伦精品一区二区三区视频女| 操婢日韩| 自拍啪啪视频| 久久国产精品91| 天天视频网站黄| 久久久久亚洲熟妇熟女| 国产中文福利| 欧美精品自慰系列寂寞少妇 | 精品人人插人人操| 91在线精品一区二区三区| 欧美亚洲美少妇一区二区| 久久亚洲AV成人精品无码| 九九九只有精品| 天天做天天爱天天爽| 亚洲91色| 日韩av情韩国爱禁区av一区二区| 猛交交| 欧亚性爱在线视频| 青青草一区二区高清无码视频| 欧美1727免费观看视频| 中文字幕日韩人妻视频一区二区三区| 欧美日韩久久精品爱爱| 天堂亚洲精品久久老牛| 精品人妻二区三区| 无码抄逼网| a片在线播放| 亚洲综合色在线| 97超碰碰碰| 国产情侣自拍在线播放| 日韩精品在线放| 啊啊啊 在线| 日韩中文字幕av在线播放| 国产无码一二三区| 日本精品网站在线中文| 久久久久99999| 国产精品久久久久久久久久久久久久久久 | 国产嫩草精品A88AV| 欧美黄色图片| 久久午夜伦| 九九久久一区二区伦理| 精品免费视频国产一区| www欧美91| 欲色啪| 二级久久网| 久久综合乱子伦国产免费| 日韩中文字幕在线视频观看| 色色色色日本| 日韩激情毛片一级久久久| 熟妇人妻丰满久久久久久久无码| 欧美专区在线| 人妻熟女av国产网站| 国产美女口爆吞精视频| 好吊色综合| 超碰97欧美日韩| 日韩丝袜高跟制服在线观看| 99999精品成人| 麻豆 欧美 日韩| 91狠狠综合久久| 把腿张开老子CAO烂你| 18啪啪手机免费性爱| 91丝袜在线观看| 91综合网在线| 人妻少妇精品视频一区二区三区| 亚洲美女高潮喷水视频| 天天欧美| 91情色| 久久久久九九九| 91老熟妇| 久久久一区二区三区三州| 人妻一区二区三区四区视频| 欧亚日韩中文在线| 少妇综合网| 亚洲男人天堂av| 欧美女同在线| 综合五月天| 狠狠入| 亚洲欧美不卡线| 人妻丝袜美腿中文字幕| 人妻精品免费一二三区| 日韩av不卡在线看| 日本理论在线| 欧美日韩美女精品久草一区二区三区| 九九九九免费视频| 人人澡人人干| 亚洲欧美日韩制服另类| 一线黄色免费性爱片| 亚洲五码一区二区三区| 成片免费播放| 日韩久久超碰色| 99色骚| 国产91丝袜 在线播放| 精品人妻一区二区三区日产| 成人无码在线视频网站| 日本欧美亚洲高清在线看| 一起草精品人妻| 中文字幕高清20页视频| 亚洲色悠悠久久88| 高清孕妇孕交 交| 在线观看中文字幕| 日韩乱伦影音先锋| 殴美牲| 天天天天天天天天综合| 国产精品日日摸天天碰| 超碰免费人妻人人| 九九色影院| 美女淫穴| 啊啊啊水好多| 天天做日日做天天欢。| 国产人妻精品久久久一区二区三区 | 精品美女在线视频| 97 国产精品| 一级一性爱免费视频| 国模艳艳啪啪一区| 欧美熟妇乱码在线一区| 综合熟妇一区二区三区| 成人无码在线视频网站| 97色碰| 欧美色日本| 欲香欲色综合天天伊人| 国产精品人妻熟女aⅴ| 一区二区三区精品视频| 热热热热日日漂亮永久永久国产日| 婷婷激情丁香| 嫩草影院在线观看精品| 精品人妻二区三区| 天天干18禁| 操B在线观看| 国产欧美一区二区| 78精品| 青青伊人这里只有精品| 伊人久久国产免费观看视频| 国产91丝袜 在线播放| 日韩欧美午夜视频在线| 日han少妇无码| 澳门色噜噜色噜噜色噜噜色噜噜色噜噜| 在线人成亚洲视频免费观看| 极品色社| 久久六六| 操人妻少妇中文 | 日韩av在线播放不卡| 美女淫穴| 一区二区三区美女超清| 婷婷成人久久久精品| 一本一道久久综合久久| 日韩午夜精品一区二区三区电影| 精品97久久综合| 亚洲日韩人妻中文字幕一区| 色爽爽文学| www国产天美久久久| 91殴美大片| 久久久久久久人妻丝袜| 天美精品av| 久久久91| 国产成人亚洲精品自产在线| 精品人妻一区二区三区视频在线| 婷婷中文字幕| 欧美成人性活片| 久久婷婷五月天| 综合熟妇一区二区三区| 99热国产| 美女啊啊啊啊啊啊| 97爱爱爱综合| 亚洲最新Av| av在线人气| 中文字幕高清精品一区| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师 | 男女激情黄色网址| q2午夜理论片夜色av| www.人人cao| 2020天天色综合| 丁香五月色情| 日本阿v天堂在线观看| 9热9热综合网| 日韩一区二区三区四区五区| 欧美日韩亚洲少妇寂寞影院正在播放 | 五月天伊人| 日韩亚洲中文有码视频| q2午夜理论片夜色av| 黄片直播三级黄片两女一男| 超碰色97| 免费网色网站| 色综合网1| 久久久人妻| 久久av色| 亚洲AV永久无码一区仙野| 色综合天天爱去电影网| 大香蕉综合久久| 欧美日韩岛国大片在线观看| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区 | 蜜屁Av| 激情AV| 欧美不卡在线一区二区| 四虎免费视频| 久久久com| 欧美性爱www免费版| 久久久久久加勒比| 亚洲限制级| 99色婷婷| 操高情无码| 999综合网| 日本九九久久99| 天天爱天天韩国日本牛牛牛牛| 欧美一区二区男人天堂| 激情内射| 性爱欧美五月| 亚洲欧洲视频小说在线观看| 成年人一级黄色毛片大全在线观看| 亚洲资源站| 东京热大香焦| 大香蕉伊人在线成人AV在线观看| 午夜色婷婷| 亚洲性爱免费电影| 久久久蜜桃臀无码视频| 91亚.色| 亚洲宗合电影| 欧美美女自慰一区二区三区| 久草免费在线一区二区| 亚洲欧洲自拍图片专区满春格| 色色97爱| 青青草在线视频美女| 久久大线蕉一区| 超碰97起碰| 免费一级视频特黄色大片| 家庭乱伦国产| 三男一女不戴套的A片| 精品国产乱码久久久久久久久久毛片| 欧美大干日韩| 久操在97| 都市激情人妻一区二区青青操视频| 国产精品一区二区三区在线密挑| 四虎影院成年人片| 黄aaaaaaaaaaaaaaaaaa色网站| 一区不卡在线观看av| 国产午夜在线观看| 天天草天天日| 欧美片第一页| a男人的天堂久久一级A毛片| 人妻熟女字幕一区二区| 免费人成?大片在线播放| 污污汅18禁网站在线永久免费观看| 超碰在线人人射| 丁香九月婷婷| 2024黄色视频| 一道α片欧美| 午夜视频好爽啊| 伊人久久综合精品欧美| 亚洲91在线播放影院| 国产精品盗摄 偷窥盗摄| 一级性爱视频免费观看| 日熟女| 神马久久久久久伦理片| 午夜福利精品| 一块操欧美性爱| 久久五月综合| 国产超碰国产97| 嗯阿好爽好紧| 精品9区| 大屁股熟女一区二区三区| 欧美一二级| 欧美色97| 人妻天天爽天天爽三区| 日韩精品国产一区二区| 99久久精品无码一区二区| 国产九九九九九九九九| 发朗少妇买婬全视频中文| 神马视频久久久久久| 熟女一区二区| 日韩97精| 欧美综合网在线| 手机午夜电影神马久久| 精品偷拍13p欧美dodk视频| aⅴ日韩成人电影av在线免费看av大全| 操逼网免费无码视频| 天天插天天射| 久操在97| 91亚洲综合在线| 人人看人人插| 99热最新| 亚洲视频二区| 熟妇视频一区二区三区在线| 国产精品熟女九色九色蜜臀| 秋霞视频一区二区| 极品内射| 大粗鳼巴久久久久| 国产精品蜜臀久久久久无码AV| 亚欧高清在线| 色综合加勒比四四季| 91欧美巨乳| 亚洲无码视频免费在线观看网址! J?P?NESEHD熟女熟妇伦 | 久久精品国产亚洲AV无码电影| 99热| 日韩精品影视| 亚洲国产成人7777| 色综合99| 国产人人干| A片大香蕉在线| 亚洲操操| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 99色网| 美国一区二区免费视频| 9热9热综合网| 亚洲人妻五月丁香婷婷| 欧美另类精品xxxx| 欧美亚综合色图| 亚洲第一页色网| 这里只有精品视频在线观看麻豆| 国产最新AV| 四虎精品永久在线观看| 亚洲最大成人a毛毛片| 九月丁香婷婷| 一本久道久久综合狠狠爱一密臀精| 神马久久久久久伦理片| 国产精品经典一卡久久久| 中文字幕精品一区欧美| 99热欧美| 97色爱| 九九热精品免费视频| av操操不卡| 无人区高清电影免费观看一区二区三 www.qmcai2.com | 上特色A在线| 久久久夜夜嗨免费视频| 黄色一区三区| 嫩草一区二区在线观看| 成人在线视频一区| 亚洲乱色熟女一区| 91伊人大香蕉| 日婷婷| av操操不卡| 国产欧美在线观看免费观看| 精品久久青青草| 97色综合中文网| 亚洲无码色| 欧美亚洲首页| 精品区9| 久久久久夜夜夜夜| 国产熟女少妇一区| 国产小视频91| 色九色久| 天天天天干| 日韩欧美加勒比| 国产欧美美女免费观看视频| 国产又黄又爽| AV高清一区| 三级特黄60分钟播放| 97欧美色资源| 国产强奸超碰AV| 丝袜视频网国产90| 天天综合精品| 秋霞 色色| 嗯嗯,好大,好爽,好骚| 欧美性爱91| 亚洲在线观看| 色女女女导航| 日韩人妻一二三区视频 | 亚洲偷拍自拍在线视频| 日日躁夜夜躁狠狠躁超爽| 青青草日韩无码| 无码137片内射在线影院| 欧美另类自拍| 亚洲欧美精品福利在线| 亚洲色阁| 欧美 牲| 爱射综合| 伊人久久综合影院精品久久久 | 影音先锋中文字幕日本好一区二区| 日日AAvv| 天操天操夜操夜月操月年年操| 欧美激情性爱视频网站| 日日躁狠狠躁天天躁精品| 国产女人高潮视频| 男人午夜天堂| 精品久久久中文字幕不| 乱伦1色页| 人妻天堂网| 亚洲吊色| 夜夜操狠狠操| 伊人久久在线视频观看| 99热婷婷一区二区三| 精品久久久久黄少妇| 蜜乳性色无码专日粉嫩骚逼AV| 欧美日韩小说| AV丝袜少妇| 9+1视频网址| 欧美精品日韩久久久九| 欧美日韩精品久久久久久久久东北老熟妇| 美女久久久久久久| 五月丁香婷婷色| 人人操人人插人人摸人人干| 丰满人妻一区二区三区| 欧美国产有色电影| 偷拍欧美综合| 成人av免费观看| 日本欧美韩国国产在线| 好爽视频在线观看视频| 精品久操| 亚洲视频二区 | 97色网| 97色操| 啊啊啊啊啊好舒服视频| 久久精品天美| 97爱免费插| 婷婷激情综合网| 最新中文字幕在线亚洲| 无码操逼视频一下| 日本久久女同性恋视频| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 久久久月天| 日韩三级性| 青青草视频导航官网| 又黄又爽在线观看视频| 成人av免费观看| 亚洲天堂7777| 波多野结衣先锋影音| 久久久99免费| 日韩AV电影网站| 人人色人人操在线| 黑人操一区二区| 色色色色日本| 国产精品美女在线一区| 天天插夜夜操| 一类av片在线看| 亚洲欧美日韩二区视频| 亚洲一曲日韩精品| 天天色天天干天天射| 黑人白女精品一区| 99老司机精品视频在线观看| AV一起草在线| 久综合国内精品自在自线| 欧美性爱第一页久久| 国产精品成人AV片免费看网站| 欧美亚洲| AA级电影三区| 蜜乳AV一区| 精品性爱一二三区| 六十路日本| 99热免费| 中文久久一区| 精品人妻一区二区三区视频| 亚洲综合性网址| 国产乱子伦一区二区三区免看| 天天综合网~91综合网| 中文字幕免费看| 啊啊啊慢点| 久久精品—区二区三区内射| 秋霞怕怕片| 成人麻豆av电影网站| 中文字幕狠狠玩| 三级三级三级日本99| 91蜜臀在线久久久久| 天天摸天天碰天天添青青| 欧美亚洲美少妇一区二区| 欧美美女后入| 玖玖久久久| 久久av无码| 国产色呦呦| 嗯啊不要啊在线| 日韩不卡码| 青女偷拍网| 家庭乱伦国产精品| 久久久麻豆精品| 欧美|91色综合| www.AV有限公司一区| 四虎影视 亚洲无码| 七月丁香婷婷| 一区二区视频在线播放| 婷婷久久综合| 中文字幕78| 91欧美经典| 色综合天天| 99精品无码| 日本久久综合| 五十路三区在线| 91久久精品中文字幕| 999在线电影香蕉| 色天堂在线观看| 91黑人狂躁丰满熟妇| 日韩精品在线观看观看| 中文字幕黑人大片| 欧美青青草视频| 97香蕉网| 99热精品在线播放| 亚洲成人妻日韩在线| 国产精品乱码久久久久| 久久激情亚洲精品无码?V| 国产精品一区二区在钱播放| 一摸二插三插| 九九综合久久中文字幕| 老色69| 亚洲Av诱惑| 久久美女国产| 麻豆人妻少妇在线免费观看| 亚洲天堂资源在线| www黄片免费看com| 97视频在| 在线视频 亚洲精品| 欧美日韩成人| 国内一区二区三区| 手机在线A片| 色五月69夫妻| 九九无码| 熟女日韩| 天天澡天天狠天天天做| 日本综合色图| 亚洲资源吧| 中国探花熟女| 天天天堂影视日韩亚洲91| 中国一级特黄大片护士| 欧美午夜色妇色鬼| 国产操逼网站亚洲一级黄色| 素人播放一区| 亚洲国产精品无石码久久 | 97chaopenrihan| 福利伊人玖玖国产| 亚洲国内精品成人不卡| 18禁中文字幕| 国产一区二区久久| 啪啪AV导航| 国产一区二区久久| 美女尤物人人操| 色哟哟1区2区| 亚洲图片欧洲图片aⅴ| 亚洲黄a三级三级三级看三级| 精品日韩中文在线| 91老熟女老女人国产老太| 欧美午夜视频免费观看| 一级黄碟在线看| 午夜福利在线合集| 欧美骚少妇| 中文字幕一区日韩精| 97久久超碰亚洲| 色情综合网| …亚洲黄色厕厕女女在线播…| 射 色综合| 色吧5亚洲| 樱花草社区www中国| 大香蕉www.超碰| 性九九九九九九| 丁香婷婷九月| 蜜臀99久久精品久久久久| 欧美黑人猛交春色影视大全| 久久性爱视频免费看| 精品97精品97| 日韩欧美国产高清视频| 亚洲中文字幕av| 黄色大片一区二区密桃丝袜| 国产精品不卡一区二区三区av| 欧美97日韩精品| 熟妇操花| 蜜桃狠狠色伊人亚洲综合网站| 国产自产91区13区| 美國A片| 欧美在线天堂| 四虎视频在线观看| 无码抄逼网| 97超碰超碰| 小草av不卡亚洲二区| AV综合中文字幕干| 9国产超碰| 91国产伊人大香蕉| 91人妻丝袜无码| 亚洲av影音先锋| 成人性生活高清视频在线播放| 久久一二三级一一一| 黄色一区二区秘书性感| 大香蕉视频啪啪啪啪| 91电影色诱| 99久久久久| 岛国在线国产| 乱人乱色一区二区三区免费| 一区中文字幕二区日韩| 大香蕉黄色一区| 亚洲av无码国产精品字幕| 熟女91网| 加勒比AV网| 婷婷五月天福利| 少妇人妻好深太紧了vr91| 99热婷婷一区二区三| 91久久久视| 红杏大香蕉| 91小视频| 操B视频日韩无码| 欧美性夜| 久久久精品中文字幕麻豆| 91天天日| 五月丁香婷婷综合| 日韩色欲久久一二三四区| 亚洲欧美999| 熟人人妻少妇精品久久| 久久精品中文| 欧美在线色图| 嗯嗯啊啊视频在线看 | 天堂成人网| 91网站在线播放| 青青草日本中文字幕| 欧美性猛交美女自慰91| 久久久久婷婷| 五月婷婷丁香中文字幕| 国产 日韩 欧美高清| 亚洲精品国语在线播放| 色图综合| 人人妻人人澡人人爽久久av| 插B在线观看| 天天插天天操天天摸天天射天天看| 国产久久久9999| 天天操夜夜操| 99无码| 亚洲久热| 99热这里是精品| 性做久久久久久免费观看软件| 一区操逼日比视频| 精品毛片av一区二区| 欧美人人操人人插| Sekablack无码一区| 日韩欧无码一区二区三区免费不卡| 97超碰9| 男人天堂新| 91亚洲电影| 97超碰色色| 色欧洲| 91老熟女视频| 3PAV乱伦视频| 国产精品黑人一区二区三区| 亚洲av噜噜噜噜噜噜| 免费精品无码一级毛片牛牛影视 | 午夜欧美女人操逼| 亚洲精品中文字幕一区在线视频| 日韩人妻 中文字幕| 中文字幕奈奈美被公侵犯| 国产一进一出视频网站| 久久国产乱子伦精品免费女人| 国产野战露脸在线播放| 亚洲AV无线| 国产成人久久久精品免费AV| 久久这里只精品99re66图| 五月婷婷基地| 久久久影院| 亚洲欧美色综合| 久久久久久久久久久999| 综合91网| 婷婷久久久精品| 亚洲天堂2020| 中文AV制服乱伦| 国产人伦a片信息免费片| 黄色片大香蕉| 亚洲色图超碰在线| 97久久精品亚洲中六字幕| 中文字幕人乱码中文字的预防方法 | 啊啊啊啊啊啊啊好爽不要| 久噜噜| 精品无av| 国产在线综合网| 不卡一区二区日本视频| 美女自卫慰黄网站免费| 97精品国产97久久久久久免费| 亚洲棕合电彰| 久久久天美| 97爱爱| 国模艳艳啪啪一区| 丁香五月天社区| 欧美人妻色| 大逼色网站| 亚洲一区操| 综合久久中文字幕综合日韩精品| 人人色97| 少妇色综合| 亚洲图片欧美| 夜嗨影院| 熟妇人妻一区二区三区| 午夜精品人妻二区三区| 精品国产乱码久久久久久蜜臀| 成人小说视频在线精品欧美| 性做久久久久久免费观看软件| 欧美激情亚洲色图| 天天操狠狠日夜夜干超大胆开放com大香蕉视频在线观看 | 丝袜狂射91| 九九碰九九爱97超碰| 国产美女mm131爽爽爽爽| 亚洲一区二区三区久久 亚洲一区二区| 最新av在线| 亚洲另类春色| 亚洲成?V人片在线观看福利| 天综合网欧美| 91久久青青草原精品| 天天干天天狼在线视频| 欧美五区| 中文 人妻 制服| 91精品人妻电影| 色欲人妻一区二区在线| 人人妻人人澡人人爽久久av| av在线一区二区三区| 欧美三级免费伊人| 男人天堂新在线| 91free福利| 九九九九97| 久久亚洲欧美中文字幕国语| 天天综合亚在线| 超碰人人干天天射| aaaa黄片| 激情啪啪视频| 久久久久亚洲AV无码专区少妇| 亭亭丁香激情| 国产传媒av天美传媒在线| 日韩精品一区二区三区色欲| 99热这里只有是精品10| 性爱网站一区二区| 香一区二区三区| 日韩在线国产字幕| 一二三区在线| 天天躁日日躁狠狠狠躁| 日韩不卡a级视频专区| 天堂资源站| 国产精品呦一区二区三区| 亚洲色图欧美色图制服丝袜| 96精品久久久久久久久久| 色九九九九久| 麻豆成人AV| 开心激情站| 97欧美综合| 欧美日韩性感| 色图综合网| 在线天堂999| 亚洲国产成人精品久久久国产成人一区二区 | 日本天天操| 91性网| 久热99| 999久久久九九九九| 青青草视频久久| 嗯嗯啊啊操我| 97精品国产97久久久久久户外免费| 啊啊啊爽爽| 久久久精品国产亚洲伊人| 亚洲黄色影视| 亚洲一区中文字幕| 97人人草| 啊啊啊啊啊好多水| 天美传媒国产原创中文字幕亚洲欧美另类 | 中文字幕神马久久| 国产高清在线观看欧美| 亚州图片第一页| 亚洲经典啪啪| 老女人综合| 爱干爱射网啊啊啊| 波多野42部无码喷潮在线观看 | 激情久久av一区av二区av| 天天日天天干天天摸天天操| 五月婷婷综合激情| 91在线免费精品视频| 在线视频五十市| 国产精品无码在线| 97国产精品一区| 黄色二级片网站| 国产啊v在线免费播放| 好爽要喷了| 精品国产乱码久久久久久影片| 亚洲熟伦熟妇AV无码春色| 亚洲情色一区二区三区| 亚洲aV性爱| 99热| 国产精品久久久久久久久久久久久久久久 | 国产精品一区在线播放| 小草精彩毛片| 草草影院最新网址| 亚洲成人ab| 蜜臀99999| 久久香蕉影院| 欧美黄色手机在线观看| 亚洲大色鬼| 91原创在线观看| 美中日韩无码| 精品九九九九| 麻豆区久久久久亚| 国产精品制服丝袜中文字幕日韩一区二区三区 | 国产在线视频二区| 9 1果冻精品视频| 麻豆精品A片免费观看| 曰韩av中文字幕专区| 亚洲日韩在线a不卡99精品| 2019男人的天堂| 蜜桃视频一区二区三区在线观看| 亚洲一区二区性爱电影| 2023天天操夜夜操| 亚洲精品熟妇1区2区3区。| 九热大香蕉| 青青草中文-久久青草精品一区二区三| 国产精品露脸在线观看| 四方色播| 久操| 91精品成人| 人妻天堂综合网| 强奸乱伦αv片| 成人97人人超碰人人| 天天狂操夜夜狂日| 日韩欧美天堂| 蜜臀AV成人精品蜜臀| 青青草精品| 欧美性综合| 极品白嫩福利在线| 国产福利精品最新在线| 强奸乱伦AV一天堂网| 少妇蹲下露出大唇5| 国产乱子伦一区二区三区免看| 成 人 影视 一区 二区 三区 四区| 破苞ⅩXXX性无码动漫无码| 看免费的黄片| 女色综合| 久久久久久久9999| 大香交| 国产久久男人天堂| 91美女在线视频| 老师充足的奶水小说| 欧美美女自慰一区二区三区| 狠狠色婷婷777| 超碰成人国产| 99久久久er直播网址| 8x福利精品第一福利视频导航| 激情小说亚洲| 久久久久久性爱免费视频| 黄色成年| 国产精品伦理| 伊人97| 亚洲色性| 亚州欧美在线| 97人人夜| 强乱老妇中文字幕| 四虎AV在线播放| 91精品久久久久| 九九九九九九九九九国产精品 | 亚洲色图欧美一区二区不卡| 欧美双插| 97综合网| {男男暴菊gay无套网站| 91被操| 日日夜夜精品| 91艹B视频| 国产女生在线| 99热欧美| 美女尤物福利视频| 日韩内射视频| 日日黄色三级网站| 好舒服视频| 97草草| 国产91美女视频| 日本一区二区不卡| 欧美亚洲国产91在线| 正在播放国产精品一区| 99色热国产视频精品|