日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

mybatis看这一篇就够了,简单全面一发入魂

發(fā)布時間:2023/12/3 综合教程 42 生活家
生活随笔 收集整理的這篇文章主要介紹了 mybatis看这一篇就够了,简单全面一发入魂 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • Mybatis
    • 概述
    • 快速入門
      • 原生開發(fā)示例
      • 基于Mapper代理的示例
      • 基于注解的示例
    • 應(yīng)用場景
      • 主鍵返回
      • 批量查詢
      • 動態(tài)SQL
      • 緩存
      • 關(guān)聯(lián)查詢
      • 延遲加載
      • 逆向工程
      • PageHelper分頁插件
      • Mybatis Plus

Mybatis

概述

  1. mybatis是什么?有什么特點?

    它是一款半自動的ORM持久層框架,具有較高的SQL靈活性,支持高級映射(一對一,一對多),動態(tài)SQL,延遲加載和緩存等特性,但它的數(shù)據(jù)庫無關(guān)性較低

    • 什么是ORM?

      Object Relation Mapping,對象關(guān)系映射。對象指的是Java對象,關(guān)系指的是數(shù)據(jù)庫中的關(guān)系模型,對象關(guān)系映射,指的就是在Java對象和數(shù)據(jù)庫的關(guān)系模型之間建立一種對應(yīng)關(guān)系,比如用一個Java的Student類,去對應(yīng)數(shù)據(jù)庫中的一張student表,類中的屬性和表中的列一一對應(yīng)。Student類就對應(yīng)student表,一個Student對象就對應(yīng)student表中的一行數(shù)據(jù)

    • 為什么mybatis是半自動的ORM框架?

      用mybatis進(jìn)行開發(fā),需要手動編寫SQL語句。而全自動的ORM框架,如hibernate,則不需要編寫SQL語句。用hibernate開發(fā),只需要定義好ORM映射關(guān)系,就可以直接進(jìn)行CRUD操作了。由于mybatis需要手寫SQL語句,所以它有較高的靈活性,可以根據(jù)需要,自由地對SQL進(jìn)行定制,也因為要手寫SQL,當(dāng)要切換數(shù)據(jù)庫時,SQL語句可能就要重寫,因為不同的數(shù)據(jù)庫有不同的方言(Dialect),所以mybatis的數(shù)據(jù)庫無關(guān)性低。雖然mybatis需要手寫SQL,但相比JDBC,它提供了輸入映射和輸出映射,可以很方便地進(jìn)行SQL參數(shù)設(shè)置,以及結(jié)果集封裝。并且還提供了關(guān)聯(lián)查詢動態(tài)SQL等功能,極大地提升了開發(fā)的效率。并且它的學(xué)習(xí)成本也比hibernate低很多

快速入門

只需要通過如下幾個步驟,即可用mybatis快速進(jìn)行持久層的開發(fā)

  1. 編寫全局配置文件
  2. 編寫mapper映射文件
  3. 加載全局配置文件,生成SqlSessionFactory
  4. 創(chuàng)建SqlSession,調(diào)用mapper映射文件中的SQL語句來執(zhí)行CRUD操作

原生開發(fā)示例

  1. 在本地虛擬機mysql上創(chuàng)建一個庫yogurt,并在里面創(chuàng)建一張student表

  2. 打開IDEA,創(chuàng)建一個maven項目

  3. 導(dǎo)入依賴的jar包

    	<dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.10</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope></dependency></dependencies>
    
  4. 創(chuàng)建一個po類

    package com.yogurt.po;import lombok.*;@Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    public class Student {private Integer id;private String name;private Integer score;private Integer age;private Integer gender;}
  5. 編寫mapper映射文件(編寫SQL)

    <!-- StudentMapper.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="test"><select id="findAll" resultType="com.yogurt.po.Student">SELECT * FROM student;</select><insert id="insert" parameterType="com.yogurt.po.Student">INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});</insert><delete id="delete" parameterType="int">DELETE FROM student WHERE id = #{id};</delete>
    </mapper>
    
  6. 編寫數(shù)據(jù)源properties文件

    db.url=jdbc:mysql://192.168.183.129:3306/yogurt?characterEncoding=utf8
    db.user=root
    db.password=root
    db.driver=com.mysql.jdbc.Driver
    
  7. 編寫全局配置文件(主要是配置數(shù)據(jù)源信息)

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration><!-- 配置文件信息 --><properties resource="properties/db.properties"></properties><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!-- 從配置文件中加載屬性 --><property name="driver" value="${db.driver}"/><property name="url" value="${db.url}"/><property name="username" value="${db.user}"/><property name="password" value="${db.password}"/></dataSource></environment></environments><mappers><!-- 加載前面編寫的SQL語句的文件 --><mapper resource="StudentMapper.xml"/></mappers></configuration>
    
  8. 編寫dao類

    package com.yogurt.dao;import com.yogurt.po.Student;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;public class StudentDao {private SqlSessionFactory sqlSessionFactory;public StudentDao(String configPath) throws IOException {InputStream inputStream = Resources.getResourceAsStream(configPath);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}public List<Student> findAll() {SqlSession sqlSession = sqlSessionFactory.openSession();List<Student> studentList = sqlSession.selectList("findAll");sqlSession.close();return studentList;}public int addStudent(Student student) {SqlSession sqlSession = sqlSessionFactory.openSession();int rowsAffected = sqlSession.insert("insert", student);sqlSession.commit();sqlSession.close();return rowsAffected;}public int deleteStudent(int id) {SqlSession sqlSession = sqlSessionFactory.openSession();int rowsAffected = sqlSession.delete("delete",id);sqlSession.commit();sqlSession.close();return rowsAffected;}
    }
  9. 測試

    public class SimpleTest {private StudentDao studentDao;@Beforepublic void init() throws IOException {studentDao = new StudentDao("mybatis-config.xml");}@Testpublic void insertTest() {Student student = new Student();student.setName("yogurt");student.setAge(24);student.setGender(1);student.setScore(100);studentDao.addStudent(student);}@Testpublic void findAllTest() {List<Student> all = studentDao.findAll();all.forEach(System.out::println);}
    }
    

總結(jié)

  1. 編寫mapper.xml,書寫SQL,并定義好SQL的輸入?yún)?shù),和輸出參數(shù)
  2. 編寫全局配置文件,配置數(shù)據(jù)源,以及要加載的mapper.xml文件
  3. 通過全局配置文件,創(chuàng)建SqlSessionFactory
  4. 每次進(jìn)行CRUD時,通過SqlSessionFactory創(chuàng)建一個SqlSession
  5. 調(diào)用SqlSession上的selectOneselectListinsertdeleteupdate等方法,傳入mapper.xml中SQL標(biāo)簽的id,以及輸入?yún)?shù)

