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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

综合教程

MyBatis Plus

發(fā)布時(shí)間:2024/1/4 综合教程 32 生活家
生活随笔 收集整理的這篇文章主要介紹了 MyBatis Plus 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.引入

1.簡(jiǎn)介

??MyBatis-Plus(簡(jiǎn)稱(chēng) MP),是一個(gè) MyBatis 的增強(qiáng)工具包,只做增強(qiáng)不做改變. 為簡(jiǎn)化開(kāi)發(fā)工作、提高生產(chǎn)率而生,愿景是成為 Mybatis 最好的搭檔,就像 魂斗羅 中的 1P、2P,基友搭配,效率
翻倍,基于mybatis

2.相關(guān)文檔

??官方地址:

http://mp.baomidou.com

https://mybatis.plus/

??代碼發(fā)布地址:Github: https://github.com/baomidou/mybatis-plusGitee: https://gitee.com/baomidou/mybatis-plus

??文檔發(fā)布地址:http://mp.baomidou.com/#/?id=簡(jiǎn)??%

3.前置知識(shí)

Mybatis、Spring、Maven

2.環(huán)境搭建

2.1 準(zhǔn)備

表結(jié)構(gòu)

-- 創(chuàng)建庫(kù)
CREATE DATABASE mp;
-- 使用庫(kù)
USE mp;
-- 創(chuàng)建表
CREATE TABLE tbl_employee(
 id INT(11) PRIMARY KEY AUTO_INCREMENT,
 last_name VARCHAR(50),
 email VARCHAR(50),
 gender CHAR(1),
 age int
);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom','tom@zhenqk.com',1,18);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tony','jerry@zhenqk.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','black@zhenqk.com',1,20);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','white@zhenqk.com',0,30);

用包裝類(lèi)的原因: 每個(gè)基本類(lèi)型的默認(rèn)值不一樣

domain

@Setter
@Getter
@ToString
public class Employee implements Serializable {
    private Integer id;
    private String lastNamprivate;
    String email;
    private Integer gender;
    private Integer age;
}

pom.xml

  <dependencies>
        <!-- mp依賴(lài)
                       mybatisPlus 會(huì)自動(dòng)的維護(hù)Mybatis 以及MyBatis-spring相關(guān)的依賴(lài)
                   -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.4.0</version>
        </dependency>

        <!--junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
        </dependency>
        <!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
    </dependencies>

2.mybatis 的整合

