<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] **** ## 1 簡介 ### 1-1 數據庫驅動層次 TP5的數據庫驅動實現了重構 從應用到底層從上到下分為以下幾部分 >[info]1 數據庫中間層(Db.php):數據庫操作接口 >[info]2 數據庫連接(Connection.php):數據庫連接操作與查詢入口 >[info]3 數據庫查詢(Query.php):數據庫查詢操作 >[info]4 數據庫查詢語句構造(Builder.php):合成數據庫查詢語句 另外還是要Model封裝了數據庫的ORM操作 有關模型ORM的分析見 新模型Model功能 ### 1-2 層次關系 >[info]1 Db.php:數據庫操作接口 >[info]2 Connection.php:數據庫連接接口 >[info]3 Query.php:數據庫語句執行接口 >[info]4 Builder.php:數據庫語句生成接口 整個層次實現為通過(Builder.php)生成語句,然后在(Connection.php)連接的數據庫實例上,通過(Query.php)執行生成的語句 而Db.php作為數據庫的操作接口 ## 2 數據庫中間層(Db.php) ### 2-1 成員變量 ~~~ ;所有數據庫連接實例,當前數據庫連接實例 private static $instances = []; private static $instance = null; ;數據庫查詢次數統計,數據庫執行次數統計 public static $queryTimes = 0; public static $executeTimes = 0; ~~~ ### 2-2 public 成員方法 #### 1 connect() 數據庫初始化 ~~~ public static function connect($config = []) ~~~ > $config:數據庫連接配置 > 生成數據庫連接實例存儲到$instances與$instance中,并返回self::$instance ~~~ ;使用Db::connect()初始化數據庫連接 $db = Db::connect([ 'type' => 'mysql', 'dsn' => '', 'hostname' => '127.0.0.1', 'database' => 'thinkphp', 'username' => 'root', 'password' => '', 'hostport' => '', 'params' => [], 'charset' => 'utf8', 'prefix' => 'think_', ]); ~~~ ~~~ ;使用/config/database.php配置中的連接參數 return [ 'type' => 'mysql', 'dsn' => '', 'hostname' => '127.0.0.1', 'database' => 'thinkphp', 'username' => 'root', 'password' => '', 'hostport' => '', 'params' => [], 'charset' => 'utf8', 'prefix' => 'think_', 'debug' => false, 'deploy' => 0, 'rw_separate' => false, 'master_num' => 1, 'slave_no' => '', ]; $db = Db::connect(); ~~~ ~~~ ;使用字符串配置 $db = Db::connect('mysql://root:1234@127.0.0.1:3306/thinkphp#utf8'); ~~~ ~~~ ;/config/database.php中多個數據庫配置 //數據庫配置1 'db_config1' => [ 'type' => 'mysql', 'hostname' => '127.0.0.1', 'database' => 'thinkphp', 'username' => 'root', 'password' => '', 'charset' => 'utf8', 'prefix' => 'think_', ], //數據庫配置2 'db_config2' => 'mysql://root:1234@localhost:3306/thinkphp#utf8'; $db1 = Db::connect('db_config1'); $db2 = Db::connect('db_config2'); ~~~ ~~~ ;在Model中配置數據庫連接 namespace app\index\model; use think\Model; class User extends Model { protected static $connection = [ 'type' => 'mysql', 'dsn' => '', 'hostname' => '127.0.0.1', 'database' => 'thinkphp', 'username' => 'root', 'password' => '', 'hostport' => '', 'params' => [], 'charset' => 'utf8', 'prefix' => 'think_', 'debug' => false, 'deploy' => 0, 'rw_separate' => false, 'master_num' => 1, 'slave_no' => '', ]; } ~~~ ~~~ ;模型中字符串數據庫連接配置 namespace app\index\model; use think\Model; class User extends Model { //或者使用字符串定義 protected static $connection = 'mysql://root:1234@127.0.0.1:3306/thinkphp#utf8'; } ~~~ #### 2 __callStatic() 數據庫靜態方法調用攔截 ~~~ public static function __callStatic($method, $params) ~~~ >$method:調用的方法名 >$paramse:調用方法的參數 >內部調用self::$instance對應的方法。 ~~~ ;數據庫查詢語句 $data = Db::query('select * from think_user where id=?',[8]); ;數據庫語句執行 $result = Db::execute('insert into think_user (id, name) values (?, ?)',[8,'thinkphp']); ;使用助手函數 $data = db($config)->query('select * from think_user where id=:id',['id'=>8]); ~~~ ### 2-3 private 方法 #### 1 parseConfig() 數據庫配置解析 ~~~ private static function parseConfig($config) ~~~ > $config:數據庫連接參數,如果為空則獲取配置文件database.php中數據庫連接配置參數 #### 2 parseDsn() 數據庫DSN配置解析 ~~~ private static function parseDsn($dsnStr) ~~~ > $dsnStr :dsn字符串 > 解析字符串為數據庫配置參數 ## 3 數據庫連接(Connection.php) ### 3-1 成員變量 ~~~ ;PDO操作實例 protected $PDOStatement; ;當前操作的數據表名;當前操作的數據對象名;當前SQL指令 protected $table = ''; protected $name = ''; protected $queryStr = ''; ;操作結果最后插入ID;返回或者影響記錄數 protected $lastInsID; protected $numRows = 0; ;事務的數據庫連接;事務指令數;事務標識 protected $transPDO; protected $transTimes = 0; protected $transLabel = ''; ;錯誤信息;數據庫連接ID數組 ;當前連接ID protected $error = ''; protected $links = []; protected $linkID; ;查詢結果類型 ;字段屬性大小寫;監聽回調 protected $fetchType = PDO::FETCH_ASSOC; protected $attrCase = PDO::CASE_LOWER; protected static $event = []; ;數據庫連接參數配置 protected $config = [ 'type' => '', 'hostname' => '', 'database' => '', 'username' => '', 'password' => '', 'hostport' => '', 'dsn' => '', 'params' => [], 'charset' => 'utf8', 'prefix' => '', 'debug' => false, 'deploy' => 0, 'rw_separate' => false, 'master_num' => 1, 'slave_no' => '', 'fields_strict' => true, ]; ;PDO連接參數 protected $params = [ PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, PDO::ATTR_STRINGIFY_FETCHES => false, PDO::ATTR_EMULATE_PREPARES => false, ]; ~~~ ### 3-2 public成員方法 #### 1 __construct() 連接構造函數 ~~~ public function __construct(array $config = []) ~~~ > $config:連接配置信息 > 獲取配置參數創建查詢對象。 #### 2 __call() 連接對象方法回調攔截 ~~~ public function __call($method, $args) ~~~ > $method: 調用的方法名 > $args: 調用方法的參數 > 內部調用查詢對象的對應方法 #### 3 getConfig() 獲取數據庫配置 ~~~ public function getConfig($config) ~~~ > $config: 配置名稱 > 返回數據庫配置中對應名稱的值 #### 4 setConfig() 修改數據庫配置 ~~~ public function setConfig($config, $value) ~~~ > $config:配置名稱,$value:配置名稱值 #### 5 connect() 數據庫連接 ~~~ public function connect(array $config = [], $linkNum = 0, $autoConnection = false) ~~~ > $config: 數據庫連接配置 > $linkNum 連接序號 > $autoConnection 自動連接控制(分布式中) #### 6 getDriverName() 獲取數據庫驅動類型 ~~~ public function getDriverName() ~~~ > 返回數據庫驅動類型或者數據庫類型 #### 7 free() 釋放查詢結果 ~~~ public function free() ~~~ > 置空PDOStatement #### 8 getPdo() 獲取PDO對象 ~~~ public function getPdo() ~~~ #### 9 query() 執行數據庫查詢(重點) ~~~ public function query($sql, $bind = [], $fetch = false, $master = false, $returnPdo = false) ~~~ > $sql: 數據庫語句 > $bind: 參數綁定  > $fetch: 是否只返回合并的sql語句 > $master: 是否在主服務器操作 > $returnPdo: 是否返回PDOStatement對象 #### 10 execute() 執行數據庫操作語句(重點) ~~~ public function execute($sql, $bind = [], $fetch = false, $getLastInsID = false) ~~~ > $sql: 數據庫語句 > $bind: 參數綁定 > $fetch: 是否只返回合并的sql語句 > $getLastInsID:是否返回自增ID #### 11 transaction() 執行數據庫事務 ~~~ public function transaction($callback) ~~~ > $callback 數據庫事務回調 #### 12 startTrans()  數據庫事務啟動 ~~~ public function startTrans($label = '') ~~~ > $label:事務標識 #### 13 commit() 數據庫事務手動提交 ~~~ public function commit($label = '') ~~~ > $label:事務標識 #### 14 rollback() 數據庫事務回滾 ~~~ public function rollback() ~~~ #### 15 batchQuery() 數據庫語句數組執行 ~~~ public function batchQuery($sql = []) ~~~ > $sql:數據庫語句數組 #### 16 parseSqlTable() 數據庫表前綴替換 ~~~ public function parseSqlTable($sql) ~~~ > $sql:數據庫語句 #### 17 getQueryTimes() 獲取查詢次數 ~~~ public function getQueryTimes($execute = false) ~~~ > $execute:是否返回執行次數 #### 18 getExecuteTimes() 獲取執行次數 ~~~ public function getExecuteTimes() ~~~ #### 19 close() 關閉數據庫 ~~~ public function close() ~~~ #### 20 getLastSql() 獲取最后一次查詢的sql語句 ~~~ public function getLastSql() ~~~ #### 21 getLastInsID() 獲取最后插入的ID ~~~ public function getLastInsID() ~~~ #### 22 getError() 獲取最后的錯誤信息 ~~~ public function getError() ~~~ #### 23 quote() sql指令安全過濾 ~~~ public function quote($str) ~~~ > $str:待過濾sql語句 #### 24 listen() 注冊sql監聽回調 ~~~ public function listen($callback) ~~~ > $callback: 監聽回調數組鍵名為事件名,鍵值為回調 #### 25 __destruct() 數據庫析構方法 ~~~ public function __destruct() ~~~ > 釋放數據庫資源 ### 3-3 abstract成員方法 #### 1 parseDsn() 解析DSN配置 ~~~ abstract protected function parseDsn($config); ~~~ > 在具體類型的數據庫連接中實現 ### 3-4 protected成員方法 #### 1 fieldCase() 數據庫表字段大小寫轉換 ~~~ protected function fieldCase($info) ~~~ > $info 字段信息 > 根據PDO參數轉換對應字段大小寫 #### 2 getBindSql() 組織SQL語句 ~~~ protected function getBindSql($sql, array $bind = []) ~~~ > $sql: sql語句 > $bind: 綁定參數列表 > 返回組織的SQL語句 #### 3 bindValue() 參數綁定處理 ~~~ protected function bindValue(array $bind = []) ~~~ > $bind:綁定參數列表 #### 4 getResult() 獲取數據集 ~~~ protected function getResult() ~~~ > 調用PDO的fetchAll()獲取操作結果 #### 5 debug() 數據庫調試操作 ~~~ protected function debug($start) ~~~ > $start:true,數據庫調試開始;false,數據庫調試結束 #### 6 trigger() 觸發SQL事件 ~~~ protected function trigger($sql, $runtime, $explain = []) ~~~ > $sql語句 > $runtime sql運行時間 > $explain sql分析 #### 7 initConnect() 數據庫連接初始化 ~~~ protected function initConnect($master = true) ~~~ > $master:是否主服務器連接 #### 8 multiConnect() 主數據庫連接 ~~~ protected function multiConnect($master = false) ~~~ > $master:是否主服務器連接 ### 3-5 數據庫連接驅動(db\connector\) 數據庫連接實現為下不同類型數據庫的連接 目前包含Mysql,Oracle,Pgsql,Sqlite,Sqlsrv等數據庫 各種數據庫連接主要包含的方法如下 ~~~ ;解析DSN字符串 protected function parseDsn($config) ;獲取數據庫表字段信息 public function getFields($tableName) ;獲取數據庫表單信息 public function getTables($dbName = '') ;sql性能分析 protected function getExplain($sql) ~~~ ## 4 數據庫查詢(Query.php) ### 4-1 成員變量 ~~~ ;連接對象,驅動類型 protected $connection; protected $driver; ;查詢參數,綁定參數 protected $options = []; protected $bind = []; ~~~ ### 4-2 public成員方法 #### 1 __construct() 構造查詢對象 ~~~ public function __construct($connection = '') ~~~ > $connection:連接對象 > 初始化連接對象$this->connection和連接類型$this->driver #### 2 __call() 對象方法調用攔截 ~~~ public function __call($method, $args) ~~~ > $method:調用的方法名 > $args:調用方法的參數 > 內部調用where()->find(),或者where()->value() #### 3 value() 獲取某個字段的值 ~~~ public function value($field) ~~~ > $field:字段名 > #### 4 column() 獲取某個列的數組 ~~~ public function column($field, $key = '') ~~~ > $filed:字段名或字段數組名 > $key:索引 #### 5 count() COUNT查詢 ~~~ public function count($field = '*') ~~~ > $filed:統計的列字段名稱 #### 6 sum() SUM查詢 ~~~ public function sum($field = '*') ~~~ > $field:求和的列字段名稱 #### 7 min() MIN查詢 ~~~ public function min($field = '*') ~~~ > $filed:求最小值的列字段名稱 #### 8 max() MAX查詢 ~~~ public function max($field = '*') ~~~ > $field:求最大值的列字段名稱 #### 9 avg() AVG查詢 ~~~ public function avg($field = '*') ~~~ > $field:求平均值的列字段名稱 #### 10 setField() 修改字段的值 ~~~ public function setField($field, $value = '') ~~~ > $field:修改的字段列名稱 > $value:字段值 #### 11 setInc() 字段自增 ~~~ public function setInc($field, $step = 1, $lazyTime = 0) ~~~ > $field:自增的字段列名稱 > $step:自增的值 > $lazyTime:延遲的值 #### 12 setDec() 字段自減 ~~~ public function setDec($field, $step = 1, $lazyTime = 0) ~~~ > $field:自減的字段列名稱 > $step:自減的值 > $lazyTime:延遲時間 #### 13 joins() join查詢 ~~~ public function join($join, $condition = null, $type = 'INNER') ~~~ > $join:關聯的表信息 > $condition:查詢條件 > $type:joins類型 #### 14 union() union查詢 ~~~ public function union($union, $all = false) ~~~ > $union:union語句 > $all: #### 15 field() 指定查詢字段 ~~~ public function field($field, $except = false, $tableName = '', $prefix = '', $alias = '') ~~~ > $filed:字段名 > $except: 字段排除控制 > $tableName: 數據表名 > $prefix: 字段前綴 > $alias: 別名前綴 #### 16 where() 指定查詢條件 ~~~ public function where($field, $op = null, $condition = null) ~~~ > $field:字段名 > $op:查詢表達式 > $condition:查詢條件 #### 17 whereOr() Or查詢條件 ~~~ public function whereOr($field, $op = null, $condition = null) ~~~ > $field:字段名 > $op:查詢表達式 > $condition:查詢條件 #### 18 whereExist() whereOrExist() whereNotExist() whereOrNotExist() 查詢條件 ~~~ public function whereExist($where) public function whereOrExist($where) public function whereNotExist($where) public function whereOrNotExist($where) ~~~ > $where:條件表達式 #### 19 limit() limit生成 ~~~ public function limit($offset, $length = null) ~~~ > $offset:起始位置 > $length:獲取長度 #### 20 page() 分頁查詢 ~~~ public function page($page, $listRows = null) ~~~ > $page:頁數 > $listRows:每頁數量 #### 21 table() From語句 ~~~ public function table($table) ~~~ > $table:操作表名稱 #### 22 using() USING語句 ~~~ public function using($using) ~~~ #### 23 order() ORDER語句 ~~~ public function order($field, $order = null) ~~~ > $field:排序字段 > $order:排序控制 #### 24 cache() 查詢緩存 ~~~ public function cache($key = true, $expire = null) ~~~ > $key:緩存控制 > $expire:緩存時間 #### 25 group() GROUP語句 ~~~ public function group($group) ~~~ #### 26 having() HAVING語句 ~~~ public function having($having) ~~~ #### 27 lock() LOCK語句 ~~~ public function lock($lock = false) ~~~ #### 28 distinct() DISTINCT語句 ~~~ public function distinct($distinct) ~~~ #### 29 alias() 數據表別名 ~~~ public function alias($alias) ~~~ #### 30 force() 強制索引 ~~~ public function force($force) ~~~ #### 31 comment() 注釋語句 ~~~ public function comment($comment) ~~~ #### 32 fetchSql() 是否返回SQL語句 ~~~ public function fetchSql($fetch = true) ~~~ #### 33 fetchPdo() 是否返回Pdo ~~~ public function fetchPdo($pdo = true) ~~~ #### 34 master() 是否主服務器 ~~~ public function master() ~~~ #### 35 strict() 是否嚴格檢查字段名 ~~~ public function strict($strict = true) ~~~ #### 36 failException() 是否拋出異常 ~~~ public function failException($fail = true) ~~~ #### 37 model() 指定當前模型 ~~~ public function model($model) ~~~ #### 38 name() 指定當前模型名 ~~~ public function name($name) ~~~ #### 39 getTable() 獲取當前的數據表 ~~~ public function getTable() ~~~ #### 40 getTableInfo() 獲取數據表信息 ~~~ public function getTableInfo($tableName = '', $fetch = '') ~~~ #### 41 getPk() 獲取主鍵 ~~~ public function getPk($table = '') ~~~ #### 42 bind() 參數綁定處理 ~~~ public function bind($key, $value = false, $type = PDO::PARAM_STR) ~~~ #### 43 isBind() 檢查是否綁定參數 ~~~ public function isBind($key) ~~~ #### 44 getOptions() 獲取查詢參數 ~~~ public function getOptions($name = '') ~~~ #### 45 with() 關聯查詢JOIN預查詢 ~~~ public function with($with) ~~~ #### 46 via() 設置字段的表別名 ~~~ public function via($via = '') ~~~ #### 47 relation() 設置關聯查詢 ~~~ public function relation($relation) ~~~ #### 48 insert() 添加數據 ~~~ public function insert(array $data, $replace = false, $getLastInsID = false) ~~~ #### 49 insertGetId() 添加數據獲取自增ID ~~~ public function insertGetId(array $data, $replace = false) ~~~ #### 50 insertAll() 批量添加數據 ~~~ public function insertAll(array $dataSet) ~~~ #### 51 selectInsert() 添加查詢結果到數據庫 ~~~ public function selectInsert($fields, $table) ~~~ #### 52 update() 更新數據 ~~~ public function update(array $data) ~~~ #### 53 select() 查詢多條數據 ~~~ public function select($data = []) ~~~ #### 54 find() 查詢單條數據 ~~~ public function find($data = []) ~~~ #### 55 chunk() 分批數據返回處理 ~~~ public function chunk($count, $callback, $column = null) ~~~ #### 56 getBind() 獲取綁定參數并清空 ~~~ public function getBind() ~~~ #### 57 buildSql() 構造子查詢 ~~~ public function buildSql($sub = true) ~~~ #### 58 delete() 刪除數據 ~~~ public function delete($data = []) ~~~ #### 59 parseExpress() 檢查查詢參數 ~~~ public function parseExpress() ~~~ ### 4-3 protected成員方法 #### 1 builder() 創建查詢語句構建對象 ~~~ protected function builder() ~~~ > 根據$this->driver數據庫類型創建對應構建對象 > 設置當前查詢對象 setQuery() #### 2 lazyWrite() 延遲更新時間 ~~~ protected function lazyWrite($guid, $step, $lazyTime) ~~~ > $guid:寫入標識 > $step:寫入步進值 > $lazyTime:寫入的延遲時間 #### 3 parseWhereExp() 合成查詢下條件 ~~~ protected function parseWhereExp($operator, $field, $op, $condition, $param = []) ~~~ > $operator:條件緩存鍵名 > $field: 查詢字段 > $op:查詢表達式 > $condition:查詢條件 > $param:查詢參數 #### 4 parsePkWhere() 解析主鍵為查詢條件 ~~~ protected function parsePkWhere($data, &$options) ~~~ ## 5 查詢語句構造(Builder.php) ### 5-1 成員變量 ~~~ ;數據庫連接實例,查詢實例 protected $connection; protected $query; ;查詢參數 protected $options = []; ;運算符轉換數組 protected $exp = []; ;語句構造模板 protected $selectSql; protected $insertSql; protected $insertAllSql; protected $updateSql; protected $deleteSql; ~~~ ### 5-2 public 成員方法 #### 1 __construct() 構造函數 ~~~ public function __construct($connection) ~~~ > 初始化數據庫連接對象 #### 2 setQuery() 設置Query對象 ~~~ public function setQuery($query) ~~~ #### 3 buildWhere() 生成where語句 ~~~ public function buildWhere($where, $table) ~~~ #### 4 select() 生成select語句 ~~~ public function select($options = []) ~~~ #### 5 insert() 生成insert語句 ~~~ public function insert(array $data, $options = [], $replace = false) ~~~ #### 6 insertAll() 生成InsertAll語句 ~~~ public function insertAll($dataSet, $options) ~~~ #### 7 selectInsert() 生成selectinsert語句 ~~~ public function selectInsert($fields, $table, $options) ~~~ #### 8 update() 生成update語句 ~~~ public function update($data, $options) ~~~ #### 9 delete() 生成delete語句 ~~~ public function delete($options) ~~~ ### 5-3 protected 成員方法 ~~~~ ;Table,Data,Key,Value,Field,Table,Where等解析 protected function parseSqlTable($sql) protected function parseData($data, $options) protected function parseKey($key) protected function parseValue($value) protected function parseField($fields) protected function parseTable($tables) protected function parseWhere($where, $table) ;where子單元解析,閉包子查詢解析,Limit解析,Join解析,Order解析,Group解析,Having解析,Comment解析,Distinct解析,Union解析,index解析,Lock解析 protected function parseWhereItem($key, $val, $rule = '') protected function parseClosure($call, $show = true) protected function parseLimit($limit) protected function parseJoin($join) protected function parseOrder($order) protected function parseGroup($group) protected function parseHaving($having) protected function parseComment($comment) protected function parseDistinct($distinct) protected function parseUnion($union) protected function parseForce($index) protected function parseLock($lock = false) ~~~~ ### 5-4 數據庫語句構造驅動(\db\builder\) 在構造驅動目錄下實現了針對不同數據庫的語句生成驅動 目前包含Mysql,Oracle,Pgsql,Sqlite,Sqlsrv6種 其中的主要方法為Builder.php的方法覆蓋或者擴展 ~~~ ;字段和表名處理 protected function parseKey($key) ;隨機排序 protected function parseRand() ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看