注意要點

  1. 全局配置文件中,各個標(biāo)簽要按照如下順序進(jìn)行配置,因為mybatis加載配置文件的源碼中是按照這個順序進(jìn)行解析的

    <configuration><!-- 配置順序如下properties  settingstypeAliasestypeHandlersobjectFactorypluginsenvironmentsenvironmenttransactionManagerdataSourcemappers-->
    </configuration>
    

    各個子標(biāo)簽說明如下

    • <properties>

      一般將數(shù)據(jù)源的信息單獨放在一個properties文件中,然后用這個標(biāo)簽引入,在下面environment標(biāo)簽中,就可以用${}占位符快速獲取數(shù)據(jù)源的信息

    • <settings>

      用來開啟或關(guān)閉mybatis的一些特性,比如可以用<setting name="lazyLoadingEnabled" value="true"/>來開啟延遲加載,可以用<settings name="cacheEnabled" value="true"/>來開啟二級緩存

    • <typeAliases>

      在mapper.xml中需要使用parameterTyperesultType屬性來配置SQL語句的輸入?yún)?shù)類型和輸出參數(shù)類型,類必須要寫上全限定名,比如一個SQL的返回值映射為Student類,則resultType屬性要寫com.yogurt.po.Student,這太長了,所以可以用別名來簡化書寫,比如

      <typeAliases><typeAlias type="com.yogurt.po.Student" alias="student"/>
      </typeAliases>
      

      之后就可以在resultType上直接寫student,mybatis會根據(jù)別名配置自動找到對應(yīng)的類。

      當(dāng)然,如果想要一次性給某個包下的所有類設(shè)置別名,可以用如下的方式

      <typeAliases><package name="com.yogurt.po"/>
      </typeAliases>
      

      如此,指定包下的所有類,都會以簡單類名的小寫形式,作為它的別名

      另外,對于基本的Java類型 -> 8大基本類型以及包裝類,以及String類型,mybatis提供了默認(rèn)的別名,別名為其簡單類名的小寫,比如原本需要寫java.lang.String,其實可以簡寫為string

    • <typeHandlers>

      用于處理Java類型和Jdbc類型之間的轉(zhuǎn)換,mybatis有許多內(nèi)置的TypeHandler,比如StringTypeHandler,會處理Java類型String和Jdbc類型CHAR和VARCHAR。這個標(biāo)簽用的不多

    • <objectFactory>

      mybatis會根據(jù)resultTyperesultMap的屬性來將查詢得到的結(jié)果封裝成對應(yīng)的Java類,它有一個默認(rèn)的DefaultObjectFactory,用于創(chuàng)建對象實例,這個標(biāo)簽用的也不多

    • <plugins>

      可以用來配置mybatis的插件,比如在開發(fā)中經(jīng)常需要對查詢結(jié)果進(jìn)行分頁,就需要用到pageHelper分頁插件,這些插件就是通過這個標(biāo)簽進(jìn)行配置的。在mybatis底層,運用了責(zé)任鏈模式+動態(tài)代理去實現(xiàn)插件的功能

      <!-- PageHelper 分頁插件 -->
      <plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="helperDialect" value="mysql"/></plugin>
      </plugins>
      
    • <environments>

      用來配置數(shù)據(jù)源

    • <mappers>

      用來配置mapper.xml映射文件,這些xml文件里都是SQL語句

  2. mapper.xml的SQL語句中的占位符${}#{}

    一般會采用#{}#{}在mybatis中,最后會被解析為?,其實就是Jdbc的PreparedStatement中的?占位符,它有預(yù)編譯的過程,會對輸入?yún)?shù)進(jìn)行類型解析(如果入?yún)⑹荢tring類型,設(shè)置參數(shù)時會自動加上引號),可以防止SQL注入,如果parameterType屬性指定的入?yún)㈩愋褪呛唵晤愋偷脑?簡單類型指的是8種java原始類型再加一個String),#{}中的變量名可以任意,如果入?yún)㈩愋褪莗ojo,比如是Student類

    public class Student{private String name;private Integer age;//setter/getter
    }
    

    那么#{name}表示取入?yún)ο骃tudent中的name屬性,#{age}表示取age屬性,這個過程是通過反射來做的,這不同于${}${}取對象的屬性使用的是OGNL(Object Graph Navigation Language)表達(dá)式

    ${},一般會用在模糊查詢的情景,比如SELECT * FROM student WHERE name like '%${name}%';

    它的處理階段在#{}之前,它不會做參數(shù)類型解析,而僅僅是做了字符串的拼接,若入?yún)⒌腟tudent對象的name屬性為zhangsan,則上面那條SQL最終被解析為SELECT * FROM student WHERE name like '%zhangsan%';

    而如果此時用的是SELECT * FROM student WHERE name like '%#{name}%'; 這條SQL最終就會變成

    SELECT * FROM student WHERE name like '%'zhangsan'%'; 所以模糊查詢只能用${},雖然普通的入?yún)⒁部梢杂?code>${},但由于${}不會做類型解析,就存在SQL注入的風(fēng)險,比如

    SELECT * FROM user WHERE name = '${name}' AND password = '${password}'

    我可以讓一個user對象的password屬性為'OR '1' = '1,最終的SQL就變成了

    SELECT * FROM user WHERE name = 'yogurt' AND password = ''OR '1' = '1',因為OR '1' = '1'恒成立,這樣攻擊者在不需要知道用戶名和密碼的情況下,也能夠完成登錄驗證

    另外,對于pojo的入?yún)?#xff0c;${}中獲取對象屬性的語法和#{}幾乎一樣,但${}在mybatis底層是通過OGNL表達(dá)式語言進(jìn)行處理的,這跟#{}的反射處理有所不同

    對于簡單類型(8種java原始類型再加一個String)的入?yún)?#xff0c;${}中參數(shù)的名字必須是value,例子如下

    <select id="fuzzyCount" parameterType="string" resultType="int">SELECT count(1) FROM `user` WHERE name like '%${value}%'
    </select>
    

    為什么簡單類型的變量名必須為value呢?因為mybatis源碼中寫死的value,哈哈

上面其實是比較原始的開發(fā)方式,我們需要編寫dao類,針對mapper.xml中的每個SQL標(biāo)簽,做一次封裝,SQL標(biāo)簽的id要以字符串的形式傳遞給SqlSession的相關(guān)方法,容易出錯,非常不方便;為了簡化開發(fā),mybatis提供了mapper接口代理的開發(fā)方式,不需要再編寫dao類,只需要編寫一個mapper接口,一個mapper的接口和一個mapper.xml相對應(yīng),只需要調(diào)用SqlSession對象上的getMapper(),傳入mapper接口的class信息,即可獲得一個mapper代理對象,直接調(diào)用mapper接口中的方法,即相當(dāng)于調(diào)用mapper.xml中的各個SQL標(biāo)簽,此時就不需要指定SQL標(biāo)簽的id字符串了,mapper接口中的一個方法,就對應(yīng)了mapper.xml中的一個SQL標(biāo)簽

基于Mapper代理的示例

全局配置文件和mapper.xml文件是最基本的配置,仍然需要。不過,這次我們不編寫dao類,我們直接創(chuàng)建一個mapper接口

package com.yogurt.mapper;import com.yogurt.po.Student;import java.util.List;public interface StudentMapper {List<Student> findAll();int insert(Student student);int delete(Integer id);List<Student> findByName(String value);
}

而我們的mapper.xml文件如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.yogurt.mapper.StudentMapper"><select id="findAll" resultType="com.yogurt.po.Student">SELECT * FROM student;</select><insert id="insert" parameterType="com.yogurt.po.Student">INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});</insert><delete id="delete" parameterType="int">DELETE FROM student WHERE id = #{id};</delete><select id="findByName" parameterType="string" resultType="student">SELECT * FROM student WHERE name like '%${value}%';</select>
</mapper>

mapper接口和mapper.xml之間需要遵循一定規(guī)則,才能成功的讓mybatis將mapper接口和mapper.xml綁定起來

  1. mapper接口的全限定名,要和mapper.xml的namespace屬性一致
  2. mapper接口中的方法名要和mapper.xml中的SQL標(biāo)簽的id一致
  3. mapper接口中的方法入?yún)㈩愋?#xff0c;要和mapper.xml中SQL語句的入?yún)㈩愋鸵恢?/li>
  4. mapper接口中的方法出參類型,要和mapper.xml中SQL語句的返回值類型一致

測試代碼如下

public class MapperProxyTest {private SqlSessionFactory sqlSessionFactory;@Beforepublic void init() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);}@Testpublic void test() {SqlSession sqlSession = sqlSessionFactory.openSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);List<Student> studentList = mapper.findAll();studentList.forEach(System.out::println);}
}

結(jié)果如下

這個mapper接口,mybatis會自動找到對應(yīng)的mapper.xml,然后對mapper接口使用動態(tài)代理的方式生成一個代理類

基于注解的示例

如果實在看xml配置文件不順眼,則可以考慮使用注解的開發(fā)方式,不過注解的開發(fā)方式,會將SQL語句寫到代碼文件中,后續(xù)的維護(hù)性和擴展性不是很好(如果想修改SQL語句,就得改代碼,得重新打包部署,而如果用xml方式,則只需要修改xml,用新的xml取替換舊的xml即可)

使用注解的開發(fā)方式,也還是得有一個全局配置的xml文件,不過mapper.xml就可以省掉了,具體操作只用2步,如下

  1. 創(chuàng)建一個Mapper接口

    package com.yogurt.mapper;
    import com.yogurt.po.Student;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Select;
    import java.util.List;public interface PureStudentMapper {@Select("SELECT * FROM student")List<Student> findAll();@Insert("INSERT INTO student (name,age,score,gender) VALUES (#{name},#{age},#{score},#{gender})")int insert(Student student);
    }
    
  2. 在全局配置文件中修改<mappers>標(biāo)簽,直接指定加載這個類

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration><properties resource="properties/db.properties"></properties><typeAliases><package name="com.yogurt.po"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${db.driver}"/><property name="url" value="${db.url}"/><property name="username" value="${db.user}"/><property name="password" value="${db.password}"/></dataSource></environment></environments><mappers><mapper class="com.yogurt.mapper.PureStudentMapper"/></mappers></configuration>
    

測試代碼如下

public class PureMapperTest {private SqlSessionFactory sqlSessionFactory;@Beforepublic void init() throws IOException {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}@Testpublic void test() {SqlSession sqlSession = sqlSessionFactory.openSession();PureStudentMapper mapper = sqlSession.getMapper(PureStudentMapper.class);mapper.insert(new Student(10,"Tomcat",120,60,0));sqlSession.commit();List<Student> studentList = mapper.findAll();studentList.forEach(System.out::println);}
}

結(jié)果如下


注:當(dāng)使用注解開發(fā)時,若需要傳入多個參數(shù),可以結(jié)合@Param注解,示例如下

package org.mybatis.demo.mapper;import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.mybatis.demo.po.Student;import java.util.List;public interface PureStudentMapper {@Select("SELECT * FROM student WHERE name like '%${name}%' AND major like '%${major}%'")List<Student> find(@Param("name") String name, @Param("major") String major);
}

@Param標(biāo)簽會被mybatis處理并封裝成一個Map對象,比如上面的示例中,實際傳入的參數(shù)是一個Map對象,@Param標(biāo)簽幫忙向Map中設(shè)置了值,即它做了

Map<String,Object> map = new HashMap<>();
map.put("name", name);
map.put("major",major);

將方法形參中的namemajor放到了map對象中,所以在@Select標(biāo)簽中可以用${name}${major}取出map對象中的值。
--------------------(我是分割線)

上面我們見到了在全局配置文件中,兩種配置mapper的方式,分別是

