午夜视频免费看_日韩三级电影网站_国产精品久久一级_亚洲一级在线播放_人妻体内射精一区二区三区_91夜夜揉人人捏人人添红杏_91福利在线导航_国产又粗又猛又黄又爽无遮挡_欧美日韩一区在线播放_中文字幕一区二区三区四区不卡 _日日夜夜精品视频免费观看_欧美韩日一区二区三区

主頁 > 知識庫 > 基于Mysql的Sequence實現(xiàn)方法

基于Mysql的Sequence實現(xiàn)方法

熱門標簽:電話機器人免費嗎 地圖標注圖標素材入駐 電銷機器人價格多少錢一臺 龍圖酒吧地圖標注 好搜地圖標注 怎么辦理400電話呢 400電話申請什么好 百度地圖標注地方備注 怎么申請400電話申請

團隊更換新框架。新的業(yè)務(wù)全部使用新的框架,甚至是新的數(shù)據(jù)庫--Mysql。

這邊之前一直是使用oracle,各種訂單號、流水號、批次號啥的,都是直接使用oracle的sequence提供的數(shù)字序列號?,F(xiàn)在數(shù)據(jù)庫更換成Mysql了,顯然以前的老方法不能適用了。

需要新寫一個:

•分布式場景使用

•滿足一定的并發(fā)要求

找了一些相關(guān)的資料,發(fā)現(xiàn)mysql這方面的實現(xiàn),原理都是一條數(shù)據(jù)庫記錄,不斷update它的值。然后大部分的實現(xiàn)方案,都用到了函數(shù)。

貼一下網(wǎng)上的代碼:

基于mysql函數(shù)實現(xiàn)

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