log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <!-- 日志輸出到控制臺(tái) -->
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <!-- 日志輸出格式 -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%p][%d{yyyy-MM-dd HH:mm:ss SSS}][%c]-[%m]%n"/>
        </layout>

        <!--過(guò)濾器設(shè)置輸出的級(jí)別-->
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <!-- 設(shè)置日志輸出的最小級(jí)別 -->
            <param name="levelMin" value="INFO"/>
            <!-- 設(shè)置日志輸出的最大級(jí)別 -->
            <param name="levelMax" value="ERROR"/>
        </filter>
    </appender>


    <!-- 輸出日志到文件 -->
    <appender name="fileAppender" class="org.apache.log4j.FileAppender">
        <!-- 輸出文件全路徑名-->
        <param name="File" value="/data/applogs/own/fileAppender.log"/>
        <!--是否在已存在的文件追加寫(xiě):默認(rèn)時(shí)true,若為false則每次啟動(dòng)都會(huì)刪除并重新新建文件-->
        <param name="Append" value="false"/>
        <param name="Threshold" value="INFO"/>
        <!--是否啟用緩存,默認(rèn)false-->
        <param name="BufferedIO" value="false"/>
        <!--緩存大小,依賴(lài)上一個(gè)參數(shù)(bufferedIO), 默認(rèn)緩存大小8K  -->
        <param name="BufferSize" value="512"/>
        <!-- 日志輸出格式 -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%p][%d{yyyy-MM-dd HH:mm:ss SSS}][%c]-[%m]%n"/>
        </layout>
    </appender>


    <!-- 輸出日志到文件,當(dāng)文件大小達(dá)到一定閾值時(shí),自動(dòng)備份 -->
    <!-- FileAppender子類(lèi) -->
    <appender name="rollingAppender" class="org.apache.log4j.RollingFileAppender">
        <!-- 日志文件全路徑名 -->
        <param name="File" value="/data/applogs/RollingFileAppender.log" />
        <!--是否在已存在的文件追加寫(xiě):默認(rèn)時(shí)true,若為false則每次啟動(dòng)都會(huì)刪除并重新新建文件-->
        <param name="Append" value="true" />
        <!-- 保存?zhèn)浞萑罩镜淖畲髠€(gè)數(shù),默認(rèn)值是:1  -->
        <param name="MaxBackupIndex" value="10" />
        <!-- 設(shè)置當(dāng)日志文件達(dá)到此閾值的時(shí)候自動(dòng)回滾,單位可以是KB,MB,GB,默認(rèn)單位是KB,默認(rèn)值是:10MB -->
        <param name="MaxFileSize" value="10KB" />
        <!-- 設(shè)置日志輸出的樣式 -->`
        <layout class="org.apache.log4j.PatternLayout">
            <!-- 日志輸出格式 -->
            <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%-5p] [method:%l]%n%m%n%n" />
        </layout>
    </appender>


    <!-- 日志輸出到文件,可以配置多久產(chǎn)生一個(gè)新的日志信息文件 -->
    <appender name="dailyRollingAppender" class="org.apache.log4j.DailyRollingFileAppender">
        <!-- 文件文件全路徑名 -->
        <param name="File" value="/data/applogs/own/dailyRollingAppender.log"/>
        <param name="Append" value="true" />
        <!-- 設(shè)置日志備份頻率,默認(rèn):為每天一個(gè)日志文件 -->
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />

        <!--每分鐘一個(gè)備份-->
        <!--<param name="DatePattern" value="'.'yyyy-MM-dd-HH-mm'.log'" />-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%p][%d{HH:mm:ss SSS}][%c]-[%m]%n"/>
        </layout>
    </appender>



    <!--
        1. 指定logger的設(shè)置,additivity是否遵循缺省的繼承機(jī)制
        2. 當(dāng)additivity="false"時(shí),root中的配置就失靈了,不遵循缺省的繼承機(jī)制
        3. 代碼中使用Logger.getLogger("logTest")獲得此輸出器,且不會(huì)使用根輸出器
    -->
    <logger name="logTest" additivity="false">
        <level value ="INFO"/>
        <appender-ref ref="dailyRollingAppender"/>
    </logger>


    <!-- 根logger的設(shè)置,若代碼中未找到指定的logger,則會(huì)根據(jù)繼承機(jī)制,使用根logger-->
    <root>
        <appender-ref ref="console"/>
        <appender-ref ref="fileAppender"/>
        <appender-ref ref="rollingAppender"/>
        <appender-ref ref="dailyRollingAppender"/>
    </root>

</log4j:configuration>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

</configuration>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
       xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring
        http://mybatis.org/schema/mybatis-spring-1.2.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    <!-- 數(shù)據(jù)源 -->

    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${druid.driver}"></property>
        <property name="url" value="${druid.url}"></property>
        <property name="username" value="${druid.username}"></property>
        <property name="password" value="${druid.password}"></property>
    </bean>
    <!-- 事務(wù)管理器 -->
    <bean id="dataSourceTransactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 基于注解的事務(wù)管理 -->
    <tx:annotation-driven
            transaction-manager="dataSourceTransactionManager"/>
    <!-- 配置 SqlSessionFactoryBean -->
    <bean id="sqlSessionFactoryBean"
          class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 數(shù)據(jù)源 -->
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation"

                  value="classpath:mybatis-config.xml"></property>
        <!-- 別名處理 -->
        <property name="typeAliasesPackage"
                  value="cn.ccut.domain"></property>
    </bean>
    <!--
    配置 mybatis 掃描 mapper 接口的路徑
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage"
                  value="cn.ccut.mapper"></property>
    </bean>
</beans>

mybatisPlus 適配 更改這里, 由原來(lái)的 SqlSessionFactoryBean改成MybatisSqlSessionFactoryBean

<!--  配置SqlSessionFactoryBean
        Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
        MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
     -->
     
    <bean id="sqlSessionFactoryBean"
          class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

3.通用增刪改實(shí)現(xiàn)

0.準(zhǔn)備

1.繼承接口

基于Mybatis: 在Mapper接口中編寫(xiě)CRUD相關(guān)的方法 提供Mapper接口所對(duì)應(yīng)的SQL映射文件 以及 方法對(duì)應(yīng)的SQL語(yǔ)句.

基于MP: 讓XxxMapper接口繼承 BaseMapper接口即可.

BaseMapper : 泛型指定的就是當(dāng)前Mapper接口所操作的實(shí)體類(lèi)類(lèi)型

public interface EmployeeMapper extends BaseMapper<Employee> { }

2.BaseMapper 已經(jīng)定義了各式各樣的方法不用我們?nèi)ザx

1.insert方法

1.指定主鍵策略

 @TableId:
	 * 	 value: 指定表中的主鍵列的列名, 如果實(shí)體屬性名與列名一致,可以省略不指定. 
	 *   type: 指定主鍵策略. 

   @TableId(value="id" , type =IdType.AUTO)
	private Integer id ;   //  int 

2.指定表名注解

 * MybatisPlus會(huì)默認(rèn)使用實(shí)體類(lèi)的類(lèi)名到數(shù)據(jù)中找對(duì)應(yīng)的表. 

@TableName(value="tbl_employee")
public class Employee {

3.test

@Test
    public void testInsert() throws SQLException {
        //初始化Employee對(duì)象
        Employee employee  = new Employee();
        employee.setLastName("MP");
        employee.setEmail("mp@zhenqk.com");
        employee.setGender(1);
        employee.setAge(22);
        // employee.setSalary(20000.0);
        int a=employeeMapper.insert(employee);
    }

4.再分析

屬性名是lastName ,而數(shù)據(jù)庫(kù)是last_name(駝峰命名法) ,原因是因?yàn)槿帜J(rèn)配置是true

5.如何配置 主鍵策略和表名

通過(guò)全局配置整個(gè)都起作用,若通過(guò)注解只能在當(dāng)前類(lèi)有作用
需要將配置作用在mybatis-session (注冊(cè))

spring配置文件

	<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
		<!-- 數(shù)據(jù)源 -->
		<property name="dataSource" ref="dataSource"></property>
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
		<!-- 別名處理 -->
		<property name="typeAliasesPackage" value="com.atguigu.mp.beans"></property>		
// 		-------------------------------------------------
		<!-- 注入全局MP策略配置 -->
		<property name="globalConfig" ref="globalConfiguration"></property>
	</bean>
	
	<!-- 定義MybatisPlus的全局策略配置-->
	<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
		<!-- 在2.3版本以后,dbColumnUnderline 默認(rèn)值就是true  駝峰  -->
		<property name="dbColumnUnderline" value="true"></property>
		
		<!-- 全局的主鍵策略  實(shí)體類(lèi)中可以刪除了 -->
		<property name="idType" value="0"></property>
		
		<!-- 全局的表前綴策略配置 實(shí)體類(lèi)中可以刪除了 -->
		<property name="tablePrefix" value="tbl_"></property>
	</bean>
        
  // ------------   

6.@TableField

指定別名

當(dāng)數(shù)據(jù)庫(kù)不存在此字段,選擇性過(guò)濾插入 就是舍棄掉

@TableField(exist=false)

7.插入獲取當(dāng)前數(shù)據(jù)的主鍵值

8.insertAllColumn方法 -- 全字段的插入,

默認(rèn)數(shù)據(jù)為空就不插入

// insert方法在插入時(shí), 會(huì)根據(jù)實(shí)體類(lèi)的每個(gè)屬性進(jìn)行非空判斷,只有非空的屬性對(duì)應(yīng)的字段才會(huì)出現(xiàn)到SQL語(yǔ)句中
//insertAllColumn方法在插入時(shí), 不管屬性是否非空, 屬性所對(duì)應(yīng)的字段都會(huì)出現(xiàn)到SQL語(yǔ)句中. 

2.更新操作

1.updateById

會(huì)做非空判斷,選擇性更新操作

2.沒(méi)有賦值就為null(在全賦值情況下) updateAllColumnById

	//初始化修改對(duì)象
		Employee employee = new Employee();
		employee.setId(7);
		employee.setLastName("小澤老師");
		employee.setEmail("xz@sina.com");
		employee.setGender(0);
Integer result = employeeMapper.updateAllColumnById(employee);
		
System.out.println("result: " + result );

沒(méi)有給值就為ull,為每一個(gè)字段賦值

3.通用的查詢(xún)操作

1.selectById(Serialize id)

2.通過(guò)多列進(jìn)行查詢(xún) id+lastName selectOne |

注意: 最多只能查詢(xún)一條,不能查詢(xún)多條(當(dāng)條件相同的列有多條的時(shí)候)

3.通過(guò)多個(gè)id 進(jìn)行查詢(xún) in () ===mybatis foreach

4.通過(guò)map封裝條件查詢(xún)----selectByMap

注意:是數(shù)據(jù)庫(kù)類(lèi)名

分頁(yè)查詢(xún)--selectPage

wapper 條件構(gòu)造器

注意:當(dāng)前頁(yè)碼,每頁(yè)顯示的條數(shù),不是通過(guò)limit

是一種內(nèi)存分頁(yè) RowBound,物理分頁(yè)借助分頁(yè)插件

不推薦使用

4.通用刪除

1.根據(jù)id 進(jìn)行刪除--- deleteById

2.根據(jù)條件進(jìn)行刪除-----deleteByMap

where 進(jìn)行可拼接

3.批量刪除 deleteBatchIds

底層 in

5.MP 啟動(dòng)自動(dòng)注入SQL原理分析

??啟動(dòng)的時(shí)候就注入進(jìn)來(lái)了,繼承了BaseMapper 中提供的CRUB方法,方法來(lái)源于BaseMapper有方法就必須有SQL,因?yàn)镸abatis最終還是需要通過(guò)SQL語(yǔ)句操作實(shí)現(xiàn),要熟悉:MyBatis 執(zhí)行流程, 透過(guò)現(xiàn)象看本質(zhì)

Configuration 全局配置--->MappedStatement


?AutoSqlInjector

?SqlMethod 枚舉對(duì)象 MP支持的SQL方法

?TableInfo 數(shù)據(jù)庫(kù)表放射信息,可以獲取數(shù)據(jù)庫(kù)表的相關(guān)信息

?SqlSource :sql 處理對(duì)象

?MapperbuilderAssistant 用于緩存sql參數(shù) 查詢(xún)方法的結(jié)果集處理等

? 通過(guò)MapperbuilderAssistant 將每一個(gè)MappedStatement添加到Configuration中

?MappedStatements

共17 種方法

wrapper 實(shí)體對(duì)象封裝操作類(lèi)

4.條件構(gòu)造器

1.EntityWrapper 簡(jiǎn)介

Mybatis-Plus 通過(guò) EntityWrapper(簡(jiǎn)稱(chēng) EW,MP 封裝的一個(gè)查詢(xún)條件構(gòu)造器)或者Condition(與 EW 類(lèi)似) 來(lái)讓用戶(hù)自由的構(gòu)建查詢(xún)條件,簡(jiǎn)單便捷,沒(méi)有額外的負(fù)擔(dān),
能夠有效提高開(kāi)發(fā)效率

實(shí)體包裝器,主要用于處理 sql 拼接,排序,實(shí)體參數(shù)查詢(xún)等

注意: 使用的是數(shù)據(jù)庫(kù)字段,不是 Java 屬性!

條件參數(shù)的說(shuō)明

用的最多是查詢(xún)操作

2.需求

??現(xiàn)有一個(gè)需求,我們需要分頁(yè)查詢(xún) tbl_employee 表中,年齡在 18~50 之間性別為男且姓名為 xx 的所有用戶(hù),這時(shí)候我們?cè)撊绾螌?shí)現(xiàn)上述需求呢?
??MyBatis : 需要在 SQL 映射文件中編寫(xiě)帶條件查詢(xún)的 SQL,并基于 PageHelper 插件完成分頁(yè). 實(shí)現(xiàn)以上一個(gè)簡(jiǎn)單的需求,往往需要我們做很多重復(fù)單調(diào)的工作。普通的 Mapper能夠解決這類(lèi)痛點(diǎn)嗎?
??MP: 依舊不用編寫(xiě) SQL 語(yǔ)句, MP 提供了功能強(qiáng)大的條件構(gòu)造器 EntityWrapper

利用條件構(gòu)造器查詢(xún) 		
//我們需要分頁(yè)查詢(xún)tbl_employee表中,年齡在18~50之間且性別為男且姓名為T(mén)om的所有用戶(hù)
		//  是數(shù)據(jù)庫(kù)字段名
		List<Employee> emps =employeeMapper.selectPage(new Page<Employee>(1, 2),
				new EntityWrapper<Employee>()
				.between("age", 18, 50)
				.eq("gender", 1)
				.eq("last_name", "Tom")
			);
	System.out.println(emps);

3. 帶條件的查詢(xún)selectList方法

小語(yǔ)法

or() 或者 關(guān)系 前面是一起的,后面是一起
orNew()

	// 查詢(xún)tbl_employee表中, 性別為女并且名字中帶有"老師" 或者  郵箱中帶有"a"
		
	List<Employee> emps = employeeMapper.selectList(
			new EntityWrapper<Employee>()
			.eq("gender", 0)
				.like("last_name", "老師")
				//.or()    
        // SQL: (gender = ? AND last_name LIKE ? OR email LIKE ?)    
			.orNew()  
        // SQL: (gender = ? AND last_name LIKE ?) OR (email LIKE ?)   or New 另起一個(gè)括號(hào)
			.like("email", "a")
			);
	System.out.println(emps);

4. 帶條件的修改

??update

把tom 修改成蒼老師


		Employee employee = new Employee();
		employee.setLastName("蒼老師");
		employee.setEmail("cls@sina.com");
		employee.setGender(0);
		
		employeeMapper.update(employee, 
					new EntityWrapper<Employee>()
					.eq("last_name", "Tom")
					.eq("age", 44)
					);

5.帶條件的刪除

employeeMapper.delete(
					new EntityWrapper<Employee>()
					.eq("last_name", "Tom")
					.eq("age", 22)
				);

6.其他常用方法

orderby 默認(rèn)是升序列

orderSesc 降序

		// 查詢(xún)性別為女的, 根據(jù)age進(jìn)行排序(asc/desc), 簡(jiǎn)單分頁(yè)
	List<Employee> emps  = employeeMapper.selectList(
			new EntityWrapper<Employee>()
			.eq("gender", 0)
			.orderBy("age")
			//.orderDesc(Arrays.asList(new String [] {"age"}))
			.last("desc limit 1,3")
		);

last 具有SQL注入風(fēng)險(xiǎn)

7.使用Condition的方式打開(kāi)如上需求


		List<Employee > emps = employeeMapper.selectPage(
							new Page<Employee>(1,2), 
							Condition.create()  // 獲取方式一樣 new EntityWrapper<Employee>() 
							.between("age", 18, 50)
							.eq("gender", "1")
							.eq("last_name", "Tom")
							
							);
		
		System.out.println(emps);	

mp 條件構(gòu)造器 Condition // EntityWrapper

逆向工程qbc

5.ActiveRecord 活動(dòng)記錄

1.介紹

? Active Record(活動(dòng)記錄),是一種領(lǐng)域模型模式,特點(diǎn)是一個(gè)模型類(lèi)對(duì)應(yīng)關(guān)系型數(shù)據(jù)庫(kù)中的
一個(gè)表,而模型類(lèi)的一個(gè)實(shí)例對(duì)應(yīng)表中的一行記錄。
? ActiveRecord 一直廣受動(dòng)態(tài)語(yǔ)言( PHP 、 Ruby 等)的喜愛(ài),而 Java 作為準(zhǔn)靜態(tài)語(yǔ)言,
對(duì)于 ActiveRecord 往往只能感嘆其優(yōu)雅,所以 MP 也在 AR 道路上進(jìn)行了一定的探索

概念慢慢理解 慢慢會(huì)用就可以了

2.開(kāi)啟AR模式

僅僅需要讓實(shí)體類(lèi)繼承 Model 類(lèi)且實(shí)現(xiàn)主鍵指定方法,即可開(kāi)啟 AR 之旅

@TableName("tbl_employee")
public class Employee extends Model<Employee>{
// .. fields
// .. getter and setter
@Override
protected Serializable pkVal() {
return this.id;
}

3.基本CRUB

1. 插入操作

對(duì)象進(jìn)行操作 自己插入自己

/**
	 * AR  插入操作
	 */
	@Test
	public void  testARInsert() {
		Employee employee = new Employee();
		employee.setLastName("王老師");
		employee.setEmail("king@ccut.com");
		employee.setGender(1);
		employee.setAge(35);
		
		boolean result = employee.insert();
		System.out.println("result:" +result );
	}

2.修改操作


	/**
	 * AR 修改操作
	 */
	@Test
	public void testARUpdate() {
		Employee employee = new Employee();
		employee.setId(20);
		employee.setLastName("王大師");
		employee.setEmail("king@ccut.com");
		employee.setGender(1);
		employee.setAge(36);
		
		
		boolean result = employee.updateById();
		System.out.println("result:" +result );
		
	}

3.AR的查詢(xún)操作

1.selectById方法 and selectById(Serializable id)

第一種方式:

	Employee employee = new Employee();	
    Employee result = employee.selectById(14);
	System.out.println(result );

第二種方式:

Employee employee = new Employee();
		
		employee.setId(14);
	Employee result = employee.selectById();
	System.out.println(result );

2.selectAll()

	Employee employee = new Employee();
	List<Employee> emps = employee.selectAll();
  	System.out.println(emps);

3.selectList and selectCount 方法

		Employee employee = new Employee();
		
	List<Employee > emps= 
				employee.selectList(new EntityWrapper<Employee>().like("last_name", "老師"));
		System.out.println(emps);
Employee employee = new Employee();
Integer result = employee.selectCount(new EntityWrapper<Employee>().eq("gender", 0));
// 全表統(tǒng)計(jì) 就不要加條件了 
		System.out.println("result: " +result );

4. 刪除操作

1.注意: 刪除不存在的數(shù)據(jù) 邏輯上也是屬于成功的.

2.deleteById(id) 和deleteById()

第一種方式

Employee employee = new Employee();
boolean result = employee.deleteById(2);

第二種方式

刪除不存在在邏輯上也是成功的 
Employee employee = new Employee();
		employee.setId(2);
		boolean result = employee.deleteById();
	System.out.println("result:" +result );

3.delete(wrapper)

boolean result = employee.delete(new EntityWrapper<Employee>().like("last_name", "小"));
		System.out.println(result );

4.分頁(yè)的復(fù)雜操作

@Test
	public void  testARPage() {
		
		Employee employee = new Employee();
		
		Page<Employee> page = employee.selectPage(new Page<>(1, 1), 
				new EntityWrapper<Employee>().like("last_name", "老"));
		List<Employee> emps = page.getRecords();  //獲取查詢(xún)數(shù)據(jù)庫(kù) 查詢(xún)回來(lái)的記錄返回
		System.out.println(emps);
	}

返回的是一個(gè)page 對(duì)象,更加的方便使用分頁(yè)信息

5.小結(jié):

AR 模式提供了一種更加便捷的方式實(shí)現(xiàn) CRUD 操作,其本質(zhì)還是調(diào)用的 Mybatis 對(duì)
應(yīng)的方法,類(lèi)似于語(yǔ)法糖
語(yǔ)法糖是指計(jì)算機(jī)語(yǔ)言中添加的某種語(yǔ)法,這種語(yǔ)法對(duì)原本語(yǔ)言的功能并沒(méi)有影響.可以更方便開(kāi)發(fā)者使用,可以避免出錯(cuò)的機(jī)會(huì),讓程序可讀性更好.
到此,我們簡(jiǎn)單領(lǐng)略了 Mybatis-Plus 的魅力與高效率,值得注意的一點(diǎn)是:我們提供了強(qiáng)大的代碼生成器,可以快速生成各類(lèi)代碼,真正的做到了即開(kāi)即用

6.代碼生成器

通過(guò)java代碼來(lái)實(shí)現(xiàn)的

逆向軟件通過(guò) xml而配置

1.MP與MBG的簡(jiǎn)單比較

??1) MP 提供了大量的自定義設(shè)置,生成的代碼完全能夠滿(mǎn)足各類(lèi)型的需求
??2) MP 的代碼生成器 和 Mybatis MBG 代碼生成器:MP 的代碼生成器都是基于 java 代碼來(lái)生成。MBG 基于 xml 文件進(jìn)行代碼生成
?MyBatis 的代碼生成器可生成: 實(shí)體類(lèi)、Mapper 接口、Mapper 映射文件
?MP 的代碼生成器可生成: 實(shí)體類(lèi)(可以選擇是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 層、Controller 層.
??3) 表及字段命名策略選擇
??在 MP 中,我們建議數(shù)據(jù)庫(kù)表名 和 表字段名采用駝峰命名方式, 如果采用下劃線命名方式 請(qǐng)開(kāi)啟全局下劃線開(kāi)關(guān),如果表名字段名命名方式不一致請(qǐng)注解指定,我們建議最好保持一致。
??這么做的原因是為了避免在對(duì)應(yīng)實(shí)體類(lèi)時(shí)產(chǎn)生的性能損耗,這樣字段不用做映射就能直接和實(shí)體類(lèi)對(duì)應(yīng)。當(dāng)然如果項(xiàng)目里不用考慮這點(diǎn)性能損耗,那么你采用下滑線也是沒(méi)問(wèn)題的,只需要在生成代碼時(shí)配置 ; dbColumnUnderline 屬性就可以

2. 準(zhǔn)備

導(dǎo)入代碼產(chǎn)生器依賴(lài)

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.0</version>
</dependency>

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.2</version>
</dependency>

加入日志 sl4f 日志輸出依賴(lài)

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>

3. GlobalConfig全局配置參數(shù)

1.全局配置

//1. 全局配置
		GlobalConfig config = new GlobalConfig();
		config.setActiveRecord(true) // 是否支持AR模式
			  .setAuthor("weiyunhui") // 作者
			  .setOutputDir("D:\workspace_mp\mp03\src\main\java") // 生成路徑
			  .setFileOverride(true)  // 文件覆蓋
			  .setIdType(IdType.AUTO) // 主鍵策略
			  .setServiceName("%sService")  // 設(shè)置生成的service接口的名字的首字母是否為I
			  					   // IEmployeeService
 			  .setBaseResultMap(true)
 			  .setBaseColumnList(true);

2.數(shù)據(jù)源配置

//2. 數(shù)據(jù)源配置
		DataSourceConfig  dsConfig  = new DataSourceConfig();
		dsConfig.setDbType(DbType.MYSQL)  // 設(shè)置數(shù)據(jù)庫(kù)類(lèi)型
				.setDriverName("com.mysql.jdbc.Driver")
				.setUrl("jdbc:mysql://localhost:3306/mp")
				.setUsername("root")
				.setPassword("1234");

3.策略配置

原來(lái)在配置文件

     	StrategyConfig stConfig = new StrategyConfig();
		stConfig.setCapitalMode(true) //全局大寫(xiě)命名
				.setDbColumnUnderline(true)  // 指定表名 字段名是否使用下劃線
				.setNaming(NamingStrategy.underline_to_camel) // 數(shù)據(jù)庫(kù)表映射到實(shí)體的命名策略
				.setTablePrefix("tbl_")
				.setInclude("tbl_employee");  // 生成的表 所使用的表

4.包名策略設(shè)置

//4. 包名策略配置 
		PackageConfig pkConfig = new PackageConfig();
		pkConfig.setParent("com.atguigu.mp")
				.setMapper("mapper")
				.setService("service")
				.setController("controller")
				.setEntity("beans")
				.setXml("mapper");

//  .setBaseResultMap(true)    xml
 //			  .setBaseColumnList(true);

5.整合配置

//5. 整合配置
		AutoGenerator  ag = new AutoGenerator();
		
		ag.setGlobalConfig(config)
		  .setDataSource(dsConfig)
		  .setStrategy(stConfig)
		  .setPackageInfo(pkConfig);
		
		//6. 執(zhí)行
		ag.execute();

導(dǎo)入包 spring-webmvc

@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
	
	//不用再進(jìn)行mapper的注入.
	
	/**
	 * EmployeeServiceImpl  繼承了ServiceImpl
	 * 1. 在ServiceImpl中已經(jīng)完成Mapper對(duì)象的注入,直接在EmployeeServiceImpl中進(jìn)行使用
	 * 2. 在ServiceImpl中也幫我們提供了常用的CRUD方法, 基本的一些CRUD方法在Service中不需要我們自己定義.
	 * 
	 * 
	 */
}

Controller

@Controller
@RequestMapping("/employee")
public class EmployeeController {
	
	@Autowired
	private EmployeeService employeeService; 
	
//	public String  login() {
//		
//		//employeeService.select
//	}
}

更多詳情信息可以看文檔

7.插件擴(kuò)展

1.介紹

??1) 插件機(jī)制: Mybatis 通過(guò)插件(Interceptor) 可以做到攔截四大對(duì)象相關(guān)方法的執(zhí)行,根據(jù)需求,完 成相關(guān)數(shù)據(jù)的動(dòng)態(tài)改變。 Executor StatementHandler ParameterHandler ResultSetHandler

?? 2) 插件原理 四大對(duì)象的每個(gè)對(duì)象在創(chuàng)建時(shí),都會(huì)執(zhí)行 interceptorChain.pluginAll(),會(huì)經(jīng)過(guò)每個(gè)插 件對(duì)象的 plugin()方法,目的是為當(dāng)前的四大對(duì)象創(chuàng)建代理。代理對(duì)象就可以攔截到四 大對(duì)象相關(guān)方法的執(zhí)行,因?yàn)橐獔?zhí)行四大對(duì)象的方法需要經(jīng)過(guò)代理.

2.分頁(yè)插件

??物理分頁(yè)

com.baomidou.mybatisplus.plugins.PaginationInterceptor

??注冊(cè)有兩種方式

1.mybaiss 配置文件

<configuration>
	<!-- <plugins>
		<plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></plugin>
	</plugins> -->

</configuration>

?2.放在spring中 數(shù)組可以用list

	<!-- 插件注冊(cè) -->
		<property name="plugins">
			<list>
				<!-- 注冊(cè)分頁(yè)插件 -->
				<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
		</list>
			
		</property>
	</bean>

?測(cè)試方法

	ApplicationContext ctx  = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	EmployeeMapper employeeMapper = ctx.getBean("employeeMapper",EmployeeMapper.class);

Page<Employee> page = new Page<>(1,1);
		List<Employee > emps = 
				employeeMapper.selectPage(page, null);
		System.out.println(emps);

?把mapper 中開(kāi)啟二級(jí)緩存去掉

注冊(cè)分頁(yè)插件后,Page對(duì)象的使用

@Test
	public void testPage() {
		
		Page<Employee> page = new Page<>(1,1);
		
		List<Employee > emps = 
				employeeMapper.selectPage(page, null);
		System.out.println(emps);
		
		
		System.out.println("===============獲取分頁(yè)相關(guān)的一些信息======================");
		
		System.out.println("總條數(shù):" +page.getTotal());
		System.out.println("當(dāng)前頁(yè)碼: "+  page.getCurrent());
		System.out.println("總頁(yè)碼:" + page.getPages());
		System.out.println("每頁(yè)顯示的條數(shù):" + page.getSize());
		System.out.println("是否有上一頁(yè): " + page.hasPrevious());
		System.out.println("是否有下一頁(yè): " + page.hasNext());
		
		//將查詢(xún)的結(jié)果封裝到page對(duì)象中
		page.setRecords(emps);
		
		
	}

3.執(zhí)行分析插件(不建議生產(chǎn)環(huán)境用)

1) com.baomidou.mybatisplus.plugins.SqlExplainInterceptor
2) SQL 執(zhí)行分析攔截器,只支持 MySQL5.6.3 以上版本
3) 該插件的作用是分析 DELETE UPDATE 語(yǔ)句,防止小白
或者惡意進(jìn)行 DELETE UPDATE 全表操作
4) 只建議在開(kāi)發(fā)環(huán)境中使用,不建議在生產(chǎn)環(huán)境使用
5) 在插件的底層 通過(guò) SQL 語(yǔ)句分析命令:Explain 分析當(dāng)前的 SQL 語(yǔ)句,
根據(jù)結(jié)果集中的 Extra 列來(lái)斷定當(dāng)前是否全表操作。

插件注冊(cè)


<!-- 插件注冊(cè) -->
		<property name="plugins">
			<list>
				<!-- 注冊(cè)分頁(yè)插件 -->
				<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
				
				<!-- 注冊(cè)執(zhí)行分析插件   發(fā)現(xiàn)對(duì)全表的操作就停止  -->
				<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
					<property name="stopProceed" value="true"></property>
				</bean>

測(cè)試

/**
	 * 測(cè)試SQL執(zhí)行分析插件  發(fā)現(xiàn)全表刪除操作 就停止
	 */
	@Test
	public void testSQLExplain() {
		
		employeeMapper.delete(null);  // 全表刪除
	}

explain sql分析

4. 性能分析插件

?1) com.baomidou.mybatisplus.plugins.PerformanceInterceptor

?2) 性能分析攔截器,用于輸出每條 SQL 語(yǔ)句及其執(zhí)行時(shí)間

?3) SQL 性能執(zhí)行分析,開(kāi)發(fā)環(huán)境使用,超過(guò)指定時(shí)間,停止運(yùn)行。有助于發(fā)現(xiàn)問(wèn)題----測(cè)試可以用

注冊(cè)插件

	<!-- 注冊(cè)性能分析插件 -->
				<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"> 是否格式化sql語(yǔ)句
					<property name="format" value="true"></property>
					<!-- <property name="maxTime" value="5"></property> -->   每條sql語(yǔ)句執(zhí)行所消耗的時(shí)間
				</bean>

時(shí)間是 5毫秒

測(cè)試

/**
	 * 測(cè)試 性能分析插件
	 */
	@Test
	public void testPerformance() {
		Employee employee = new Employee();
		employee.setLastName("瑪利亞老師");
		employee.setEmail("mly@sina.com");
		employee.setGender("0");
		employee.setAge(22);
		employeeMapper.insert(employee);
	}


5.樂(lè)觀鎖插件

?1) com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor

?2) 如果想實(shí)現(xiàn)如下需求: 當(dāng)要更新一條記錄的時(shí)候,希望這條記錄沒(méi)有被別人更新

?3) 樂(lè)觀鎖的實(shí)現(xiàn)原理: 取出記錄時(shí),獲取當(dāng)前 version 2 更新時(shí),帶上這個(gè) version 2 執(zhí)行更新時(shí), set version = yourVersion+1 where version = yourVersion 如果 version 不對(duì),就更新失敗

?4) @Version 用于注解實(shí)體字段,必須要有。

domian

加上字段

? - 數(shù)據(jù)庫(kù)也要加上 version int 11

注冊(cè)樂(lè)觀鎖

	<!-- 基于注解的事務(wù)管理 -->
	<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
	
	
	<!--  配置SqlSessionFactoryBean 
		Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
		MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
	 -->
	<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
		<!-- 數(shù)據(jù)源 -->
		<property name="dataSource" ref="dataSource"></property>
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
		<!-- 別名處理 -->
		<property name="typeAliasesPackage" value="com.atguigu.mp.beans"></property>		
		
 		<!-- 注入全局MP策略配置 -->
		<property name="globalConfig" ref="globalConfiguration"></property>
		
		<!-- 插件注冊(cè) -->
		<property name="plugins">
			<list>
				<!-- 注冊(cè)分頁(yè)插件 -->
				<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
				
				<!-- 注冊(cè)執(zhí)行分析插件 -->
				<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
					<property name="stopProceed" value="true"></property>
				</bean>
				
				<!-- 注冊(cè)性能分析插件 -->
				<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
					<property name="format" value="true"></property>
					<!-- <property name="maxTime" value="5"></property> -->
				</bean>
				
				<!-- 注冊(cè)樂(lè)觀鎖插件 -->
				<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor">
				</bean>
			
			</list>
			
		</property>
		
	</bean>

?測(cè)試比對(duì)

	/**
	 * 測(cè)試 樂(lè)觀鎖插件
	 */
	
	@Test
	public void testOptimisticLocker() {
		//更新操作
		Employee employee = new Employee();
		employee.setId(15);
		employee.setLastName("TomAA");
		employee.setEmail("tomAA@sina.com");
		employee.setGender("1");
		employee.setAge(22);
		employee.setVersion(3);
		
		employeeMapper.updateById(employee);
		
	}

8.全局配置

? 根據(jù) MybatisPlus 的 AutoSqlInjector 可以自定義各種你想要的 sql ,注入到全局中,相當(dāng)于自 定義 Mybatisplus 自動(dòng)注入的方法。

? 之前需要在 xml 中進(jìn)行配置的 SQL 語(yǔ)句,現(xiàn)在通過(guò)擴(kuò)展 AutoSqlInjector 在加載 mybatis 環(huán)境 時(shí)就注入。

8.1 AutoSqlInjector

在 Mapper 接口中定義相關(guān)的 CRUD 方法

擴(kuò)展 AutoSqlInjector inject 方法,實(shí)現(xiàn) Mapper 接口中方法要注入的 SQL

新建包 injector/MySqlInjector.java

/**
 * 自定義全局操作
 */
public class MySqlInjector  extends AutoSqlInjector{
	
	/**
	 * 擴(kuò)展inject 方法,完成自定義全局操作
	 a模仿 injectDeleteSql
	 */
	@Override
	public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass,
			Class<?> modelClass, TableInfo table) {
		//將EmployeeMapper中定義的deleteAll, 處理成對(duì)應(yīng)的MappedStatement對(duì)象,加入到configuration對(duì)象中。
		
		//注入的SQL語(yǔ)句
		String sql = "delete from " +table.getTableName();
		//注入的方法名   一定要與EmployeeMapper接口中的方法名一致
		String method = "deleteAll" ;
		
		//構(gòu)造SqlSource對(duì)象
		SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
		
		//構(gòu)造一個(gè)刪除的MappedStatement
		this.addDeleteMappedStatement(mapperClass, method, sqlSource);
		
	}
}

?3) 在 MP 全局策略中,配置 自定義注入器

<!-- 定義MybatisPlus的全局策略配置-->
	<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
		<!-- 在2.3版本以后,dbColumnUnderline 默認(rèn)值就是true -->
		<property name="dbColumnUnderline" value="true"></property>
		
		<!-- Mysql 全局的主鍵策略 -->
		<!-- <property name="idType" value="0"></property> -->
		
		<!-- Oracle全局主鍵策略 -->
		<property name="idType" value="1"></property>
		
		<!-- 全局的表前綴策略配置 -->
		<property name="tablePrefix" value="tbl_"></property>
		
		<!--注入自定義全局操作 
		<property name="sqlInjector" ref="mySqlInjector"></property>
		
		
     	<property name="keyGenerator" ref="oracleKeyGenerator"></property>
	</bean>
	
	<!-- 定義自定義注入器 -->
	<bean id="mySqlInjector" class="com.ccut.mp.injector.MySqlInjector"></bean>
	
    
    

測(cè)試

	/**
	 * 測(cè)試自定義全局操作
	 */
	@Test
	public void  testMySqlInjector() {
		Integer result = employeeMapper.deleteAll();
		System.out.println("result: " +result );
	}

沒(méi)有寫(xiě)映射文件mapper 是在啟動(dòng)的時(shí)候就注入了

8.2 自定義注入器的應(yīng)用之 邏輯刪除

假刪除、邏輯刪除: 并不會(huì)真正的從數(shù)據(jù)庫(kù)中將數(shù)據(jù)刪除掉,而是將當(dāng)前被刪除的這條數(shù)據(jù) 中的一個(gè)邏輯刪除字段置為刪除狀態(tài). tbl_user logic_flag = 1 → -1

com.baomidou.mybatisplus.mapper.LogicSqlInjector

logicDeleteValue 邏輯刪除全局值

logicNotDeleteValue 邏輯未刪除全局值

在 POJO 的邏輯刪除字段 添加 @TableLogic 注解

會(huì)在 mp 自帶查詢(xún)和更新方法的 sql 后面,追加『邏輯刪除字段』=『LogicNotDeleteValue 默認(rèn)值』 刪除方法: deleteById()和其他 delete 方法, 底層 SQL 調(diào)用的是 update tbl_xxx set 『邏輯刪除字段』=『logicDeleteValue 默認(rèn)值』

8.3 實(shí)戰(zhàn)

全局sql 注入器的使用,配置

1.appcattionContex.xml


<!-- 定義MybatisPlus的全局策略配置-->
	<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
		<!-- 在2.3版本以后,dbColumnUnderline 默認(rèn)值就是true -->
		<property name="dbColumnUnderline" value="true"></property>
		.....
	 	
	 	
	 	<!-- 注入邏輯刪除 -->
	 	<property name="sqlInjector" ref="logicSqlInjector"></property>
	 	
	 	<!-- 注入邏輯刪除全局值 -->
	 	<property name="logicDeleteValue" value = "-1"></property>
	 	<property name="logicNotDeleteValue" value="1"></property>
	 	
	 	
	</bean>
	
	
	<!-- 邏輯刪除 -->
	<bean id="logicSqlInjector" class="com.baomidou.mybatisplus.mapper.LogicSqlInjector"></bean>
	

創(chuàng)建表:

logflag 字段

實(shí)體類(lèi)

usermapper

直接繼承BaseMapper<User>
/**
	 * 測(cè)試邏輯刪除
	 */
	@Test
	public void testLogicDelete() {
		
//		Integer result = userMapper.deleteById(1); 變成了更新?tīng)顟B(tài) 
//		System.out.println("result:" +result );
		
		User user = userMapper.selectById(1);  //查詢(xún)不到的 null   判斷 and  邏輯字段等于1
		System.out.println(user);
	}

9.公共字段填充

希望有些默認(rèn)的值給他填充上去

?9.1 元數(shù)據(jù)處理器接口 com.baomidou.mybatisplus.mapper.MetaObjectHandler

insertFill(MetaObject metaObject) 插入的填充

updateFill(MetaObject metaObject) 更新的時(shí)候填充

metaobject: 元對(duì)象. 是 Mybatis 提供的一個(gè)用于更加方便,更加優(yōu)雅的訪問(wèn)對(duì)象的屬性, 給對(duì)象的屬性設(shè)置值 的一個(gè)對(duì)象. 還會(huì)用于包裝對(duì)象. 支持對(duì) Object 、Map、Collection 等對(duì)象進(jìn)行包裝

本質(zhì)上 metaObject 獲取對(duì)象的屬性值或者是給對(duì)象的屬性設(shè)置值,最終是要 通過(guò) Reflector 獲取到屬性的對(duì)應(yīng)方法的 Invoker, 最終 invoke.

?9.2 開(kāi)發(fā)步驟

注解填充字段 @TableFile(fill = FieldFill.INSERT) 查看 FieldFill

自定義公共字段填充處理器

MP 全局注入 自定義公共字段填充處理器

1.實(shí)現(xiàn)步驟

實(shí)體類(lèi)

公共字段處理器

全局配置

放在全局策略上

	<!-- 注入公共字段填充處理器 -->
	 	<property name="metaObjectHandler" ref="myMetaObjectHandler"></property>
	 	
	 	<!-- 注入Oracle主鍵Sequence -->
	 	<property name="keyGenerator" ref="oracleKeyGenerator"></property>
	</bean>
	
	
	
<!-- 公共字段填充 處理器 -->
	<bean id="myMetaObjectHandler" class="com.atguigu.mp.metaObjectHandler.MyMetaObjectHandler"> </bean>	
	
	

2.自定義填充處理器的實(shí)現(xiàn)

/**
 * 自定義公共字段填充處理器
 */
public class MyMetaObjectHandler extends MetaObjectHandler {
	
	/**
	 * 插入操作 自動(dòng)填充
	 */
	@Override
	public void insertFill(MetaObject metaObject) {
		//獲取到需要被填充的字段的值
		Object fieldValue = getFieldValByName("name", metaObject);
		if(fieldValue == null) {
			System.out.println("*******插入操作 滿(mǎn)足填充條件*********");
			setFieldValByName("name", "weiyunhui", metaObject);
		}
		
	}
	/**
	 * 修改操作 自動(dòng)填充
	 */
	@Override
	public void updateFill(MetaObject metaObject) {
		Object fieldValue = getFieldValByName("name", metaObject);
		if(fieldValue == null) {
			System.out.println("*******修改操作 滿(mǎn)足填充條件*********");
			setFieldValByName("name", "weiyh", metaObject);
		}
	}

}

3.測(cè)試

/**
	 * 測(cè)試公共字段填充
	 有名字就不會(huì)進(jìn)行填充
	 */
	@Test
	public void testMetaObjectHandler() {
		User user = new User();
		//user.setName("Tom");
		 // userMapper.insert(user);
		user.setId(5);
		user.setLogicFlag(1);
		
		userMapper.updateById(user);
	}

對(duì)某個(gè)字段修改,就不適合了,它認(rèn)為沒(méi)有值就填充了

10. Oracle 主鍵 Sequence

MySQL: 支持主鍵自增。 IdType.Auto
Oracle: 序列(Sequence)  不支持主鍵自增

1.步驟

實(shí)體類(lèi)配置主鍵 Sequence @KeySequence(value=”序列名”,

clazz=xxx.class 主鍵屬性類(lèi) 型)

全局 MP 主鍵生成策略為 IdType.INPUT

多個(gè) ,也就是整個(gè)環(huán)境都在使用oracle數(shù)據(jù)庫(kù)

 <!-- Oracle全局主鍵策略 -->
		<property name="idType" value="1"></property>

全局 MP 中配置 Oracle 主鍵 Sequence com.baomidou.mybatisplus.incrementer.OracleKeyGenerator

 <!-- 注入Oracle主鍵Sequence -->
	 	<property name="keyGenerator" ref="oracleKeyGenerator"></property>
	</bean>
	
	

<!-- 配置Oracle主鍵Sequence -->
	<bean id="oracleKeyGenerator" class="com.baomidou.mybatisplus.incrementer.OracleKeyGenerator"></bean>
		

可以將@keySequence 定義在父類(lèi)中,可實(shí)現(xiàn)多個(gè)子類(lèi)對(duì)應(yīng)的多個(gè)表公用一個(gè) Sequence

2.Oracle 驅(qū)動(dòng)依賴(lài)問(wèn)題


3.配置連接信息

orcl.driver=oracle.jdbc.OracleDriver
orcl.url=jdbc:oracle:thin:@localhost:1521:xe
orcl.username=system
orcl.password=1234

4.創(chuàng)建表及序列


5.演示.

	/**
	 * 測(cè)試Oracle 主鍵 Sequence
	 */
	@Test
	public void testOracle() {
		User user = new User();
		user.setLogicFlag(1);
		user.setName("OracleSEQ");
		userMapper.insert(user);
	}

6. 擴(kuò)展 多個(gè)實(shí)體類(lèi)公用一個(gè)序列

11. idea

MybatisX 輔助 idea 快速開(kāi)發(fā)插件,
為效率而生. 可以實(shí)現(xiàn) java 與 xml 跳轉(zhuǎn),根據(jù) Mapper 接口中的方法自動(dòng)生成 xml 結(jié)構(gòu).
官方安裝: File -> Settings -> Plugins -> Browse Repositories.. 輸入 mybatisx 安裝下載
Jar 安裝: File -> Settings -> Plugins -> Install plugin from disk.. 選中 mybatisx..jar 安裝

不停的思考,就會(huì)不停的進(jìn)步

總結(jié)

以上是生活随笔為你收集整理的MyBatis Plus的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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

在线免费观看麻豆 | 91九色视频在线 | 欧美成人一二区 | 综合五月婷婷 | 五月婷婷视频在线 | 日韩激情中文字幕 | 天天射色综合 | 色吊丝在线永久观看最新版本 | 久久系列 | 国产乱老熟视频网88av | 国产精品嫩草在线 | 99日韩精品 | 999久久久欧美日韩黑人 | 亚洲精品美女久久久久 | 国产91精品一区二区麻豆亚洲 | 亚洲精品国产麻豆 | 人人舔人人干 | 国产 字幕 制服 中文 在线 | 91九色视频在线 | 色综合www | 字幕网在线观看 | 黄色成人在线观看 | 天天艹天天爽 | 国产成人av在线影院 | 香蕉视频在线播放 | 伊人午夜 | 中文字幕在线观看一区二区三区 | 国产精品普通话 | 91中文字幕在线播放 | 少妇bbw搡bbbb搡bbb | 六月激情婷婷 | 亚洲成av人片在线观看www | 日韩高清精品一区二区 | 天干啦夜天干天干在线线 | 欧美福利精品 | 亚洲二区精品 | 一区二区三区中文字幕在线观看 | 国产不卡一区二区视频 | 97激情影院| av电影在线观看完整版一区二区 | 91精品日韩| 久久在视频 | 久久视屏网 | 午夜精品一区二区国产 | av九九九 | 中文字幕黄色 | 精品人妖videos欧美人妖 | 手机看国产毛片 | 在线看一区二区 | 久久躁日日躁aaaaxxxx | 久久久久久97三级 | 中文字幕免费高清av | 永久免费在线 | 久久成人免费视频 | 欧美日韩中文在线观看 | 久久成人麻豆午夜电影 | 亚洲极色| 亚洲aaa级| 中文字幕人成人 | 最近2019年日本中文免费字幕 | 91中文字幕网 | 免费亚洲精品视频 | 成人网在线免费视频 | 青青草国产免费 | 99精品视频免费全部在线 | 日韩网站在线观看 | 超碰国产在线观看 | 久久视影 | 亚洲a资源 | 精品一区91| 麻豆91精品91久久久 | 美女福利视频一区二区 | 日韩精品一卡 | 在线高清av | 久久九九视频 | 三级黄色网址 | 日日夜夜天天综合 | 日韩和的一区二在线 | 九色视频网站 | 九九久久久 | 91麻豆精品国产自产在线 | 激情中文字幕 | 亚洲激情网站免费观看 | 国产精品99久久99久久久二8 | 久久免费国产 | 黄色免费视频在线观看 | 亚洲中字幕 | 91成人小视频 | 九九九在线观看视频 | 国产日韩视频在线播放 | 欧美国产精品一区二区 | 欧美日韩亚洲第一 | 日韩大片免费在线观看 | 欧美另类xxxxx | 久久综合九色综合欧美狠狠 | 天天拍天天操 | 五月天婷婷综合 | 色综合久久久久久久 | 免费a级毛片在线看 | 免费在线一区二区三区 | 在线欧美a | japanesexxxhd奶水| 在线观看中文字幕一区 | 日韩视频一二三区 | 成人av在线网 | 日韩国产精品久久 | 久青草视频在线观看 | www操操操| 一区二区三区免费 | 亚洲成a人片77777kkkk1在线观看 | 97久久精品午夜一区二区 | 最近免费在线观看 | 99久久99视频 | 亚洲人成人在线 | 久久黄色小说视频 | 国产一区免费看 | 国产精品尤物视频 | 久久精品影片 | 视频在线观看亚洲 | 制服丝袜天堂 | 久久久99精品免费观看乱色 | 久久私人影院 | 国产中文字幕网 | 精品久久一区二区三区 | 黄色av网站在线观看免费 | 中文字幕在线观看的网站 | 国产三级久久久 | 国产精品中文久久久久久久 | 超碰97国产精品人人cao | 国产精品中文字幕在线观看 | 黄网站www| 国产精品久久久久久欧美 | 久久蜜臀av | 日韩在线视频网 | 日日干 天天干 | a成人v在线 | 精品久久久久_ | 91在线一区二区 | 在线观看一区视频 | 91亚洲国产成人 | 欧美午夜剧场 | 日韩欧美在线第一页 | 国产精品字幕 | 亚洲小视频在线观看 | 国产成人一区二区三区电影 | 色综合久久五月天 | 国产最新视频在线观看 | 黄色影院在线观看 | 成人在线视频免费看 | 日韩视频在线不卡 | 婷婷综合在线 | 欧美性免费 | 国产 日韩 中文字幕 | 黄色毛片视频免费观看中文 | 婷婷六月天在线 | 国产一区视频在线 | 中文字幕黄色 | 日韩高清在线一区二区 | 欧美91片| 国产精品21区| 国产精品久久久久一区二区三区 | 狠狠狠色丁香综合久久天下网 | 久久永久免费 | 色大片免费看 | 91成人网在线播放 | 亚洲精品一区二区在线观看 | 亚洲最新在线视频 | 韩日精品视频 | 韩国中文三级 | 81国产精品久久久久久久久久 | 日韩伦理片一区二区三区 | 亚洲国产综合在线 | 日韩免费 | 日精品 | 欧美日韩在线观看一区二区三区 | 天天爱天天操天天干 | 色综合久久精品 | 黄色影院在线播放 | 综合伊人av| 欧美成人一区二区 | 丁香五月亚洲综合在线 | 欧美一级专区免费大片 | 人人擦 | 一区 二区 精品 | 黄色小网站免费看 | 天天综合精品 | 丰满少妇在线观看 | 狠狠狠综合 | 在线看一区 | 波多野结衣在线视频免费观看 | 久久97久久97精品免视看 | 国产又粗又猛又爽又黄的视频免费 | 欧美亚洲三级 | 色资源中文字幕 | 国产亚洲欧洲 | 国产日本高清 | 久久欧美在线电影 | 天天射狠狠干 | 激情五月综合 | 亚洲黄色高清 | 国产精品一区二区三区免费看 | 成人中文字幕在线 | 久久精品国产免费看久久精品 | 日韩av午夜 | 久久好看 | 99在线观看精品 | 国产在线综合视频 | 91在线精品播放 | 四虎国产精| 久久在线精品视频 | 亚洲91网站 | 视频在线亚洲 | 欧美巨乳波霸 | 蜜臀久久99精品久久久无需会员 | 国产精品去看片 | 国产色一区 | 国产性天天综合网 | 国产伦理久久精品久久久久_ | 欧美日韩国产一二三区 | 久久综合电影 | 狠狠色狠狠色合久久伊人 | 久久麻豆精品 | 亚洲精品乱码久久久久久蜜桃动漫 | 国产精品黑丝在线观看 | 99热最新 | 人人爽久久久噜噜噜电影 | 日韩有码在线观看视频 | 欧洲亚洲女同hd | 日韩精品久久久久久 | 精品福利网站 | 国产精品99久久久精品免费观看 | 亚洲高清视频在线观看 | 69亚洲视频 | 97精品国产一二三产区 | 在线播放 亚洲 | 日本色小说视频 | 91视频高清免费 | 亚洲免费精品一区二区 | 亚洲精品国偷自产在线91正片 | 97超碰在| 亚洲日本成人网 | 日韩精品亚洲专区在线观看 | 欧美日本啪啪无遮挡网站 | 不卡av免费在线观看 | 91成人在线视频 | 欧美日韩高清国产 | 黄网站www | 午夜视频一区二区三区 | 亚洲精品综合在线观看 | 国产精品99久久久久人中文网介绍 | 亚洲小视频在线 | 国产精品18p| 最近中文字幕免费视频 | 日韩中文在线字幕 | 国产精品久久久久久久久久久久午夜 | 国产精品综合在线观看 | 黄色com| 99久久久国产精品免费99 | 免费黄色在线 | a天堂免费 | 成人在线免费观看网站 | 麻豆一二三精选视频 | av 在线观看 | 人人讲下载 | 久久久久综合 | av在线观| 久久久久国 | 夜夜干天天操 | 成人av网站在线观看 | 九九热视频在线 | 国产成人在线免费观看 | 免费麻豆网站 | 天堂av色婷婷一区二区三区 | 日本午夜在线亚洲.国产 | 欧美日韩一区二区久久 | 午夜av一区| 丝袜制服天堂 | 美女视频黄频 | 免费在线视频一区二区 | 免费一级日韩欧美性大片 | 九色精品免费永久在线 | 久久99这里只有精品 | 天天天操天天天干 | 亚洲精品影视 | 久久视频这里只有精品 | 亚洲精品视频二区 | 精品久久久久久亚洲 | 久草视频在线免费看 | www黄色av| 亚洲精品视频在线播放 | 黄色免费网站下载 | 99中文视频在线 | 中日韩在线视频 | 日韩一区二区免费在线观看 | 久久久五月婷婷 | 久久在线免费观看 | 欧美一级片免费观看 | 亚洲播播 | 久久久国产一区 | 日韩欧美精品在线 | 国产精品入口麻豆 | 超级碰碰免费视频 | 免费视频99| 欧美一区日韩精品 | 午夜色影院 | 亚洲精选视频在线 | 五月婷婷久久丁香 | 狠狠操狠狠 | 亚洲欧美国内爽妇网 | 99看视频在线观看 | 亚洲一级黄色大片 | 日日日爽爽爽 | 五月天中文字幕mv在线 | 91在线播放视频 | 久久草网站 | 一级黄色免费 | 国产成人精品999在线观看 | 日韩在线影视 | 日韩毛片一区 | 99色人| 日本黄网站 | 日韩久久久久久久久久久久 | 成年人在线观看 | 中文字幕在线日亚洲9 | 国产精品手机在线观看 | www.久热| 欧美激情第八页 | 999成人网 | 亚洲综合色视频 | 美女国内精品自产拍在线播放 | 久久99热久久99精品 | 成人午夜电影在线播放 | 天天操网址| 久久精品国产免费看久久精品 | 国产精彩视频一区 | 91麻豆高清视频 | av免费看在线 | 色婷婷午夜 | 日本中文字幕系列 | 亚洲国产成人精品久久 | 日韩欧美成人网 | 免费视频网 | 美女视频黄在线 | www.福利 | 国产免费a | 精品91视频 | 国产精品女人久久久 | 特及黄色片 | 成人精品国产免费网站 | 日批网站免费观看 | 国产精品一区二区av麻豆 | 天天搞天天干 | 国产日产精品一区二区三区四区 | 久久精品99国产精品酒店日本 | 亚洲区另类春色综合小说 | 97成人在线视频 | 欧美日韩xx | 久久成人国产精品入口 | 色婷婷激情电影 | 精品久久久久久国产偷窥 | 黄色av电影一级片 | 久久精品视频网址 | 日韩欧美国产激情在线播放 | 久久tv | 97色视频在线 | 伊人婷婷久久 | 77国产精品 | 国产精品久久久久久久久婷婷 | 亚洲一二视频 | 国产精品 中文字幕 亚洲 欧美 | 啪啪免费试看 | 黄污污网站| 九九视频在线播放 | 特级西西人体444是什么意思 | 丰满少妇高潮在线观看 | 国产精品原创在线 | 99久久99久久精品国产片果冰 | 三级黄免费看 | 亚洲自拍偷拍色图 | 韩国一区二区三区视频 | 欧美国产日韩在线观看 | 日本三级人妇 | 国产高清日韩欧美 | 天天综合入口 | 最新av网址大全 | 黄色免费看片网站 | 午夜影院在线观看18 | 欧美一级片免费在线观看 | 日韩在线免费不卡 | 亚洲最大av | 亚洲精品视频在线观看免费视频 | 日韩精品一区二区三区不卡 | 精品久久一区二区三区 | 69精品在线 | www.久久色 | 一级欧美一级日韩 | 精品久久久久久久久久久久久久久久久久 | 69av国产| 免费看三级| 99精品一区 | 国产精品乱码久久久久久1区2区 | 97av视频 | 91资源在线观看 | av丁香花| 干亚洲少妇 | 欧美一级片免费 | 免费看的黄色片 | 91麻豆精品国产91久久久久久久久 | 99久久er热在这里只有精品66 | 日韩欧美精品在线观看视频 | 日韩精品久久久久久中文字幕8 | 四虎影视成人永久免费观看亚洲欧美 | 992tv在线 | 中文字幕频道 | 黄色成人影视 | 国产精品久久久久久av | 日韩电影在线观看一区二区 | 欧美不卡视频在线 | 97综合视频| 91免费国产在线观看 | 99热99热| 色婷婷综合久久久中文字幕 | av福利网址导航大全 | 亚洲欧美日韩国产一区二区 | 日本在线观看视频一区 | 国产天天综合 | 激情 婷婷 | www.天天射 | 国产一区二区在线免费观看 | 亚洲激情影院 | 日本久久久久久科技有限公司 | 18国产精品白浆在线观看免费 | 在线有码中文 | 一个色综合网站 | 婷婷久久丁香 | 日韩高清成人在线 | 免费看的黄色片 | 在线视频久 | 蜜臀av在线一区二区三区 | 久久久久麻豆v国产 | 精品人人人人 | av在线一二三区 | 欧美巨大 | 日韩av免费在线电影 | 五月天婷婷在线观看视频 | 日韩免费三区 | 亚洲精品美女在线 | 天天干天天拍天天操 | 在线观看黄 | 91成人亚洲 | 在线 成人| 狠狠干天天射 | 久久99偷拍视频 | 中文字幕在线观看三区 | 999久久精品| 亚洲三级国产 | 国产精品女视频 | mm1313亚洲精品国产 | 成人欧美一区二区三区黑人麻豆 | 黄色小说免费观看 | 欧美一级日韩免费不卡 | 国产精品永久免费在线 | 五月激情五月激情 | 国产精品久久久久久久久久久久冷 | 97av影院| 亚洲精选在线观看 | 一区二区三区中文字幕在线观看 | 成年人视频在线观看免费 | 93久久精品日日躁夜夜躁欧美 | 日本中文字幕观看 | 麻豆免费精品视频 | 又爽又黄又无遮挡网站动态图 | 中文字幕 影院 | 欧美资源在线观看 | 久久国产精品久久w女人spa | 久久视频国产 | 狠狠色伊人亚洲综合网站色 | 亚洲视频 一区 | 久久免费电影 | 96av麻豆蜜桃一区二区 | 美女视频黄频大全免费 | 午夜精品福利在线 | 999成人| 欧美久久久久久久久久久久久 | 人人涩 | 青青久草在线视频 | 波多野结衣理论片 | 丁香网五月天 | 亚洲欧美日韩国产精品一区午夜 | 国产韩国日本高清视频 | 欧美怡红院视频 | 免费看污在线观看 | 日韩专区在线播放 | 国产探花 | 色天天| 五月天色站 | 亚洲国产精品影院 | 中国一级片免费看 | 欧美成人在线网站 | www黄色av| 中文十次啦| 国产亚洲免费的视频看 | 香蕉视频国产在线观看 | 国产精品久久久久久久久久久免费看 | 在线免费视频一区 | 欧美一级日韩免费不卡 | 久99精品 | 高清不卡一区二区在线 | 国产精品久久久久久影院 | 精品久久一区 | 99免费精品视频 | 亚洲另类人人澡 | 激情五月五月婷婷 | 亚洲综合小说 | 亚洲精品在线看 | 成人黄色免费在线观看 | av黄色亚洲 | 亚洲精品视 | 色www永久免费 | av日韩国产| 成人午夜免费福利 | 中文字幕精品一区二区三区电影 | 国产乱码精品一区二区蜜臀 | 麻花传媒mv免费观看 | 久久国产露脸精品国产 | 国产精品成人免费精品自在线观看 | 天天av综合网 | 亚洲精品国精品久久99热 | 亚洲欧美视频在线 | 亚洲一区二区精品3399 | 国内精品久久久久影院男同志 | 亚洲成人精品久久 | 手机版av在线| 色综合天天天天做夜夜夜夜做 | 免费在线电影网址大全 | 欧美大香线蕉线伊人久久 | 91精品视频观看 | 成人黄色电影免费观看 | 国产999精品久久久久久 | 1024手机看片国产 | 久草久草在线 | 国产区精品在线 | 成人亚洲精品国产www | 国产中文视 | 99免费在线视频 | 国产涩涩在线观看 | 91人人人| 九九久久成人 | 亚洲 欧美 国产 va在线影院 | 在线视频欧美日韩 | 国内久久久 | 欧美精品久久久久久久久老牛影院 | 日日操日日操 | 国产一区二区三区免费在线 | 99视频在线看 | 天天天射 | 天天爽天天摸 | 亚洲动漫在线观看 | 久久精品日本啪啪涩涩 | 中文字幕丝袜 | 久久激情婷婷 | 欧美激情精品久久久久久变态 | 久久这里有精品 | 亚洲国产精品推荐 | 国产91九色蝌蚪 | 久久精品一区二区国产 | 免费在线观看国产黄 | 国产一级大片免费看 | 色综合天 | 免费韩国av | www.成人久久 | 四虎在线视频免费观看 | 91亚洲国产 | 在线观看免费版高清版 | 婷婷久久五月天 | 国产精品欧美激情在线观看 | 天天草天天操 | 久久精品99精品国产香蕉 | 国产又粗又硬又爽的视频 | 欧美日韩国产二区 | 天天天天天天天操 | 97超碰人人澡人人爱 | 精品国产视频在线观看 | 欧美大片第1页 | 国产精品99爱 | 亚洲欧美日韩不卡 | 精品久久久久久综合日本 | 成人欧美一区二区三区黑人麻豆 | 激情丁香月 | 亚洲精品在线免费观看视频 | 亚洲精品美女在线 | 欧美午夜性 | 久久久国产精华液 | av7777777| 激情婷婷 | 最近中文字幕国语免费av | 综合色天天 | 日本韩国精品一区二区在线观看 | 国产麻豆精品一区二区 | 综合久久网| 中文字幕超清在线免费 | 欧美激情精品久久久久久 | 九九免费在线观看 | 欧美va在线观看 | 五月天婷婷在线播放 | 深爱激情婷婷网 | 天天玩天天干天天操 | 2023亚洲精品国偷拍自产在线 | 免费观看一级成人毛片 | 五月花丁香婷婷 | 免费观看一级特黄欧美大片 | 欧美性超爽 | 天天天天色射综合 | 婷婷六月天天 | 亚洲成av| 国产视频99 | 午夜精品福利影院 | 国产日韩精品视频 | 久久婷婷久久 | 狠狠黄 | 友田真希x88av| 国产精品永久久久久久久www | 国产精品美女视频网站 | 夜夜躁狠狠躁日日躁 | 日韩精品一区电影 | 欧美另类z0zx | 亚洲精品电影在线 | 热99久久精品 | 综合网成人 | 色偷偷88888欧美精品久久久 | 成人在线免费av | 亚洲精品久久视频 | 日本性高潮视频 | 9999精品| 欧美日韩裸体免费视频 | 久久久久久久影视 | 亚洲激情小视频 | 国产成人精品亚洲精品 | 91成人网在线观看 | 三上悠亚一区二区在线观看 | 午夜精品福利一区二区 | 99久久久国产精品美女 | 麻豆视频免费网站 | 免费av片在线 | 日韩高清在线不卡 | 黄色av电影在线观看 | 狠狠久久 | 国产精品精品久久久 | 6080yy精品一区二区三区 | 日韩av免费观看网站 | 精品久久久久久久久久久久 | 在线观看免费观看在线91 | 久久久影视 | 少妇bbb | 国产手机在线精品 | 嫩草av在线| 国产高清免费观看 | 在线中文字幕网站 | 视频在线日韩 | 天天爱天天操天天爽 | 中文字幕中文字幕在线中文字幕三区 | 中文字幕影片免费在线观看 | 亚洲精品午夜一区人人爽 | 在线观看视频一区二区三区 | 成人在线观看你懂的 | 欧美性天天 | 丁香六月婷婷开心 | 99视频免费播放 | 国产一级久久 | 亚洲最大av网站 | 99色免费 | 99久久精品免费看国产 | 午夜久久久久久久久久久 | 国产日韩精品一区二区在线观看播放 | 91av亚洲 | 97av影院| 国产视频精品视频 | 91麻豆免费看 | 九九热在线视频 | 一区二区三区视频在线 | 久久久三级视频 | 国产精品毛片网 | 三级av在线免费观看 | 午夜精品麻豆 | 欧美日韩国语 | 久草在线91| 色播99| 国产精品99久久久久久久久 | 91色在线观看视频 | 成人影片在线播放 | 国产精品一区久久久久 | 激情五月婷婷综合 | 成人黄色大片在线观看 | 99草视频 | 91色国产在线 | 高清国产在线一区 | 久久精品久久综合 | 亚洲综合射 | 国产黄色播放 | 免费看一级一片 | 亚洲理论片 | 久免费 | 日日久视频| 91成人精品观看 | 最新日韩视频 | 国产成人精品免高潮在线观看 | 在线观看成人福利 | 一区二区精品在线 | 国产人成精品一区二区三 | 久久精品视频免费播放 | a在线免费 | 一区二区视频在线免费观看 | 亚洲午夜小视频 | 日韩精品大片 | 黄p网站在线观看 | 黄色毛片观看 | 国产综合香蕉五月婷在线 | 九九九电影免费看 | 亚av在线| 91视频免费看网站 | 91片网 | 深爱婷婷激情 | 国产亚洲成av片在线观看 | 免费成人av在线看 | 久久免费毛片视频 | 麻豆成人在线观看 | 中文字幕在线看视频国产 | 六月激情 | 国产一区二区不卡在线 | av在观看 | 99视频精品视频高清免费 | 色的网站在线观看 | 97国产在线视频 | 九色在线| 日韩在线观看第一页 | 久久99热精品 | 亚州精品天堂中文字幕 | 色综合人人 | av在线电影免费观看 | 免费a v观看 | 国产日韩精品一区二区三区在线 | 免费下载高清毛片 | 在线观看中文字幕一区二区 | 激情影院在线观看 | 亚洲美女视频在线 | 在线中文字幕一区二区 | 亚洲综合婷婷 | 制服丝袜一区二区 | 久久蜜桃av | 视频二区| 欧美做受高潮 | 欧美精品黑人性xxxx | 免费视频你懂的 | 亚洲精品乱码久久久久久9色 | 国产一级大片在线观看 | 久草在线 | 91探花国产综合在线精品 | 国产一卡二卡四卡国 | 久热精品国产 | 国产精品毛片一区视频播 | 亚洲天堂网在线播放 | 成人宗合网 | 日日摸日日 | 久久人人爽人人爽人人 | 在线观看一级视频 | 国产精品久久99 | 欧美精品一区二区在线播放 | 久久精品女人毛片国产 | 国产专区第一页 | 久av在线| 五月婷婷.com | 99精品热视频 | 人人爱人人舔 | 欧美日韩在线观看一区二区三区 | 成人av视屏 | 99九九免费视频 | 97在线观看视频免费 | av一级在线 | 精品国产免费av | 毛片网在线 | 亚洲成av人影院 | 在线观看成人 | 天天综合人人 | 天天爱天天射天天干天天 | 日韩天堂在线观看 | 色婷婷久久久综合中文字幕 | 狠狠干网址 | 国产亚洲精品av | 97超碰在线久草超碰在线观看 | 99爱国产精品 | 日本精品久久久久影院 | 国产一区影院 | 开心激情网五月天 | 国产高清 不卡 | 免费观看一区二区 | 日韩一区二区免费在线观看 | 操操综合网 | 亚洲精品视频在线观看免费 | 国产99久久久久久免费看 | 国产玖玖精品视频 | 久久免费国产精品 | av性在线| 亚洲aⅴ乱码精品成人区 | 91天堂素人约啪 | 黄色av免费在线 | 亚洲午夜久久久久久久久电影网 | 97国产视频| 国产福利小视频在线 | 久久久久久久久免费视频 | 韩国av免费观看 | 蜜臀av性久久久久av蜜臀三区 | 一区 在线观看 | 欧美小视频在线观看 | 亚洲国产精品500在线观看 | av色网站| 久久不卡电影 | 精品国产1区2区 | 日韩激情中文字幕 | 一区二区三区免费在线 | 色综合婷婷 | 国产理论在线 | www.五月婷婷.com | 91大神电影 | www日韩| 黄色免费视频在线观看 | 日韩小视频 | 亚洲六月丁香色婷婷综合久久 | 午夜私人影院久久久久 | 中文字幕一区二区三区乱码在线 | 日韩激情一二三区 | 国产精品精 | 色国产精品 | 99精品视频在线观看视频 | 91精品国产麻豆国产自产影视 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 精品国产99 | 天天爱天天插 | 久久久亚洲精品 | 免费在线观看日韩欧美 | 99免费看片 | 色99之美女主播在线视频 | 欧美日韩另类视频 | 亚洲精品在线电影 | 综合网欧美| 日韩欧美精品一区二区三区经典 | 久久久精品综合 | 国产日韩欧美在线观看视频 | 波多野结衣精品在线 | 69视频永久免费观看 | 欧美一区二区日韩一区二区 | 精品视频资源站 | 久久精品aaa | 最近av在线 | 在线观看av中文字幕 | 国产 一区二区三区 在线 | 在线观看成人小视频 | 久久久久国产精品免费 | 免费日韩一区二区三区 | 国产精品久久久久久久电影 | 操操综合网| 国产精品美女网站 | 97在线公开视频 | 69国产盗摄一区二区三区五区 | 在线国产精品视频 | 色99久久| 国产乱码精品一区二区三区介绍 | 久久撸在线视频 | 国产精品国产三级国产专区53 | 午夜av日韩| 夜夜视频欧洲 | 狂野欧美激情性xxxx | 国产精品久久久久av免费 | www亚洲视频| 91大神dom调教在线观看 | 国产精品免费看 | 久久久久亚洲精品男人的天堂 | 亚洲国产高清视频 | 中文av不卡 | 天天操天天操天天操天天操 | 亚洲精品小视频在线观看 | 国产精品一区免费看8c0m | 欧美激情操 | 精品在线免费观看 | 91九色porny在线 | 四虎欧美| 69国产盗摄一区二区三区五区 | 国产xxxx | 麻豆91在线播放 | 精品国产乱码一区二 | 男女啪啪免费网站 | 成人av视屏 | 天天看天天干天天操 | 福利av影院 | 中文字幕乱码日本亚洲一区二区 | 狠狠狠狠狠操 | 欧美福利网站 | 久久久久精| 国产精品自拍在线 | 国产伦精品一区二区三区在线 | 国产精品青草综合久久久久99 | 狠狠色免费 | 激情欧美丁香 | 国产不卡在线视频 | 久久99欧美 | 黄色影院在线观看 | 色婷婷天天干 | 久久久久久不卡 | 天堂在线视频中文网 | 色婷婷综合成人av | 国产又粗又猛又黄又爽视频 | 黄色av一区二区三区 | 免费在线观看不卡av | 欧美日韩三区二区 | 在线免费中文字幕 | 久久久久久久久毛片精品 | 在线观看午夜av | 欧美激情精品久久久 | 成人欧美一区二区三区黑人麻豆 | 超碰在线97国产 | 成人影音在线 | 高清av在线免费观看 | 一区中文字幕 | 丁香五婷 | 国产亚洲va综合人人澡精品 | 日本精品视频一区 | 在线观看中文字幕亚洲 | av网站在线观看播放 | 成人免费看片98欧美 | www.超碰97.com | 欧美一区二区三区在线观看 | 国产高清免费在线观看 | 高清一区二区 | 久久国产精品久久国产精品 | 97精品久久人人爽人人爽 | 日韩丝袜视频 | 激情 婷婷| 九九天堂 | 夜夜视频欧洲 | 亚洲另类交| 午夜精品视频福利 | 中文字幕视频 | 五月香婷| 夜夜操夜夜干 | 日韩精品视频免费在线观看 | 日韩免费不卡av | 久久国产精品精品国产色婷婷 | 麻豆传媒视频在线播放 | 91成人在线观看喷潮 | 日韩高清免费在线 | 国产午夜三级一区二区三桃花影视 | 天堂入口网站 | 人人爽人人澡人人添人人人人 | 欧美精品久久久久久久久久久 | 99久久久久久久 | 亚洲成人蜜桃 | 久久成熟 | 国产黄色a | 免费观看一级成人毛片 | 国产精品黄色影片导航在线观看 | 狠狠操天天射 | 欧美激情综合五月色丁香 | 国产在线精品一区二区三区 | 久久久999免费视频 日韩网站在线 | 有码一区二区三区 | 日韩精品中文字幕久久臀 | 日韩欧美在线观看 | 在线视频婷婷 | av黄免费看 | 国产伦精品一区二区三区在线 | 国产精品久久久久一区二区三区共 | 在线观看91精品国产网站 | 日韩性xxx| 成人免费视频网 | 午夜精品久久久99热福利 | 国产成人精品一区二区三区免费 | 国产免费av一区二区三区 | 日本不卡一区二区 | 久久久.com | 久久视精品 | 午夜视频播放 | 久久永久视频 | 黄色小说免费观看 | 少妇av网 | 国产一区二区高清不卡 | 天天射色综合 | www色,com | 91在线观看视频 | 免费a级毛片在线看 | 在线视频欧美亚洲 | 久久精品超碰 | 国产精品初高中精品久久 | 808电影免费观看三年 | 国产五月婷婷 | 91九色综合 | 99久久婷婷国产综合精品 | 日韩欧美69| 玖玖视频国产 | 中文字幕永久免费 |