<!-- 在mapper接口中使用注解 -->
<mappers><mapper class="com.yogurt.mapper.PureStudentMapper"/>
</mappers><!-- 普通加載xml -->
<mappers><mapper resource="StudentMapper.xml"/>
</mappers>

而在實際工作中,一般我們會將一張表的SQL操作封裝在一個mapper.xml中,可能有許多張表需要操作,那么我們是不是要在<mappers>標(biāo)簽下寫多個<mapper>標(biāo)簽?zāi)?#xff1f;其實不用,還有第三種加載mapper的方法,使用<package>標(biāo)簽

<mappers><package name="com.yogurt.mapper"/>
</mappers>

這樣就會自動加載com.yogurt.mapper包下的所有mapper,這種方式需要將mapper接口文件和mapper.xml文件都放在com.yogurt.mapper包下,且接口文件和xml文件的文件名要一致。注意,在IDEA的maven開發(fā)環(huán)境下,maven中還需配置<resources>標(biāo)簽,否則maven打包不會將java源碼目錄下的xml文件打包進(jìn)去,見下文

三種加載mapper的方式總結(jié)

  • <mapper resource="" />

    加載普通的xml文件,傳入xml的相對路徑(相對于類路徑)

  • <mapper class="" />

    使用mapper接口的全限定名來加載,若mapper接口采用注解方式,則不需要xml;若mapper接口沒有采用注解方式,則mapper接口和xml文件的名稱要相同,且在同一個目錄

  • <package name="" />

    掃描指定包下的所有mapper,若mapper接口采用注解方式,則不需要xml;若mapper接口沒有采用注解方式,則mapper接口和xml文件的名稱要相同,且在同一目錄

注意:用后兩種方式加載mapper接口和mapper.xml映射文件時,可能會報錯

仔細(xì)檢查了一下,mapper接口文件和xml映射文件確實放在了同一個目錄下,而且文件名一致,xml映射文件的namespace也和mapper接口的全限定名對的上。為什么會這樣呢?

其實是因為,對于src/main/java 源碼目錄下的文件,maven打包時只會將該目錄下的java文件打包,而其他類型的文件都不會被打包進(jìn)去,去工程目錄的target目錄下看看maven構(gòu)建后生成的文件

我們需要在pom.xml中的<build> 標(biāo)簽下 添加<resources> 標(biāo)簽,指定打包時要將xml文件打包進(jìn)去

<build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource></resources>
</build>

此時再用maven進(jìn)行打包,看到對應(yīng)目錄下有了xml映射文件(特別注意,這里配置了pom.xml下的resource標(biāo)簽后,可能會引發(fā)一些問題,例如原本src/main/resources資源目錄下的文件沒有被打包進(jìn)來,參考我的這篇文章maven打包時的資源文件問題)

此時再運行單元測試,就能正常得到結(jié)果了

應(yīng)用場景

主鍵返回

通常我們會將數(shù)據(jù)庫表的主鍵id設(shè)為自增。在插入一條記錄時,我們不設(shè)置其主鍵id,而讓數(shù)據(jù)庫自動生成該條記錄的主鍵id,那么在插入一條記錄后,如何得到數(shù)據(jù)庫自動生成的這條記錄的主鍵id呢?有兩種方式

  1. 使用useGeneratedKeyskeyProperty屬性

    <insert id="insert" parameterType="com.yogurt.po.Student" useGeneratedKeys="true" keyProperty="id">INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});</insert>
    
  2. 使用<selectKey>子標(biāo)簽

    <insert id="insert" parameterType="com.yogurt.po.Student">INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});<selectKey keyProperty="id" order="AFTER" resultType="int" >SELECT LAST_INSERT_ID();</selectKey></insert>
    

    如果使用的是mysql這樣的支持自增主鍵的數(shù)據(jù)庫,可以簡單的使用第一種方式;對于不支持自增主鍵的數(shù)據(jù)庫,如oracle,則沒有主鍵返回這一概念,而需要在插入之前先生成一個主鍵。此時可以用<selectKey>標(biāo)簽,設(shè)置其order屬性為BEFORE,并在標(biāo)簽體內(nèi)寫上生成主鍵的SQL語句,這樣在插入之前,會先處理<selectKey>,生成主鍵,再執(zhí)行真正的插入操作。

    <selectKey>標(biāo)簽其實就是一條SQL,這條SQL的執(zhí)行,可以放在主SQL執(zhí)行之前或之后,并且會將其執(zhí)行得到的結(jié)果封裝到入?yún)⒌腏ava對象的指定屬性上。注意<selectKey>子標(biāo)簽只能用在<insert><update>標(biāo)簽中。上面的LAST_INSERT_ID()實際上是MySQL提供的一個函數(shù),可以用來獲取最近插入或更新的記錄的主鍵id。

測試代碼如下

public class MapperProxyTest {private SqlSessionFactory sqlSessionFactory;@Beforepublic void init() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);}@Testpublic void test() {SqlSession sqlSession = sqlSessionFactory.openSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);Student student = new Student(-1, "Podman", 130, 15, 0);mapper.insert(student);sqlSession.commit();System.out.println(student.getId());}
}

結(jié)果如下

批量查詢

主要是動態(tài)SQL標(biāo)簽的使用,注意如果parameterTypeList的話,則在標(biāo)簽體內(nèi)引用這個List,只能用變量名list,如果parameterType是數(shù)組,則只能用變量名array

<select id="batchFind" resultType="student" parameterType="java.util.List">SELECT * FROM student<where><if test="list != null and list.size() > 0">AND id in<foreach collection="list" item="id" open="(" separator="," close=")">#{id}</foreach></if></where>
</select>
	@Testpublic void testBatchQuery() {SqlSession sqlSession = sqlSessionFactory.openSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);List<Student> students = mapper.batchFind(Arrays.asList(1, 2, 3, 7, 9));students.forEach(System.out::println);}

結(jié)果

動態(tài)SQL

可以根據(jù)具體的參數(shù)條件,來對SQL語句進(jìn)行動態(tài)拼接。

比如在以前的開發(fā)中,由于不確定查詢參數(shù)是否存在,許多人會使用類似于where 1 = 1 來作為前綴,然后后面用AND 拼接要查詢的參數(shù),這樣,就算要查詢的參數(shù)為空,也能夠正確執(zhí)行查詢,如果不加1 = 1,則如果查詢參數(shù)為空,SQL語句就會變成SELECT * FROM student where ,SQL不合法。

mybatis里的動態(tài)標(biāo)簽主要有

  • if

    <!-- 示例 -->
    <select id="find" resultType="student" parameterType="student">SELECT * FROM student WHERE age >= 18<if test="name != null and name != ''">AND name like '%${name}%'</if>
    </select>
    

    當(dāng)滿足test條件時,才會將<if>標(biāo)簽內(nèi)的SQL語句拼接上去

  • choose

    <!-- choose 和 when , otherwise 是配套標(biāo)簽 
    類似于java中的switch,只會選中滿足條件的一個
    -->
    <select id="findActiveBlogLike"resultType="Blog">SELECT * FROM BLOG WHERE state = ‘ACTIVE’<choose><when test="title != null">AND title like #{title}</when><when test="author != null and author.name != null">AND author_name like #{author.name}</when><otherwise>AND featured = 1</otherwise></choose>
    </select>
    
  • trim

    • where

      <where>標(biāo)簽只會在至少有一個子元素返回了SQL語句時,才會向SQL語句中添加WHERE,并且如果WHERE之后是以AND或OR開頭,會自動將其刪掉

      <select id="findActiveBlogLike"resultType="Blog">SELECT * FROM BLOG<where><if test="state != null">state = #{state}</if><if test="title != null">AND title like #{title}</if><if test="author != null and author.name != null">AND author_name like #{author.name}</if></where>
      </select>
      

      <where>標(biāo)簽可以用<trim>標(biāo)簽代替

      <trim prefix="WHERE" prefixOverrides="AND | OR">...
      </trim>
      
    • set

      在至少有一個子元素返回了SQL語句時,才會向SQL語句中添加SET,并且如果SET之后是以,開頭的話,會自動將其刪掉

      <set>標(biāo)簽相當(dāng)于如下的<trim>標(biāo)簽

      <trim prefix="SET" prefixOverrides=",">...
      </trim>
      

    可以通過<trim>標(biāo)簽更加靈活地對SQL進(jìn)行定制

    實際上在mybatis源碼,也能看到trim與set,where標(biāo)簽的父子關(guān)系

  • foreach

    用來做迭代拼接的,通常會與SQL語句中的IN查詢條件結(jié)合使用,注意,到parameterType為List(鏈表)或者Array(數(shù)組),后面在引用時,參數(shù)名必須為list或者array。如在foreach標(biāo)簽中,collection屬性則為需要迭代的集合,由于入?yún)⑹莻€List,所以參數(shù)名必須為list

    <select id="batchFind" resultType="student" parameterType="list">SELECT * FROM student WHERE id in<foreach collection="list" item="item" open="(" separator="," close=")">#{item}</foreach>
    </select>
    
  • sql

    可將重復(fù)的SQL片段提取出來,然后在需要的地方,使用<include>標(biāo)簽進(jìn)行引用

    <select id="findUser" parameterType="user" resultType="user">SELECT * FROM user<include refid="whereClause"/>
    </select><sql id="whereClause"><where><if test="user != null">AND username like '%${user.name}%'</if></where>
    </sql>
    
  • bind

    mybatis的動態(tài)SQL都是用OGNL表達(dá)式進(jìn)行解析的,如果需要創(chuàng)建OGNL表達(dá)式以外的變量,可以用bind標(biāo)簽

    <select id="selectBlogsLike" resultType="Blog"><bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />SELECT * FROM BLOGWHERE title LIKE #{pattern}
    </select>
    