CREATE TABLE `t_sequence` (
`sequence_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '序列名稱' ,
`value` int(11) NULL DEFAULT NULL COMMENT '當前值' ,
PRIMARY KEY (`sequence_name`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
ROW_FORMAT=COMPACT
;

獲取下一個值

CREATE DEFINER = `root`@`localhost` FUNCTION `nextval`(sequence_name varchar(64))
 RETURNS int(11)
BEGIN
 declare current integer;
 set current = 0;
 
 update t_sequence t set t.value = t.value + 1 where t.sequence_name = sequence_name;
 select t.value into current from t_sequence t where t.sequence_name = sequence_name;

 return current;
end;

并發(fā)場景有可能會出問題,雖然可以在業(yè)務(wù)層加鎖,但分布式場景就無法保證了,然后效率應該也不會高。

自己實現(xiàn)一個,java版

原理:

•讀取一條記錄,緩存一個數(shù)據(jù)段,如:0-100,將記錄的當前值從0修改為100

•數(shù)據(jù)庫樂觀鎖更新,允許重試

•讀取數(shù)據(jù)從緩存中讀取,用完再讀取數(shù)據(jù)庫

不廢話,上代碼:

基于java實現(xiàn)

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

每次update,都是將SEQ_VALUE設(shè)置為SEQ_VALUE+STEP

CREATE TABLE `t_pub_sequence` (
 `SEQ_NAME` varchar(128) CHARACTER SET utf8 NOT NULL COMMENT '序列名稱',
 `SEQ_VALUE` bigint(20) NOT NULL COMMENT '目前序列值',
 `MIN_VALUE` bigint(20) NOT NULL COMMENT '最小值',
 `MAX_VALUE` bigint(20) NOT NULL COMMENT '最大值',
 `STEP` bigint(20) NOT NULL COMMENT '每次取值的數(shù)量',
 `TM_CREATE` datetime NOT NULL COMMENT '創(chuàng)建時間',
 `TM_SMP` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間',
 PRIMARY KEY (`SEQ_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流水號生成表';

sequence接口

/**
 * p>/p>
 * @author coderzl
 * @Title MysqlSequence
 * @Description 基于mysql數(shù)據(jù)庫實現(xiàn)的序列
 * @date 2017/6/6 23:03
 */
public interface MysqlSequence {
 /**
  * p>
  * 獲取指定sequence的序列號
  * /p>
  * @param seqName sequence名
  * @return String 序列號
  */
 public String nextVal(String seqName);
}

序列區(qū)間

用于本地緩存一段序列,從min到max區(qū)間

/**
 * p>/p>
 *
 * @author coderzl
 * @Title SequenceRange
 * @Description 序列區(qū)間,用于緩存序列
 * @date 2017/6/6 22:58
 */
 @Data
public class SequenceRange {
 private final long  min;
 private final long  max;
 /** */
 private final AtomicLong value;
 /** 是否超限 */
 private volatile boolean over = false;

 /**
  * 構(gòu)造.
  *
  * @param min 
  * @param max 
  */
 public SequenceRange(long min, long max) {
  this.min = min;
  this.max = max;
  this.value = new AtomicLong(min);
 }

 /**
  * p>Gets and increment/p>
  *
  * @return 
  */
 public long getAndIncrement() {
  long currentValue = value.getAndIncrement();
  if (currentValue > max) {
   over = true;
   return -1;
  }

  return currentValue;
 }

} 

BO

對應數(shù)據(jù)庫記錄

@Data
public class MysqlSequenceBo {
 /**
  * seq名
  */
 private String seqName;
 /**
  * 當前值
  */
 private Long seqValue;
 /**
  * 最小值
  */
 private Long minValue;
 /**
  * 最大值
  */
 private Long maxValue;
 /**
  * 每次取值的數(shù)量
  */
 private Long step;
 /** */
 private Date tmCreate;
 /** */
 private Date tmSmp;

 public boolean validate(){
  //一些簡單的校驗。如當前值必須在最大最小值之間。step值不能大于max與min的差
  if (StringUtil.isBlank(seqName) || minValue  0 || maxValue = 0 || step = 0 || minValue >= maxValue || maxValue - minValue = step ||seqValue  minValue || seqValue > maxValue ) {
   return false;
  }
  return true; 
 }
}

DAO

增刪改查,其實就用到了改和查

public interface MysqlSequenceDAO {
 /**
 * 
 */
 public int createSequence(MysqlSequenceBo bo);

 public int updSequence(@Param("seqName") String seqName, @Param("oldValue") long oldValue ,@Param("newValue") long newValue);

 public int delSequence(@Param("seqName") String seqName);

 public MysqlSequenceBo getSequence(@Param("seqName") String seqName);

 public ListMysqlSequenceBo> getAll();
}

Mapper

?xml version="1.0" encoding="UTF-8" ?>
!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
mapper namespace="com.xxxxx.core.sequence.impl.dao.MysqlSequenceDAO" >
 resultMap id="BaseResultMap" type="com.xxxxx.core.sequence.impl.MysqlSequenceBo" >
  result column="SEQ_NAME" property="seqName" jdbcType="VARCHAR" />
  result column="SEQ_VALUE" property="seqValue" jdbcType="BIGINT" />
  result column="MIN_VALUE" property="minValue" jdbcType="BIGINT" />
  result column="MAX_VALUE" property="maxValue" jdbcType="BIGINT" />
  result column="STEP" property="step" jdbcType="BIGINT" />
  result column="TM_CREATE" property="tmCreate" jdbcType="TIMESTAMP" />
  result column="TM_SMP" property="tmSmp" jdbcType="TIMESTAMP" />
 /resultMap>
 delete id="delSequence" parameterType="java.lang.String" >
  delete from t_pub_sequence
  where SEQ_NAME = #{seqName,jdbcType=VARCHAR}
 /delete>
 insert id="createSequence" parameterType="com.xxxxx.core.sequence.impl.MysqlSequenceBo" >
  insert into t_pub_sequence (SEQ_NAME,SEQ_VALUE,MIN_VALUE,MAX_VALUE,STEP,TM_CREATE)
  values (#{seqName,jdbcType=VARCHAR}, #{seqValue,jdbcType=BIGINT},
  #{minValue,jdbcType=BIGINT}, #{maxValue,jdbcType=BIGINT}, #{step,jdbcType=BIGINT},
  now())
 /insert>
 update id="updSequence" parameterType="com.xxxxx.core.sequence.impl.MysqlSequenceBo" >
  update t_pub_sequence
  set SEQ_VALUE = #{newValue,jdbcType=BIGINT}
  where SEQ_NAME = #{seqName,jdbcType=VARCHAR} and SEQ_VALUE = #{oldValue,jdbcType=BIGINT}
 /update>

 select id="getAll" resultMap="BaseResultMap" >
  select SEQ_NAME, SEQ_VALUE, MIN_VALUE, MAX_VALUE, STEP
  from t_pub_sequence
 /select>

 select id="getSequence" resultMap="BaseResultMap" >
  select SEQ_NAME, SEQ_VALUE, MIN_VALUE, MAX_VALUE, STEP
  from t_pub_sequence
  where SEQ_NAME = #{seqName,jdbcType=VARCHAR}
 /select>
/mapper>

接口實現(xiàn)

@Repository("mysqlSequence")
public class MysqlSequenceImpl implements MysqlSequence{

 @Autowired
 private MysqlSequenceFactory mysqlSequenceFactory;
 /**
  * p>
  * 獲取指定sequence的序列號
  * /p>
  *
  * @param seqName sequence名
  * @return String 序列號
  * @author coderzl
  */
 @Override
 public String nextVal(String seqName) {
  return Objects.toString(mysqlSequenceFactory.getNextVal(seqName));
 }
}

工廠

工廠只做了兩件事

•服務(wù)啟動的時候,初始化數(shù)據(jù)庫中所有sequence【完成序列區(qū)間緩存】

•獲取sequence的下一個值

@Component
public class MysqlSequenceFactory {

 private final Lock lock = new ReentrantLock();

 /** */
 private MapString,MysqlSequenceHolder> holderMap = new ConcurrentHashMap>();

 @Autowired
 private MysqlSequenceDAO msqlSequenceDAO;
 /** 單個sequence初始化樂觀鎖更新失敗重試次數(shù) */
 @Value("${seq.init.retry:5}")
 private int initRetryNum;
 /** 單個sequence更新序列區(qū)間樂觀鎖更新失敗重試次數(shù) */
 @Value("${seq.get.retry:20}")
 private int getRetryNum;

 @PostConstruct
 private void init(){
  //初始化所有sequence
  initAll();
 }


 /**
  * p> 加載表中所有sequence,完成初始化 /p>
  * @return void
  * @author coderzl
  */
 private void initAll(){
  try {
   lock.lock();
   ListMysqlSequenceBo> boList = msqlSequenceDAO.getAll();
   if (boList == null) {
    throw new IllegalArgumentException("The sequenceRecord is null!");
   }
   for (MysqlSequenceBo bo : boList) {
    MysqlSequenceHolder holder = new MysqlSequenceHolder(msqlSequenceDAO, bo,initRetryNum,getRetryNum);
    holder.init();
    holderMap.put(bo.getSeqName(), holder);
   }
  }finally {
   lock.unlock();
  }
 }


 /**
  * p> /p>
  * @param seqName
  * @return long
  * @author coderzl
  */
 public long getNextVal(String seqName){
  MysqlSequenceHolder holder = holderMap.get(seqName);
  if (holder == null) {
   try {
    lock.lock();
    holder = holderMap.get(seqName);
    if (holder != null){
     return holder.getNextVal();
    }
    MysqlSequenceBo bo = msqlSequenceDAO.getSequence(seqName);
    holder = new MysqlSequenceHolder(msqlSequenceDAO, bo,initRetryNum,getRetryNum);
    holder.init();
    holderMap.put(seqName, holder);
   }finally {
    lock.unlock();
   }
  }
  return holder.getNextVal();
 }

}

單一sequence的Holder

•init() 初始化 其中包括參數(shù)校驗,數(shù)據(jù)庫記錄更新,創(chuàng)建序列區(qū)間

•getNextVal() 獲取下一個值

public class MysqlSequenceHolder {

 private final Lock lock    = new ReentrantLock();

 /** seqName */
 private String seqName;

 /** sequenceDao */
 private MysqlSequenceDAO sequenceDAO;

 private MysqlSequenceBo sequenceBo;
 /** */
 private SequenceRange sequenceRange;
 /** 是否初始化 */
 private volatile boolean  isInitialize  = false;
 /** sequence初始化重試次數(shù) */
 private int initRetryNum;
 /** sequence獲取重試次數(shù) */
 private int getRetryNum;

 /**
  * p> 構(gòu)造方法 /p>
  * @Title MysqlSequenceHolder
  * @param sequenceDAO 
  * @param sequenceBo
  * @param initRetryNum 初始化時,數(shù)據(jù)庫更新失敗后重試次數(shù)
  * @param getRetryNum 獲取nextVal時,數(shù)據(jù)庫更新失敗后重試次數(shù)
  * @return
  * @author coderzl
  */
 public MysqlSequenceHolder(MysqlSequenceDAO sequenceDAO, MysqlSequenceBo sequenceBo,int initRetryNum,int getRetryNum) {
  this.sequenceDAO = sequenceDAO;
  this.sequenceBo = sequenceBo;
  this.initRetryNum = initRetryNum;
  this.getRetryNum = getRetryNum;
  if(sequenceBo != null)
   this.seqName = sequenceBo.getSeqName();
 }

 /**
  * p> 初始化 /p>
  * @Title init
  * @param
  * @return void
  * @author coderzl
  */
 public void init(){
  if (isInitialize == true) {
   throw new SequenceException("[" + seqName + "] the MysqlSequenceHolder has inited");
  }
  if (sequenceDAO == null) {
   throw new SequenceException("[" + seqName + "] the sequenceDao is null");
  }
  if (seqName == null || seqName.trim().length() == 0) {
   throw new SequenceException("[" + seqName + "] the sequenceName is null");
  }
  if (sequenceBo == null) {
   throw new SequenceException("[" + seqName + "] the sequenceBo is null");
  }
  if (!sequenceBo.validate()){
   throw new SequenceException("[" + seqName + "] the sequenceBo validate fail. BO:"+sequenceBo);
  }
  // 初始化該sequence
  try {
   initSequenceRecord(sequenceBo);
  } catch (SequenceException e) {
   throw e;
  }
  isInitialize = true;
 }

 /**
  * p> 獲取下一個序列號 /p>
  * @Title getNextVal
  * @param
  * @return long
  * @author coderzl
  */
 public long getNextVal(){
  if(isInitialize == false){
   throw new SequenceException("[" + seqName + "] the MysqlSequenceHolder not inited");
  }
  if(sequenceRange == null){
   throw new SequenceException("[" + seqName + "] the sequenceRange is null");
  }
  long curValue = sequenceRange.getAndIncrement();

  if(curValue == -1){
   try{
    lock.lock();
    curValue = sequenceRange.getAndIncrement();
    if(curValue != -1){
     return curValue;
    }
    sequenceRange = retryRange();
    curValue = sequenceRange.getAndIncrement();
   }finally {
    lock.unlock();
   }
  }
  return curValue;
 }

 /**
  * p> 初始化當前這條記錄 /p>
  * @Title initSequenceRecord
  * @Description
  * @param sequenceBo
  * @return void
  * @author coderzl
  */
 private void initSequenceRecord(MysqlSequenceBo sequenceBo){
  //在限定次數(shù)內(nèi),樂觀鎖更新數(shù)據(jù)庫記錄
  for(int i = 1; i  initRetryNum; i++){
   //查詢bo
   MysqlSequenceBo curBo = sequenceDAO.getSequence(sequenceBo.getSeqName());
   if(curBo == null){
    throw new SequenceException("[" + seqName + "] the current sequenceBo is null");
   }
   if (!curBo.validate()){
    throw new SequenceException("[" + seqName + "] the current sequenceBo validate fail");
   }
   //改變當前值
   long newValue = curBo.getSeqValue()+curBo.getStep();
   //檢查當前值
   if(!checkCurrentValue(newValue,curBo)){
    newValue = resetCurrentValue(curBo);
   }
   int result = sequenceDAO.updSequence(sequenceBo.getSeqName(),curBo.getSeqValue(),newValue);
   if(result > 0){
    sequenceRange = new SequenceRange(curBo.getSeqValue(),newValue - 1);
    curBo.setSeqValue(newValue);
    this.sequenceBo = curBo;
    return;
   }else{
    continue;
   }
  }
  //限定次數(shù)內(nèi),更新失敗,拋出異常
  throw new SequenceException("[" + seqName + "] sequenceBo update error");
 }

 /**
  * p> 檢查新值是否合法 新的當前值是否在最大最小值之間/p>
  * @param curValue
  * @param curBo
  * @return boolean
  * @author coderzl
  */
 private boolean checkCurrentValue(long curValue,MysqlSequenceBo curBo){
  if(curValue > curBo.getMinValue()  curValue = curBo.getMaxValue()){
   return true;
  }
  return false;
 }

 /**
  * p> 重置sequence當前值 :當前sequence達到最大值時,重新從最小值開始 /p>
  * @Title resetCurrentValue
  * @param curBo
  * @return long
  * @author coderzl
  */
 private long resetCurrentValue(MysqlSequenceBo curBo){
  return curBo.getMinValue();
 }

 /**
  * p> 緩存區(qū)間使用完畢時,重新讀取數(shù)據(jù)庫記錄,緩存新序列段 /p>
  * @Title retryRange
  * @param SequenceRange
  * @author coderzl
  */
 private SequenceRange retryRange(){
  for(int i = 1; i  getRetryNum; i++){
   //查詢bo
   MysqlSequenceBo curBo = sequenceDAO.getSequence(sequenceBo.getSeqName());
   if(curBo == null){
    throw new SequenceException("[" + seqName + "] the current sequenceBo is null");
   }
   if (!curBo.validate()){
    throw new SequenceException("[" + seqName + "] the current sequenceBo validate fail");
   }
   //改變當前值
   long newValue = curBo.getSeqValue()+curBo.getStep();
   //檢查當前值
   if(!checkCurrentValue(newValue,curBo)){
    newValue = resetCurrentValue(curBo);
   }
   int result = sequenceDAO.updSequence(sequenceBo.getSeqName(),curBo.getSeqValue(),newValue);
   if(result > 0){
    sequenceRange = new SequenceRange(curBo.getSeqValue(),newValue - 1);
    curBo.setSeqValue(newValue);
    this.sequenceBo = curBo;
    return sequenceRange;
   }else{
    continue;
   }
  }
  throw new SequenceException("[" + seqName + "] sequenceBo update error");

 }
}

總結(jié)

•當服務(wù)重啟或異常的時候,會丟失當前服務(wù)所緩存且未用完的序列

•分布式場景,多個服務(wù)同時初始化,或者重新獲取sequence時,樂觀鎖會保證彼此不沖突。A服務(wù)獲取0-99,B服務(wù)會獲取100-199,以此類推

•當該sequence獲取較為頻繁時,增大step值,能提升性能。但同時服務(wù)異常時,損失的序列也較多

•修改數(shù)據(jù)庫里sequence的一些屬性值,比如step,max等,再下一次從數(shù)據(jù)庫獲取時,會啟用新的參數(shù)

•sequence只是提供了有限個序列號(最多max-min個),達到max后,會循環(huán)從頭開始。

•由于sequence會循環(huán),所以達到max后,再獲取,就不會唯一。建議使用sequence來做業(yè)務(wù)流水號時,拼接時間。如:20170612235101+序列號

業(yè)務(wù)id拼接方法

@Service
public class JrnGeneratorService {
 private static final String SEQ_NAME = "T_SEQ_TEST";

 /** sequence服務(wù) */
 @Autowired
 private MySqlSequence mySqlSequence;
 
 public String generateJrn() {
  try {
   String sequence = mySqlSequence.getNextValue(SEQ_NAME);
   sequence = leftPadding(sequence,8);
   Calendar calendar = Calendar.getInstance();
   SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
   String nowdate = sDateFormat.format(calendar.getTime());
   nowdate.substring(4, nowdate.length());
   String jrn = nowdate + sequence + RandomUtil.getFixedLengthRandom(6);//10位時間+8位序列 + 6位隨機數(shù)=24位流水號
   return jrn;
  } catch (Exception e) {
   //TODO
  }
 }
 
 private String leftPadding(String seq,int len){
  String res ="";
  String str ="";
  if(seq.length()len){
   for(int i=0;ilen-seq.length();i++){
    str +="0"; 
   }   
  }
  res =str+seq;
  return res;
  
 }

}

以上這篇基于Mysql的Sequence實現(xiàn)方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • windows下python之mysqldb模塊安裝方法
  • 在Mac OS X中配置Apache+PHP+MySQL運行環(huán)境的詳細步驟
  • MySQL5.7免安裝版配置圖文教程
  • linux實現(xiàn)mysql數(shù)據(jù)庫每天自動備份定時備份
  • MySQL 5.7雙主同步部分表的實現(xiàn)過程詳解
  • oracle、mysql數(shù)據(jù)庫停止與啟動的批處理文件
  • 利用PHP訪問MySql數(shù)據(jù)庫的邏輯操作以及增刪改查的實例講解
  • MySQL curdate()函數(shù)的實例詳解

標簽:浙江 撫順 廣西 汕尾 防疫工作 固原 溫州 內(nèi)江

巨人網(wǎng)絡(luò)通訊聲明:本文標題《基于Mysql的Sequence實現(xiàn)方法》,本文關(guān)鍵詞  基于,Mysql,的,Sequence,實現(xiàn),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《基于Mysql的Sequence實現(xiàn)方法》相關(guān)的同類信息!
  • 本頁收集關(guān)于基于Mysql的Sequence實現(xiàn)方法的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    日本一区二区高清| 97人妻精品视频一区| 亚洲国产精品午夜在线观看| 日韩精品色哟哟| 精品成人在线视频| 欧美日韩国产首页| 国产精品丝袜视频| 欧美第一黄色网| 久久波多野结衣| 91黄色小网站| 日本视频免费观看| 国产午夜精品久久久久久免费视| 免费亚洲电影在线| 欧美日本免费一区二区三区| 91国产丝袜在线放| 成人午夜福利一区二区| 污污视频在线免费看| 欧美性三三影院| 国产精品yjizz| 深夜福利成人| 国产成人av一区二区三区不卡| 风韵丰满熟妇啪啪区老熟熟女| 欧美特黄一区二区三区| 成人久久视频在线观看| 色八戒一区二区三区| 国产在线精品一区二区中文| 精国产品一区二区三区a片| 亚洲欧美激情国产综合久久久| 99久久精品免费看| 国产做受高潮69| 亚洲精品第二页| 91麻豆免费在线观看| 久久久久久久网站| 免费日本黄色网址| 99在线精品观看| 欧美日韩一区二区三区在线免费观看| 欧美人体做爰大胆视频| 欧美精品v日韩精品v国产精品| 精品亚洲视频在线| 久久国产欧美日韩精品| 日韩一区二区在线看片| 国产精品成人在线| 亚洲天堂成人av| 成人app下载| 欧美美女一区二区在线观看| 日韩av电影手机在线| 国产视频在线观看网站| 国产精品无码久久久久成人app| 国产日韩欧美不卡| 国产精品中文字幕在线| 日韩精品在线观看免费| 777亚洲妇女| 动漫av网站免费观看| 男人操女人的视频在线观看欧美| 欧美丝袜丝nylons| 日本老太婆做爰视频| 热久久免费视频| 欧美夫妻性生活视频| 日本成人午夜影院| 最近中文字幕一区二区三区| 精品乱子伦一区二区三区| 成人h动漫精品一区二区下载| 中文成人av在线| av一区二区三区四区电影| 国产精品第5页| 亚洲欧美日韩在线播放| 亚洲欧洲一区二区福利| 免费的国产精品| 国产精品美女无圣光视频| 好吊操视频这里只有精品| 国产麻豆成人传媒免费观看| 亚洲尤物视频网| 国产视频在线观看免费| 国产精品999999| 在线视频你懂得| 色综合天天综合网国产成人网| 中文字幕成人在线视频| 亚洲一区二区三区四区在线| 国产视频九色蝌蚪| 国产欧美一区二区精品忘忧草| 国产精品盗摄久久久| 9.1片黄在线观看| 亚洲精品国产美女| 992在线观看| 国产小视频国产精品| 国产一级一级片| 亚洲日本成人女熟在线观看| 成年人av电影| 久久久久久久久久久久久久久久久久av| 三级网站免费看| 欧美日韩精品二区第二页| 男人的天堂av网| 日韩在线观看高清| 中文字幕在线播放不卡| 亚洲欧美日本另类| 成人午夜视频在线播放| 欧美一级片在线播放| 视频一区二区三区在线| 欧美日韩国产二区| 亚洲精品视频在线看| 亚洲中文字幕无码专区| 中文字幕日韩欧美一区二区三区| 精品国产一区二区三区麻豆免费观看完整版 | 香蕉视频污视频| 欧美va亚洲va| 精品无码m3u8在线观看| 中文字幕日韩在线观看| 亚洲欧洲久久久| 色综合伊人色综合网| 夜夜狠狠擅视频| 国产美女在线精品免费观看| 国产主播第一页| 成人免费看黄网站| 国产精品乱人伦中文| 成人免费观看cn| 日韩极品精品视频免费观看| 天天爽夜夜爽夜夜爽| 日本黄xxxxxxxxx100| 欧美mv日韩mv国产网站| 成人1区2区3区| av日韩在线看| 亚洲人成电影网站| 免费久久99精品国产| 国产精品一区在线观看| 欧美日韩午夜激情| 国产精品111| 91在线观看欧美日韩| 欧美韩国日本综合| 免费成人深夜天涯网站| 国产精品久久激情| 欧美国产乱子伦| 高清国产在线观看| 91探花福利精品国产自产在线| 精品人妻伦一二三区久久| 久久久久国产一区二区三区| 国产在线视频一区二区三区| 日本一二区免费| 欧美成人在线免费视频| 美女久久网站| 亚洲精华国产精华精华液网站| 日韩在线观看你懂的| 丁香天五香天堂综合| 国产毛片精品视频| 国产美女无遮挡永久免费| 免费在线观看黄色小视频| 亚洲欧美日韩在线综合 | 在线免费av播放| 欧美亚洲在线观看| 美女久久久久久久久久久| 国产色爱av资源综合区| 国产aaaaa毛片| 欧美年轻男男videosbes| 空姐吹箫视频大全| 一起草最新网址| 欧美成人午夜电影| 高清成人在线观看| 日韩av一卡二卡三卡| 国产欧美精品一区二区| 精品中文字幕在线观看| 91精品国产综合久| 麻豆tv在线观看| www.成人av.com| 成人国产精品日本在线| 午夜精品一区二区在线观看| 波多野结衣家庭教师在线播放 | 久久国产黄色片| 99久久久久久久| 一区二区视频播放| 玖玖玖国产精品| 91在线视频免费观看| 一区二区三区在线免费视频| 亚洲一区二区美女| 日韩欧美一区二区久久婷婷| 久久成人国产精品| 国产97在线|亚洲| 欧美另类videosbestsex日本| 日韩免费电影一区二区| 一区二区三区入口| 亚洲色婷婷久久精品av蜜桃| 日韩精品电影网站| 久久av一区二区三区漫画| 国产精品一区二区三区在线 | 欧洲美女和动交zoz0z| 日韩一区二区三区视频| 国产精品卡一卡二卡三| 国产综合色视频| 欧美成人午夜精品免费| 久久久精品99| 久久精品国产亚洲AV成人婷婷| 色女人综合av| 一级黄色片播放| 日本精品一区在线| www插插插无码视频网站| 亚洲国产高清国产精品| 国产精品国产亚洲精品看不卡15| 欧美r级电影在线观看| 久久久久久影视| 亚洲日本欧美天堂| 久久一区二区三区四区| 中文字幕人妻一区二| 日韩在线不卡av| 国产综合久久久久影院| 日韩欧美另类在线| 91精品成人久久| 国产又黄又爽免费视频| 亚洲国产欧美视频| www黄色av| 无码人妻aⅴ一区二区三区有奶水| 日本免费在线观看视频| 视频一区二区不卡| 精品日产卡一卡二卡麻豆| 亚洲男人的天堂在线观看| 91国产美女在线观看| 日韩avxxx| 一区二区在线观看免费视频| 欧美人与禽zoz0善交| 国产精品拍拍拍| 萌白酱视频在线| 99久久久久成人国产免费| 成人午夜私人影院| 成人免费视频网站在线观看| 日韩av一区二区在线影视| 精品国产免费视频| 亚洲专区中文字幕| 交换做爰国语对白| 午夜精品久久久内射近拍高清 | 免费黄色网址在线| av中文字幕在线不卡| 神马久久桃色视频| 亚洲中文字幕无码不卡电影| 另类小说视频一区二区| 青草青草久热精品视频在线观看| 国产一区二区三区在线免费| 在线观看色网站| 午夜精品久久久久久久久久久| 精品日本美女福利在线观看| 欧美人妖巨大在线| 美女一区视频| 中文字幕乱码av| 成人av一区二区三区在线观看| 自拍偷拍校园春色| 处破女av一区二区| 欧美精品一区男女天堂| 91理论片午午论夜理片久久| 天天综合网日韩| 欧美 中文字幕| 欧美高清一级片在线| 成人国产亚洲欧美成人综合网| 一级女性全黄久久生活片免费| 亚洲国产婷婷综合在线精品| 精品久久久久久一区| 美女久久网站| 韩剧1988免费观看全集| 亚洲国产123| 91精品国产综合久久国产大片| 17c精品麻豆一区二区免费| 91av福利视频| 岛国av在线免费| 99热这里是精品| 日韩午夜在线播放| 水蜜桃亚洲精品| 日韩 国产 欧美| 亚洲成av人片一区二区梦乃| 精品久久久视频| 欧美黑人极品猛少妇色xxxxx| 久久久国产精彩视频美女艺术照福利| 亚洲性生活视频在线观看| 成人www视频在线观看| 三级影片在线看| 亚洲欧美综合色| 日韩欧美精品免费在线| 欧美精品成人一区二区在线观看| 一级片视频免费观看| 久久久久久久久久久久久女过产乱| 国产精品综合二区| 国产亚洲欧美另类中文| 亚洲欧美日本国产有色| 在线免费观看毛片| 中文字幕中文字幕一区| 亚洲欧美日韩一区二区在线| 成人精品在线视频| 亚洲xxxxx| 不卡av免费在线| 四虎永久免费观看| 91杏吧porn蝌蚪| 久久丝袜美腿综合| 在线区一区二视频| 日韩精品福利片午夜免费观看| 中文字幕永久免费视频| 中文字幕在线观看一区二区| 精品国产户外野外| www.亚洲免费视频| 国产厕所精品在线观看| 日韩欧美一级精品久久| 久久久.com| 久久久久久久尹人综合网亚洲| 日韩精品久久久| 在线成人激情视频| 亚洲日本中文字幕| 欧美午夜久久久| 亚洲成人www| 欧美日韩国产限制| 91黄色免费观看| 欧美日韩aaaaaa| 日韩欧美一级精品久久| 日韩精品在线第一页| 亚洲美女视频网站| 欧美精品久久一区| 欧美美女黄视频| 精品久久香蕉国产线看观看gif| 2024国产精品视频| 久久久久国产精品麻豆ai换脸| 日本三级亚洲精品| 国产99久一区二区三区a片| www黄色网址| 日韩在线卡一卡二| 国产一区不卡视频| 久久这里只有精品首页| 久久99精品一区二区三区 | 97精品国产露脸对白| 久久蜜臀精品av| 亚洲最色的网站| 91福利社在线观看| 日韩亚洲国产中文字幕欧美| 亚洲欧美三级伦理| 欧美精品激情在线| 国产精品一区二区三区久久| 激情视频在线观看一区二区三区| 成人a视频在线观看| 欧美精品v日韩精品v国产精品| 国产精品日韩一区二区三区| 色999日韩自偷自拍美女| 日本熟妇人妻xxxx| 九九九九九伊人| 五月天精品在线| 无码视频一区二区三区| 亚洲av片在线观看| 天天躁日日躁狠狠躁喷水| 国产大陆a不卡| 亚洲三级视频在线观看| 欧美日韩一级片在线观看| 亚洲日本欧美中文幕| 日本精品一区二区三区在线播放视频 | 手机av免费看| 久久久久久av无码免费网站| 国产精品久久久久久免费免熟| 日本视频www色| 日本特黄久久久高潮| 91免费国产视频网站| 黑人巨大精品欧美一区免费视频 | 潘金莲激情呻吟欲求不满视频| 免费观看成人网| 在线观看福利片| 在线观看你懂的网站| 麻豆免费看一区二区三区| 国产三级久久久| 欧美日本在线视频| 欧美老妇交乱视频| 精品国产乱码一区二区三区四区 | 久久大大胆人体| 91系列在线观看| 日本阿v视频在线观看| 污污内射在线观看一区二区少妇| 97超碰在线资源| 久久国产香蕉视频| 粉嫩一区二区三区性色av| 午夜视频在线观看一区二区 | www.欧美国产| 99re这里只有精品视频首页| 色综合久久久久综合体桃花网| 欧美日韩夫妻久久| 久久久久久中文字幕| 国产精品99久久久久久久久久久久| 亚洲一区中文字幕| 婷婷四月色综合| 女同性αv亚洲女同志| 亚洲综合图片网| 成人丝袜高跟foot| 国产精品久久久久久久久免费樱桃 | 国产乱码一区二区三区四区| 日本三级午夜理伦三级三| 麻豆精品一二三| 精品久久久久久中文字幕一区奶水| 4438x亚洲最大成人网| 2019中文字幕在线免费观看| 在线观看日韩羞羞视频| 乱子伦视频在线看| 精品少妇一二三区| 极品少妇xxxx精品少妇偷拍| 欧美午夜激情小视频| 久久久久久久久电影| 免费观看黄色大片| 久久午夜精品视频| 人禽交欧美网站| 欧美日韩美女在线观看| 久久久久久久久国产| 亚洲五码在线观看视频| 国产传媒国产传媒| 性感美女一级片| 久久欧美一区二区| 亚洲精品国产精品国产自| 国产日韩一区欧美| 久草视频福利在线| 五月天综合激情| 99精品久久只有精品| 亚洲精品久久7777777| 精品国产一区二区三| 国产精品无码电影| 成人毛片一区二区三区| 国产精品视频一二三|