緩存

  • 一級緩存

    默認(rèn)開啟,同一個SqlSesion級別共享的緩存,在一個SqlSession的生命周期內(nèi),執(zhí)行2次相同的SQL查詢,則第二次SQL查詢會直接取緩存的數(shù)據(jù),而不走數(shù)據(jù)庫,當(dāng)然,若第一次和第二次相同的SQL查詢之間,執(zhí)行了DML(INSERT/UPDATE/DELETE),則一級緩存會被清空,第二次查詢相同SQL仍然會走數(shù)據(jù)庫

    一級緩存在下面情況會被清除

    • 在同一個SqlSession下執(zhí)行增刪改操作時(不必提交),會清除一級緩存
    • SqlSession提交或關(guān)閉時(關(guān)閉時會自動提交),會清除一級緩存
    • 對mapper.xml中的某個CRUD標(biāo)簽,設(shè)置屬性flushCache=true,這樣會導(dǎo)致該MappedStatement的一級緩存,二級緩存都失效(一個CRUD標(biāo)簽在mybatis中會被封裝成一個MappedStatement)
    • 在全局配置文件中設(shè)置 <setting name="localCacheScope" value="STATEMENT"/>,這樣會使一級緩存失效,二級緩存不受影響
  • 二級緩存

    默認(rèn)關(guān)閉,可通過全局配置文件中的<settings name="cacheEnabled" value="true"/>開啟二級緩存總開關(guān),然后在某個具體的mapper.xml中增加<cache />,即開啟了該mapper.xml的二級緩存。二級緩存是mapper級別的緩存,粒度比一級緩存大,多個SqlSession可以共享同一個mapper的二級緩存。注意開啟二級緩存后,SqlSession需要提交,查詢的數(shù)據(jù)才會被刷新到二級緩存當(dāng)中

緩存的詳細(xì)分析可以參考我之前的文章 => 極簡mybatis緩存

關(guān)聯(lián)查詢

使用<resultMap> 標(biāo)簽以及<association><collection> 子標(biāo)簽,進(jìn)行關(guān)聯(lián)查詢,比較簡單,不多說

延遲加載

延遲加載是結(jié)合關(guān)聯(lián)查詢進(jìn)行應(yīng)用的。也就是說,只在<association><collection> 標(biāo)簽上起作用

對于關(guān)聯(lián)查詢,若不采用延遲加載策略,而是一次性將關(guān)聯(lián)的從信息都查詢出來,則在主信息比較多的情況下,會產(chǎn)生N+1問題,導(dǎo)致性能降低。比如用戶信息和訂單信息是一對多的關(guān)系,在查詢用戶信息時,設(shè)置了關(guān)聯(lián)查詢訂單信息,如不采用延遲加載策略,假設(shè)共有100個用戶,則我們查這100個用戶的基本信息只需要一次SQL查詢

select * from user;

若開啟了關(guān)聯(lián)查詢,且不是延遲加載,則對于這100個用戶,會發(fā)出100條SQL去查用戶對應(yīng)的訂單信息,這樣會造成不必要的性能開銷(其實我認(rèn)為稱之為1+N問題更為合適)

select * from orders where u_id = 1;
select * from orders where u_id = 2;
....
select * from orders where u_id = 100;

當(dāng)我們可能只關(guān)心id=3的用戶的訂單信息,則很多的關(guān)聯(lián)信息是無用的,于是,采用延遲加載策略,可以按需加載從信息,在需要某個主信息對應(yīng)的從信息時,再發(fā)送SQL去執(zhí)行查詢,而不是一次性全部查出來,這樣能很好的提升性能。

另外,針對N+1問題,除了采用延遲加載的策略按需進(jìn)行關(guān)聯(lián)查詢。如果在某些場景下,確實需要查詢所有主信息關(guān)聯(lián)的從信息。在上面的例子中,就是如果確實需要把這100個用戶關(guān)聯(lián)的訂單信息全部查詢出來,那怎么辦呢?這里提供2個解決思路。

1是采用連接查詢,只使用1條SQL即可,如下

select * from user as u left join orders as o on u.id = o.u_id;

但使用連接查詢查出來的結(jié)果是兩表的笛卡爾積,還需要自行進(jìn)行數(shù)據(jù)的分組處理

2是使用兩個步驟來完成,先執(zhí)行一條SQL,查出全部的用戶信息,并把用戶的id放在一個集合中,然后第二條SQL采用IN關(guān)鍵字查詢即可。這種方式也可以簡化為子查詢,如下

select * from orders where u_id in (select id from user);

現(xiàn)在說回來,mybatis的延遲加載默認(rèn)是關(guān)閉的,可以通過全局配置文件中的<setting name="lazyLoadingEnabled" value="true"/>來開啟,開啟后,所有的SELECT查詢,若有關(guān)聯(lián)對象,都會采用延遲加載的策略。當(dāng)然,也可以對指定的某個CRUD標(biāo)簽單獨禁用延遲加載策略,通過設(shè)置SELECT標(biāo)簽中的fetchType=eager,則可以關(guān)閉該標(biāo)簽的延遲加載。

(還有一個侵入式延遲加載的概念,在配置文件中通過<setting name="aggressiveLazyLoading" value="true">來開啟,大概是說,訪問主對象中的主信息時,就會觸發(fā)延遲加載,將從信息查詢上來,這其實并不是真正意義的延遲加載,真正意義上的延遲加載應(yīng)該是訪問主對象中的從信息時,才觸發(fā)延遲加載,去加載從信息,侵入式延遲加載默認(rèn)是關(guān)閉的,一般情況下可以不用管他)

注意,延遲加載在關(guān)聯(lián)查詢的場景下才有意義。需要配合<resultMap>標(biāo)簽下的<association><collecction> 標(biāo)簽使用

<!-- StudentMapper.xml -->
<resultMap id="studentExt" type="com.yogurt.po.StudentExt"><result property="id" column="id"/><result property="name" column="name"/><result property="score" column="score"/><result property="age" column="age"/><result property="gender" column="gender"/><!-- 當(dāng)延遲加載總開關(guān)開啟時,resultMap下的association和collection標(biāo)簽中,若通過select屬性指定嵌套查詢的SQL,則其fetchType默認(rèn)是lazy的,當(dāng)在延遲加載總開關(guān)開啟時,需要對個別的關(guān)聯(lián)查詢禁用延遲加載時,才有必要配置fetchType = eager --><!--column用于指定用于關(guān)聯(lián)查詢的列property用于指定要封裝到StudentExt中的哪個屬性javaType用于指定關(guān)聯(lián)查詢得到的對象select用于指定關(guān)聯(lián)查詢時,調(diào)用的是哪一個DQL--><association property="clazz" javaType="com.yogurt.po.Clazz" column="class_id"select="com.yogurt.mapper.ClassMapper.findById" fetchType="lazy"/></resultMap><select id="findLazy" parameterType="string" resultMap="studentExt">SELECT * FROM student WHERE name like '%${value}%';</select>
<!-- com.yogurt.mapper.ClassMapper -->
<select id="findById" parameterType="int" resultType="com.yogurt.po.Clazz">SELECT * FROM class WHERE id = #{id}
</select>
/** 用于封裝關(guān)聯(lián)查詢的對象 **/
public class StudentExt{private Integer id;private String name;private Integer score;private Integer age;private Integer gender;/** 關(guān)聯(lián)對象 **/private Clazz clazz;//getter/setter
}

逆向工程

mybatis官方提供了mapper自動生成工具mybatis-generator-core來針對單表,生成PO類,以及Mapper接口和mapper.xml映射文件。針對單表,可以不需要再手動編寫xml配置文件和mapper接口文件了,非常方便。美中不足的是它不支持生成關(guān)聯(lián)查詢。一般做關(guān)聯(lián)查詢,就自己單獨寫SQL就好了。

基于IDEA的mybatis逆向工程操作步驟如下

  1. 配置maven插件

    <build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><!-- 輸出日志 --><verbose>true</verbose><overwrite>true</overwrite></configuration></plugin></plugins></build>
    
  2. 在resources目錄下創(chuàng)建名為generatorConfig.xml的配置文件

  3. 配置文件的模板如下

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!--導(dǎo)入屬性配置--><properties resource="properties/xx.properties"></properties><!-- 指定數(shù)據(jù)庫驅(qū)動的jdbc驅(qū)動jar包的位置 --><classPathEntry location="C:\Users\Vergi\.m2\repository\mysql\mysql-connector-java\8.0.11\mysql-connector-java-8.0.11.jar" /><!-- context 是逆向工程的主要配置信息 --><!-- id:起個名字 --><!-- targetRuntime:設(shè)置生成的文件適用于那個 mybatis 版本 --><context id="default" targetRuntime="MyBatis3"><!--optional,旨在創(chuàng)建class時,對注釋進(jìn)行控制--><commentGenerator><property name="suppressDate" value="true" /><!-- 是否去除自動生成的注釋 true:是 : false:否 --><property name="suppressAllComments" value="true" /></commentGenerator><!--jdbc的數(shù)據(jù)庫連接--><jdbcConnection driverClass="${db.driver}"connectionURL="${db.url}"userId="${db.user}"password="${db.password}"></jdbcConnection><!--非必須,類型處理器,在數(shù)據(jù)庫類型和java類型之間的轉(zhuǎn)換控制--><javaTypeResolver><!-- 默認(rèn)情況下數(shù)據(jù)庫中的 decimal,bigInt 在 Java 對應(yīng)是 sql 下的 BigDecimal 類 --><!-- 不是 double 和 long 類型 --><!-- 使用常用的基本類型代替 sql 包下的引用類型 --><property name="forceBigDecimals" value="false" /></javaTypeResolver><!-- targetPackage:生成的實體類所在的包 --><!-- targetProject:生成的實體類所在的硬盤位置 --><javaModelGenerator targetPackage="mybatis.generator.model"targetProject=".\src\main\java"><!-- 是否允許子包 --><property name="enableSubPackages" value="false" /><!-- 是否清理從數(shù)據(jù)庫中查詢出的字符串左右兩邊的空白字符 --><property name="trimStrings" value="true" /></javaModelGenerator><!-- targetPackage 和 targetProject:生成的 mapper.xml 文件的包和位置 --><sqlMapGenerator targetPackage="mybatis.generator.mappers"targetProject=".\src\main\resources"><!-- 針對數(shù)據(jù)庫的一個配置,是否把 schema 作為字包名 --><property name="enableSubPackages" value="false" /></sqlMapGenerator><!-- targetPackage 和 targetProject:生成的 mapper接口文件的包和位置 --><javaClientGenerator type="XMLMAPPER"targetPackage="mybatis.generator.dao" targetProject=".\src\main\java"><!-- 針對 oracle 數(shù)據(jù)庫的一個配置,是否把 schema 作為子包名 --><property name="enableSubPackages" value="false" /></javaClientGenerator><!-- 這里指定要生成的表 --><table tableName="student"/><table tableName="product"/></context>
    </generatorConfiguration>
    
  4. 雙擊執(zhí)行mybatis-generator的maven插件

執(zhí)行日志如下

生成的文件如下

能看到mybatis-generator除了給我們生成了基本的PO類(上圖的Student和Product),還額外生成了Example類。Example類是為了方便執(zhí)行SQL時傳遞查詢條件的。使用的示例如下

public class GeneratorTest {private SqlSessionFactory sqlSessionFactory;@Beforepublic void init() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("mysql8-config.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);}@Testpublic void test() {SqlSession sqlSession = sqlSessionFactory.openSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);StudentExample example = new StudentExample();StudentExample.Criteria criteria = example.createCriteria();criteria.andNameLike("%o%");List<Student> students = mapper.selectByExample(example);students.forEach(System.out::println);}
}

結(jié)果如下

PageHelper分頁插件

使用該插件,快速實現(xiàn)查詢結(jié)果的分頁,使用步驟如下

  1. pom.xml中配置依賴

    <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.6</version>
    </dependency>
    
  2. mybatis全局配置文件中配置<plugin>標(biāo)簽

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration><properties resource="properties/xx.properties"></properties><plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="helperDialect" value="mysql"/></plugin></plugins><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${db.driver}"/><property name="url" value="${db.url}"/><property name="username" value="${db.user}"/><property name="password" value="${db.password}"/></dataSource></environment></environments><mappers><package name="mybatis.generator.dao"/></mappers></configuration>
    
  3. 在執(zhí)行查詢之前,先設(shè)置分頁信息

    // 查詢第一頁,每頁3條信息
    PageHelper.startPage(1,3);
    

    先看一下查所有數(shù)據(jù)

    	@Testpublic void test() {SqlSession sqlSession = sqlSessionFactory.openSession();ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);//PageHelper.startPage(1,3);List<Product> products = mapper.selectByExample(new ProductExample());products.forEach(System.out::println);}
    

    加上PageHelper分頁

    	@Testpublic void test() {SqlSession sqlSession = sqlSessionFactory.openSession();ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);PageHelper.startPage(1,3);List<Product> products = mapper.selectByExample(new ProductExample());products.forEach(System.out::println);}
    


    特別注意:在編寫mapper.xml的時候,SQL語句的結(jié)尾不要帶上;,因為PageHelper插件是在SQL末尾拼接LIMIT關(guān)鍵字來進(jìn)行分頁的,若SQL語句帶上了;,就會造成SQL語法錯誤

    另外,PageHelper會先查詢總數(shù)量,然后再發(fā)出分頁查詢,打開mybatis的日志時,可以看到發(fā)出了2條SQL
    當(dāng)開啟PageHelper時,查詢得到的List實際是PageHelper中自定義的一個類Page,這個類實現(xiàn)了List接口,并封裝了分頁的相關(guān)信息(總頁數(shù),當(dāng)前頁碼等)。

    可以通過PageInfo來獲取分頁的相關(guān)信息,代碼如下

    @Test
    public void test() {SqlSession sqlSession = factory.openSession();PageHelper.startPage(1,3);ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);List<Product> list = mapper.findAll();list.forEach(System.out::println);PageInfo<Product> pageInfo = new PageInfo<>(list);System.out.println(pageInfo.getTotal()); // 獲得總數(shù)System.out.println(pageInfo.getPageSize());  // 獲得總頁數(shù)
    }
    

    PageHelper插件的源碼分析可以查看我之前的文章 =>
    極簡PageHelper源碼分析

Mybatis Plus

mybatis雖然非常方便,但也需要編寫大量的SQL語句,于是mybatis plus就應(yīng)運而生了。它是一個mybatis增強工具,為了簡化開發(fā),提高效率。搭配Spring-Boot食用簡直不要太爽。

可以參考我的這篇文章 mybatis-plus一發(fā)入魂 ,或者mybatis-plus官網(wǎng),以及慕課網(wǎng)的入門教程和進(jìn)階教程

(完)

注:該文是一篇較為全面詳細(xì)的筆記,內(nèi)容篇幅很長。當(dāng)對mybatis的使用較為熟練后,可以查看這篇極為簡短的 mybatis精髓總結(jié),從整體架構(gòu)和源碼層面上把握mybatis。

總結(jié)

以上是生活随笔為你收集整理的mybatis看这一篇就够了,简单全面一发入魂的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

国产高清视频网 | 日本婷婷色| 色天天综合网 | 三级在线视频观看 | 最近2019好看的中文字幕免费 | 国产精品久久电影观看 | 婷婷夜夜| 免费网站黄色 | 中文字幕久久网 | 精品人妖videos欧美人妖 | 成年人国产在线观看 | 国产精品免费在线视频 | 欧美激情视频一二区 | 久久免费成人网 | 操操操影院 | 亚洲国产精品人久久电影 | 国产精品原创av片国产免费 | 国产高清在线永久 | 亚洲狠狠操 | 人人射| www.色国产| 狠狠网 | 丁五月婷婷| 久久国产精品一国产精品 | 97干com| 人人爽夜夜爽 | 色噜噜狠狠色综合中国 | 国产亚洲欧美日韩高清 | 天天插视频 | 91精品久久久久久综合乱菊 | 欧美天天综合 | 日本mv大片欧洲mv大片 | 热久久免费视频精品 | 天天搞天天干天天色 | 综合网天天色 | 欧美视频99 | 91理论片午午伦夜理片久久 | 欧美日韩视频一区二区 | 精品视频免费看 | 91尤物在线播放 | 国产又粗又硬又长又爽的视频 | 成人黄色av网站 | 欧美另类亚洲 | 又大又硬又黄又爽视频在线观看 | 欧美五月婷婷 | 丁香花五月 | 97麻豆视频| 99热国产在线中文 | 久草在线国产 | 国产精品av免费 | 中文字幕免费在线看 | 国产精品6999成人免费视频 | 蜜臀aⅴ国产精品久久久国产 | 欧美一级特黄aaaaaa大片在线观看 | 色综合中文综合网 | 国产精品1区2区3区在线观看 | 在线亚洲午夜片av大片 | 中文字幕在线播放av | 国产精品一二 | avav片| 久久成人久久 | 亚洲香蕉在线观看 | 男女激情网址 | 日韩在线视频网站 | 久久精品美女视频 | 成人免费影院 | 日韩一区二区三区免费视频 | 中文字幕在线观看第二页 | 婷婷国产一区二区三区 | 91自拍视频在线观看 | 亚欧日韩成人h片 | 在线色网站 | 久热电影| 超碰97免费在线 | 日韩精品第1页 | 日韩资源视频 | 99精品偷拍视频一区二区三区 | 激情欧美网| av先锋中文字幕 | 日韩欧美在线免费观看 | 91福利在线导航 | 久久久免费观看 | 日本三级吹潮在线 | 国产日韩欧美在线免费观看 | 亚洲视频999 | 激情综合网五月婷婷 | 丝袜av网站| 亚洲激情综合 | 97夜夜澡人人双人人人喊 | 亚洲尺码电影av久久 | 亚洲a网| 欧美日韩不卡在线观看 | 中文字幕日韩av | 精品视频在线看 | 激情视频区 | 黄色免费在线看 | 精品国产电影一区二区 | 在线播放你懂 | av一级片在线观看 | 91中文字幕在线观看 | 国产99亚洲 | 久热香蕉视频 | 久久丁香 | 久九视频 | 麻豆视频在线观看免费 | 欧美在线aaa | 亚洲va欧美va人人爽春色影视 | 99精品乱码国产在线观看 | 天天综合天天做 | 国产一级片直播 | 精选久久 | 69中文字幕 | 五月婷婷在线观看视频 | 不卡视频在线 | 国产视频精品久久 | 国产精品免费一区二区三区 | 天天操天天干天天爱 | 亚洲欧洲精品一区二区精品久久久 | 国产又粗又猛又黄又爽的视频 | 999久久a精品合区久久久 | 韩国视频一区二区三区 | 天堂网一区二区 | 天天射天天射天天 | 成人免费色 | 午夜精品久久久久久久99 | 日日日操操 | 中文字幕区 | 国产免费亚洲高清 | 在线免费观看一区二区三区 | 久久国产精品影视 | 欧美日韩精品国产 | 四虎永久国产精品 | 免费日韩 精品中文字幕视频在线 | 欧美精品一区二区在线播放 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产视频在线观看一区二区 | 久热av在线| 欧美少妇xxxxxx | 91精品国自产在线观看 | 欧美性生爱 | 久久久www成人免费精品张筱雨 | www黄色av | 色综合久久88色综合天天免费 | a在线观看免费视频 | 美女又爽又黄 | 在线视频99 | 国产精品久久久 | 狠狠干婷婷 | 欧美日韩国产综合一区二区 | 9999精品 | h久久| 性色av免费在线观看 | 西西www444| 久久精品79国产精品 | 丁香婷婷在线观看 | 中文免费在线观看 | 亚洲欧美偷拍另类 | 亚洲精品国产精品国自 | 国产精品永久免费 | 国产在线观看h | 免费观看福利视频 | 亚洲精品国偷自产在线99热 | 日韩激情中文字幕 | 久草在在线视频 | 五月激情电影 | 亚洲 欧美 变态 国产 另类 | 1000部国产精品成人观看 | 麻豆国产网站入口 | 日韩一区二区三区在线观看 | 日韩精品一区二区三区外面 | 91爱爱中文字幕 | 九色精品免费永久在线 | 免费观看性生交大片3 | 国产丝袜一区二区三区 | 日韩在线观看视频中文字幕 | 日韩欧美xxxx| 精品一区二区免费视频 | 天堂麻豆 | 日韩中文字幕在线观看 | 国产亚洲欧美精品久久久久久 | 日日摸日日| 久草在线久草在线2 | 成人av免费看 | av高清在线 | 99精品在线视频播放 | 国产精品综合久久久 | 狠狠婷婷| www.福利视频| 青青河边草观看完整版高清 | 亚洲欧美国内爽妇网 | 色综合网| 久久网站免费 | 手机av电影在线 | 国产一级黄色免费看 | 中文成人字幕 | 中文在线免费看视频 | 免费av大片 | 日本在线视频一区二区三区 | 欧美99精品 | 天天操综合网站 | 日本高清中文字幕有码在线 | 免费黄色在线网站 | 国产一二三在线视频 | 99久久国产免费免费 | 天天干,天天干 | 摸bbb搡bbb搡bbbb | 成人夜晚看av | 一区中文字幕电影 | 国产黄影院色大全免费 | 狠狠干狠狠插 | 探花视频在线观看免费版 | 91亚·色| 亚洲一区av | 亚洲一区久久久 | 免费国产在线视频 | 日本护士三级少妇三级999 | 精品成人免费 | av在线等| 欧美一级黄色视屏 | 日韩a在线观看 | 久久免费在线观看 | 在线一二三区 | 精品国产乱码久久久久久久 | 亚洲最新在线视频 | 99激情网| 欧美一区二区免费在线观看 | 精品视频久久久 | 欧洲精品码一区二区三区免费看 | 久久国产精品区 | 日韩精品首页 | .国产精品成人自产拍在线观看6 | 在线播放一区二区三区 | 成人免费观看视频大全 | 波多野结衣一区 | 久久精品aaa| 波多野结衣电影一区 | 激情综合网五月激情 | www色网站 | 99亚洲国产精品 | 亚洲高清激情 | 丁香婷婷综合五月 | 狠狠狠狠狠狠狠狠 | 成人片在线播放 | 国产午夜精品av一区二区 | 国产91学生| 麻豆国产精品一区二区三区 | 久久久久久久久久久久久久免费看 | 98涩涩国产露脸精品国产网 | 中文字幕在线日本 | 91色蜜桃 | 免费看黄色大全 | 最新不卡av | 精品视频一区在线观看 | 国内精品在线观看视频 | 国内精品免费 | 亚洲美女在线一区 | 日日干,天天干 | 五月天婷婷免费视频 | 国产美女视频免费观看的网站 | 在线看国产| 午夜国产在线观看 | 国产成人久久精品77777综合 | 天天做天天爱天天综合网 | 免费人成在线观看 | 特级a老妇做爰全过程 | 美女久久久久久久 | 五月天久久激情 | 国产精品久久在线观看 | 中文欧美字幕免费 | 亚洲午夜精品久久久久久久久久久久 | 午夜黄网 | 99热精品免费观看 | 日韩精品大片 | 中文字幕精品www乱入免费视频 | 国产一区二区三区免费在线观看 | 亚在线播放中文视频 | 99中文字幕在线观看 | 久久久久久久久久久网站 | 一区二区三区观看 | 一区二区三区韩国免费中文网站 | 日韩一区二区三区高清在线观看 | 国产亚洲一区二区三区 | 激情久久伊人 | 国产精品a成v人在线播放 | 91麻豆精品国产 | 国产精品久久久久免费 | 国产成人精品福利 | 四虎影视8848dvd| 日韩三级在线 | 综合伊人av | 精品主播网红福利资源观看 | 99re8这里有精品热视频免费 | 亚洲精品在线观看中文字幕 | 激情av一区二区 | 久久久性 | 蜜臀一区二区三区精品免费视频 | 久久久香蕉视频 | 久久久久亚洲a | 丁香五月网久久综合 | 久久99亚洲精品 | 成人av高清 | 国产99久久久精品 | 国产日韩在线观看一区 | 色综久久| 91精品免费在线视频 | a级一a一级在线观看 | 免费在线国产 | 在线免费观看黄色av | 国产日韩欧美在线 | 国产色在线观看 | 天天干,天天射,天天操,天天摸 | 狠狠干夜夜操天天爽 | 免费看片亚洲 | 欧美va电影| 亚洲视频资源在线 | 97电影手机 | 怡红院成人在线 | 西西4444www大胆视频 | 少妇bbw搡bbbb搡bbbb | 国产第一页在线观看 | 三级视频日韩 | 日韩精品久久久久久中文字幕8 | 日韩动漫免费观看高清完整版在线观看 | 久久精品久久99 | 国产成人精品a | 欧美激情xxxx性bbbb | 成人国产在线 | 精品一区 精品二区 | 精品一区二区电影 | 日韩精品视频在线观看网址 | 黄色小说在线观看视频 | 国产 视频 久久 | 婷婷伊人网 | 中文字幕视频网站 | 午夜av在线播放 | 国产一级精品视频 | 99热官网 | www.久久成人 | 久久久网址 | 视频在线观看国产 | 人人爽影院 | 日韩黄色在线电影 | 亚洲天天在线日亚洲洲精 | 国产精品久久久99 | 亚洲高清视频在线 | 日韩精品免费在线视频 | 免费在线观看a v | 一区二区三区免费在线观看 | 中文字幕一区二区三区四区久久 | 国产九九九视频 | 中文字幕一区二区三区久久 | 国产精品一区久久久久 | 国产一级免费在线观看 | 精品1区2区 | 人人爽人人乐 | bbbbb女女女女女bbbbb国产 | 81精品国产乱码久久久久久 | 国产精品麻 | 欧美久久久久久久久久久久 | 欧美久久久久久久久久久久久 | 天天操天天操天天操 | 999久久久久久 | 天天干 夜夜操 | 久久久久久久久久影院 | 福利在线看片 | 91精品国产91p65| 草莓视频在线观看免费观看 | 亚洲国产三级在线观看 | 国产中文字幕在线播放 | 超碰在线观看av.com | 成人综合日日夜夜 | 亚洲精品在线一区二区 | 91亚洲精品视频 | 伊人国产在线观看 | 日韩欧美一区二区在线播放 | 国产又粗又猛又黄视频 | 中文字幕精品一区久久久久 | 国产精品欧美日韩 | 国产无遮挡又黄又爽在线观看 | 国产精品黄色影片导航在线观看 | 91激情| 国产精品久久久久久久久婷婷 | 狠狠色伊人亚洲综合成人 | 亚洲精品在线电影 | 亚洲人成人在线 | 午夜私人影院 | 色综合天天综合网国产成人网 | 在线免费观看不卡av | 蜜臀aⅴ国产精品久久久国产 | 久久大片网站 | 久久a免费视频 | 久久免费黄色网址 | 国产中文字幕视频在线观看 | 久久伊人八月婷婷综合激情 | 亚洲日本va午夜在线电影 | 国产高清综合 | 免费成人在线观看 | 久久电影日韩 | 欧美一级片免费 | 97精品国产91久久久久久久 | 97视频免费在线观看 | 日韩av在线看 | 日日夜夜精品视频天天综合网 | 久久久精选 | 国产精品日韩在线 | 精品久久国产 | 国产精品av电影 | 日韩av中文在线观看 | 日本久久久影视 | 在线免费观看羞羞视频 | 一区在线观看视频 | 丁香久久激情 | 亚洲黄色精品 | 天天操夜夜操国产精品 | 免费av网站在线 | 久久精品视频在线看 | 欧美网站黄色 | 色一级片| 97超碰资源网 | 97国产大学生情侣酒店的特点 | 97在线看| 麻豆视传媒官网免费观看 | 在线观看麻豆av | 成人av资源网 | 手机在线日韩视频 | 日韩视频图片 | 日日色综合 | 一区二区三区免费在线 | 国产拍揄自揄精品视频麻豆 | 欧美999| 国产精品久久久毛片 | 天天天综合网 | 日韩啪啪小视频 | 免费黄色小网站 | 精品中文字幕在线观看 | 亚洲国产精品99久久久久久久久 | 麻豆国产精品视频 | 国产精品麻豆果冻传媒在线播放 | 亚洲极色| 国产精品色婷婷视频 | 久久高清免费视频 | 亚洲高清精品在线 | 美女视频黄免费 | 国产偷国产偷亚洲清高 | 国产一卡二卡在线 | 就要干b| 欧美一级性生活片 | 人人躁 | 亚洲电影免费 | 久久午夜视频 | 91久久国产综合精品女同国语 | 国产美女视频网站 | 91重口视频 | 中文字幕在线观看免费高清电影 | 亚洲经典视频在线观看 | 99久久久国产精品 | 亚洲永久精品视频 | 91精品1区2区 | 日韩在线免费小视频 | 欧美性精品 | 成人一级电影在线观看 | 亚洲激情电影在线 | 久久艹国产视频 | 99精品国产免费久久 | 色噜噜日韩精品欧美一区二区 | 在线国产精品一区 | 亚洲成av人片 | 久久电影国产免费久久电影 | 麻豆视频免费入口 | 免费美女av | 极品嫩模被强到高潮呻吟91 | 国产传媒中文字幕 | 久久精品网址 | 日韩午夜一级片 | 狠狠狠的干 | 99精品欧美一区二区 | 国产乱码精品一区二区蜜臀 | 亚洲 欧美 另类人妖 | 亚洲精品久久久久58 | 久久亚洲私人国产精品va | 国产成本人视频在线观看 | 免费观看午夜视频 | 婷婷午夜 | 国产成人福利 | 国产精品青青 | 日本特黄一级 | 最新色视频 | 天天操狠狠操夜夜操 | 色综合天天做天天爱 | 国产不卡在线播放 | 在线观看视频91 | 欧美精品久久久久久久久久 | 成人免费 在线播放 | 美女视频黄在线观看 | 在线观看黄色免费视频 | 六月天综合网 | 男女啪啪免费网站 | 不卡视频在线看 | 久久久久国产精品www | 中文字幕在线观看免费 | 国产精品免费观看国产网曝瓜 | 国产免费黄视频在线观看 | 久久99久久99精品免视看婷婷 | 亚州精品天堂中文字幕 | 在线播放日韩av | 日韩日韩日韩日韩 | 91成人免费看片 | 亚洲综合色播 | 国产小视频免费在线网址 | 人人草在线观看 | 91私密视频| 不卡视频一区二区三区 | 欧美另类69 | 久久久国产精品一区二区三区 | 久久亚洲私人国产精品 | 国产一级片一区二区三区 | 99久久久| 亚洲第一中文网 | 99在线热播精品免费99热 | 精品一区精品二区高清 | 日韩中文免费视频 | 国产精品九九久久99视频 | 亚洲免费精彩视频 | 麻豆网站免费观看 | 久久久久久久久久久影院 | 97在线观看免费观看 | 日韩精品观看 | 在线免费观看黄网站 | 免费情趣视频 | 99re久久资源最新地址 | 三级动态视频在线观看 | 超级碰视频 | 国产男女无遮挡猛进猛出在线观看 | 久草在线免费播放 | 免费在线黄 | 精品国产理论片 | 日韩精品欧美一区 | 中文字幕在线观看第一页 | 超碰人人射 | 国产高清免费av | 精品久久久久久久久久 | 国产视频中文字幕在线观看 | 天天干天天怕 | 在线观看亚洲国产 | 日韩精品视频在线免费观看 | 国产精品一区免费看8c0m | 天天草天天爽 | 在线不卡中文字幕播放 | 国产在线2020 | 成人午夜精品久久久久久久3d | 在线中文字幕一区二区 | 久久免费av电影 | 免费在线观看av网站 | 99视频精品全国免费 | 国产在线不卡一区 | 精品一区三区 | 日韩黄色免费 | 五月婷婷在线视频 | 成人教育av | 国产精品一区二区三区四 | 成人蜜桃| 成人av资源站 | 波多野结衣视频一区二区三区 | 精品国产日本 | 精品国产一区二区三区久久久 | 精品在线看 | 九七在线视频 | 国产精品国内免费一区二区三区 | 三级av在线免费观看 | 久久99免费观看 | 人人揉人人揉人人揉人人揉97 | 久草在线视频国产 | 久久激情小视频 | av品善网 | 日韩天天操 | 91网址在线看 | 91资源在线播放 | 色婷婷国产精品一区在线观看 | 免费看av在线 | 国产一区在线不卡 | 24小时日本在线www免费的 | 日韩视频一区二区 | www.夜夜操.com| 天天天在线综合网 | 日韩精品视频网站 | 国产高清在线免费观看 | 精品国精品自拍自在线 | 久久精品女人毛片国产 | 免费看片亚洲 | 日本aaaa级毛片在线看 | 日韩久久久久 | 国产无遮挡又黄又爽在线观看 | 欧美日韩在线看 | 黄色网在线播放 | a天堂最新版中文在线地址 久久99久久精品国产 | 人人插人人看 | 欧美aa在线观看 | 国产探花视频在线播放 | 亚洲精品久久久久久久蜜桃 | 伊人久久精品久久亚洲一区 | 亚洲jizzjizz日本少妇 | 一区二区三区播放 | 久久久视频在线 | 99国产一区二区三精品乱码 | 三日本三级少妇三级99 | 狠狠网亚洲精品 | 欧美日韩裸体免费视频 | 欧美人操人 | 一级免费看 | 色吧久久 | 国产成人福利片 | 国产精品黑丝在线观看 | 日韩黄色中文字幕 | 狠狠色丁香久久综合网 | 精品一区二区三区久久 | 国产在线无| 日日夜夜免费精品视频 | 精品高清美女精品国产区 | 九九免费精品视频在线观看 | 欧美激情第一页xxx 午夜性福利 | 91精品一区二区三区蜜臀 | 99视频黄 | 国产高清永久免费 | 亚洲精品久久久蜜臀下载官网 | 国产色综合天天综合网 | 国产精品欧美精品 | www.五月天 | 亚洲精品黄 | 91中文字幕 | 国产日韩欧美在线一区 | 国产精品综合av一区二区国产馆 | 丁香六月久久综合狠狠色 | 欧美成人精品欧美一级乱 | 99久久久久免费精品国产 | 日韩影片在线观看 | 婷婷丁香色 | 99麻豆久久久国产精品免费 | av五月婷婷 | 六月丁香激情网 | 91精品国产欧美一区二区 | av日韩国产 | 国产精品高清一区二区三区 | 人人澡av | 狠狠网亚洲精品 | 最新中文字幕 | 国产精品视频 | 亚洲一区精品二人人爽久久 | 国产高清一 | 久久国产免 | 狂野欧美激情性xxxx欧美 | 夜夜骑天天操 | 成人中文字幕在线 | 久久久免费 | 日本久久高清视频 | 欧美一级裸体视频 | 国产精品 视频 | 手机色站| 午夜黄色影院 | a v在线视频| 狠狠色综合欧美激情 | 国产精品美女久久久久久网站 | 成人久久久久 | 久久高清国产视频 | 欧美成a人片在线观看久 | 成人免费观看在线视频 | 91成人在线观看喷潮 | 美女免费网站 | 久 久久影院| 久久久国产99久久国产一 | 精品一区在线看 | 色噜噜狠狠狠狠色综合久不 | 久久99精品波多结衣一区 | 国产一二区免费视频 | 精品亚洲午夜久久久久91 | 五月天天天操 | 亚洲在线视频播放 | 久久久久久久久久影院 | 亚洲精品国产日韩 | 亚av在线 | 国产日本在线 | 久久久免费精品国产一区二区 | 久久9999久久免费精品国产 | 成人a视频片观看免费 | 丰满少妇对白在线偷拍 | 久久久亚洲麻豆日韩精品一区三区 | 四虎国产精品免费观看视频优播 | 91精品国产乱码久久 | 久久婷婷五月综合色丁香 | 麻豆极品 | 在线看av网址 | 欧美成人精品欧美一级乱 | 中国精品一区二区 | 亚洲日本韩国一区二区 | 99热精品国产一区二区在线观看 | 国产日韩精品一区二区 | 国产网红在线观看 | 天天综合成人 | 久久精品国产久精国产 | 国产一线天在线观看 | 久久综合操 | 亚洲日本三级 | 久草网视频 | 国产精品综合在线 | 国产午夜一区二区 | 国产理论一区二区三区 | 久久99亚洲热视 | 国产中文字幕免费 | 99爱视频| 国产成人精品av在线观 | 91精彩在线视频 | 激情视频一区二区三区 | 九九久久久 | 国产录像在线观看 | 日韩中出在线 | 伊人五月婷 | 91香蕉嫩草 | 黄色一级动作片 | 午夜av一区二区三区 | 在线激情影院一区 | 国产精品地址 | 精品一区二区免费 | 91九色蝌蚪视频 | 六月天综合网 | 四虎国产视频 | 国产特级毛片aaaaaa毛片 | aa级黄色大片 | 久久不卡视频 | 久久精品视频在线观看 | 国产一区二区三区免费观看视频 | 精品国产99 | 日本精品久久久久中文字幕5 | 日产av在线播放 | 亚洲一区网 | 91麻豆精品一区二区三区 | 成人精品久久久 | 一区二区三区精品在线视频 | 99久久久国产精品免费99 | www.久久爱.cn| 久久久精品国产一区二区电影四季 | 日本精品中文字幕 | 亚洲天堂网视频在线观看 | www亚洲精品 | 九九久久久久久久久激情 | 国产精品国产三级国产专区53 | 99视频在线精品免费观看2 | 欧美日韩亚洲在线观看 | 在线看成人 | 中文字幕在线视频免费播放 | 欧洲亚洲国产视频 | 九九国产视频 | 亚洲影院国产 | 色午夜影院 | 99av在线视频| 992tv又爽又黄的免费视频 | 啪啪小视频网站 | 久久伦理视频 | 欧美日本国产在线观看 | 色av婷婷 | 亚洲伦理精品 | 日韩在线视频网 | 欧美性做爰猛烈叫床潮 | 美女精品 | 天天干com| 天天综合色天天综合 | 国产黄色理论片 | 综合网中文字幕 | 久久免费的视频 | 亚洲精品福利视频 | 91网在线观看 | 国产在线播放一区二区三区 | 黄a网站| 二区三区在线观看 | 国产精品久久久久久高潮 | 97综合视频 | 精品国产乱子伦一区二区 | 久草资源在线 | 欧美成人在线网站 | 国产 亚洲 欧美 在线 | 日韩av午夜| 黄色免费电影网站 | 九九久久视频 | 免费看毛片在线 | 日韩亚洲国产中文字幕 | 狠狠干干| 久久久黄视频 | 五月婷婷婷婷婷 | 国产永久免费高清在线观看视频 | 精品久久久久久久久久国产 | 色多视频在线观看 | 日韩二区三区在线 | 91九色网站 | 久久99精品热在线观看 | 国产精品嫩草影视久久久 | 成人av在线看 | 青青河边草观看完整版高清 | 国产成人免费在线 | 特级毛片爽www免费版 | 日本色小说视频 | 免费色视频网址 | 色久av| 在线观看日韩av | 精品国产乱码久久久久久天美 | 天堂网在线视频 | 日韩69av| 国产69精品久久久久久 | a成人v在线 | 日本公妇在线观看 | 激情久久小说 | 精品久久久久久久久久 | 久久视频这里只有精品 | 五月激情综合婷婷 | 国产免码va在线观看免费 | 欧美激情视频三区 | 日日躁天天躁 | 久草视频在线资源 | 中文字幕在线观看第一区 | jizz欧美性9 国产一区高清在线观看 | 国产精品成人一区二区 | 国产精品theporn | 国产日韩欧美在线看 | 精品免费视频. | 97福利在线| 99看视频在线观看 | a一片一级 | 不卡视频国产 | 欧美日韩国产一区二区三区 | 午夜免费福利片 | 欧美精品乱码久久久久 | 国产精品一区在线观看 | 国产精品久久久久永久免费看 | av亚洲产国偷v产偷v自拍小说 | 亚洲国产一区av | 日韩激情免费视频 | 91精品国产网站 | a视频在线看| 麻豆国产精品va在线观看不卡 | 亚洲精品在线免费观看视频 | 免费日韩在线 | 国产黄大片 | 久久久久国产精品视频 | 亚洲精品综合久久 | 国产美女网站视频 | 国产福利资源 | 成年人国产视频 | 久草视频2 | 干天天 | 激情五月五月婷婷 | 欧美日韩国产三级 | 美女视频一区二区 | 人人澡澡人人 | 黄色小说免费在线观看 | 天天操天天是 | 97国产精品久久 | 色婷婷视频在线 | 中国黄色一级大片 | 一级精品视频在线观看宜春院 | 婷婷久久综合九色综合 | 欧洲亚洲激情 | 国产亚洲精品中文字幕 | 日韩精品在线一区 | av成人免费在线观看 | 日韩黄色免费电影 | 婷婷色六月天 | 亚洲精品在线观看视频 | 日韩一区二区三区高清免费看看 | 日本精品在线看 | 免费69视频 | 久久久99精品免费观看乱色 | 在线免费视 | 在线观看视频在线观看 | 国产爽视频| 国内视频一区二区 | 国产高清视频网 | 黄色小视频在线观看免费 | 美女久久久 | 国产五月色婷婷六月丁香视频 | 91精选在线| 日本精品一区二区三区在线观看 | 超碰99在线 | www黄免费| 成人网在线免费视频 | 九草视频在线 | 欧美精品乱码久久久久久按摩 | 国产第一页在线播放 | 久久国产亚洲视频 | 日韩精品高清视频 | 国产片网站 | 不卡中文字幕在线 | 欧美性高跟鞋xxxxhd | 国产一级二级三级在线观看 | 日本视频久久久 | 色多多视频在线 | 午夜三级理论 | 国产精品综合久久久久久 | 免费a v在线| 日韩激情视频 | 国产精久久久久久妇女av | 中文字幕国产在线 | 日韩黄色中文字幕 | 涩涩网站在线看 | 久久黄色免费视频 | 久久网站免费 | 最新超碰在线 | 一区二区视频电影在线观看 | 日韩欧美视频在线观看免费 | 成人免费观看网址 | 成人毛片100免费观看 | 人人要人人澡人人爽人人dvd | 久久国产美女视频 | 免费视频一二三区 | av电影在线播放 | 国产精品99久久久久久小说 | 国产精品99久久久久久武松影视 | 国产v亚洲v| 亚洲a资源| 国产高清亚洲 | 久久国产91 | 探花视频免费观看 | 在线免费观看的av网站 | 精品一区av| 五月天激情综合网 | 欧美小视频在线 | 色五月激情五月 | 亚洲狠狠操 | 日本aaaa级毛片在线看 | 精品免费视频123区 午夜久久成人 | 亚洲精品在线看 | 日p在线观看 | 亚洲无线视频 | 中文字幕av在线免费 | 免费看的黄色片 | 久久tv视频 | 91视频链接 | 在线亚洲小视频 | 中文字幕五区 | 91pony九色丨交换 | 精品亚洲国产视频 | av黄色大片 | 在线观av | 91精品视频在线观看免费 | 精品国内 | 精品国产日本 | 久久久久久高潮国产精品视 | 亚洲色图av | 中文字幕亚洲在线观看 | 欧美国产在线看 | 中文不卡视频在线 | 久热免费在线 | 99精品国产一区二区 | 少妇性色午夜淫片aaaze | 色狠狠一区二区 | 国语自产偷拍精品视频偷 | 一区二区三区在线观看中文字幕 | av日韩不卡 | 六月色丁 | 91精品国产电影 | 国产亚洲精品久久久久久网站 | 国产日产精品一区二区三区四区的观看方式 | 国产蜜臀av| 在线观看免费高清视频大全追剧 | 婷婷久久亚洲 | 久久色视频 | av日韩在线网站 | 在线播放国产一区二区三区 | 久久婷婷国产色一区二区三区 | 精品一区欧美 | 亚洲高清av在线 | 久久久久久久亚洲精品 | 国产精品96久久久久久吹潮 | 五月激情五月激情 | 亚洲国产精品激情在线观看 | 国产综合婷婷 | 日本激情视频中文字幕 | 97超级碰碰碰碰久久久久 | 亚洲成av人片在线观看www | 九9热这里真品2 | 干av在线 | 欧美一二三区播放 | 久久a级片 | 精品亚洲va在线va天堂资源站 | 久久久亚洲电影 | 99国内精品久久久久久久 | 一二区av | 亚洲欧美日韩精品久久奇米一区 | 精品久久久久久亚洲综合网站 | 国产免费一区二区三区最新6 | 久久与婷婷 | 五月综合久久 | 欧美淫aaa免费观看 日韩激情免费视频 | 91禁在线看 | 黄色视屏在线免费观看 | 免费看三级 | 黄色片视频免费 | 午夜精品久久久久久久99热影院 | 天天色天天上天天操 | 亚洲激情久久 | 999免费视频 | 日韩专区 在线 |