1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        基于多數(shù)據(jù)源零代碼生成多個數(shù)據(jù)庫CRUD增刪改查RESTful API接口

        共 13954字,需瀏覽 28分鐘

         ·

        2022-08-04 16:34

        多數(shù)據(jù)源

        回顧

        通過前面文章的介紹,目前已經支持主流數(shù)據(jù)庫,包括MySql,PostgreSql,Oracle,Microsoft SQL Server等,通過配置零代碼實現(xiàn)了CRUD增刪改查RESTful API。采用抽象工廠設計模式,可以無縫切換不同類型的數(shù)據(jù)庫。但是如果需要同時支持不同類型的數(shù)據(jù)庫,如何通過配置進行管理呢?這時候引入多數(shù)據(jù)源功能就很有必要了。

        簡介

        利用spring boot多數(shù)據(jù)源功能,可以同時支持不同類型數(shù)據(jù)庫mysql,oracle,postsql,sql server等,以及相同類型數(shù)據(jù)庫不同的schema。零代碼同時生成不同類型數(shù)據(jù)庫增刪改查RESTful api,且支持同一接口中跨庫數(shù)據(jù)訪問二次開發(fā)。

        UI界面

        配置一個數(shù)據(jù)源,多個從數(shù)據(jù)源,每一個數(shù)據(jù)源相互獨立配置和訪問。

        2f1a230ff6e277ee36b8bd6d981134a1.webp

        核心原理

        配置數(shù)據(jù)庫連接串

        配置application.properties,spring.datasource為默認主數(shù)據(jù)源,spring.datasource.hikari.data-sources[]數(shù)組為從數(shù)據(jù)源

        #primaryspring.datasource.driverClassName=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/crudapi?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=truespring.datasource.username=rootspring.datasource.password=root
        #postgresqlspring.datasource.hikari.data-sources[0].postgresql.driverClassName=org.postgresql.Driverspring.datasource.hikari.data-sources[0].postgresql.url=jdbc:postgresql://localhost:5432/crudapispring.datasource.hikari.data-sources[0].postgresql.username=postgresspring.datasource.hikari.data-sources[0].postgresql.password=postgres
        #sqlserverspring.datasource.hikari.data-sources[1].sqlserver.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriverspring.datasource.hikari.data-sources[1].sqlserver.url=jdbc:sqlserver://localhost:1433;SelectMethod=cursor;DatabaseName=crudapispring.datasource.hikari.data-sources[1].sqlserver.username=saspring.datasource.hikari.data-sources[1].sqlserver.password=Mssql1433#oraclespring.datasource.hikari.data-sources[2].oracle.url=jdbc:oracle:thin:@//localhost:1521/XEPDB1spring.datasource.hikari.data-sources[2].oracle.driverClassName=oracle.jdbc.OracleDriverspring.datasource.hikari.data-sources[2].oracle.username=crudapispring.datasource.hikari.data-sources[2].oracle.password=crudapi
        #mysqlspring.datasource.hikari.data-sources[3].mysql.driverClassName=com.mysql.cj.jdbc.Driverspring.datasource.hikari.data-sources[3].mysql.url=jdbc:mysql://localhost:3306/crudapi2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=truespring.datasource.hikari.data-sources[3].mysql.username=rootspring.datasource.hikari.data-sources[3].mysql.password=root

        動態(tài)數(shù)據(jù)源——DynamicDataSource

        Spring boot提供了抽象類AbstractRoutingDataSource,復寫接口determineCurrentLookupKey, 可以在執(zhí)行查詢之前,設置使用的數(shù)據(jù)源,從而實現(xiàn)動態(tài)切換數(shù)據(jù)源。

        public class DynamicDataSource extends AbstractRoutingDataSource {  @Override  protected Object determineCurrentLookupKey() {    return DataSourceContextHolder.getDataSource();  }}

        數(shù)據(jù)源Context——DataSourceContextHolder

        默認主數(shù)據(jù)源名稱為datasource,從數(shù)據(jù)源名稱保存在ThreadLocal變量CONTEXT_HOLDER里面,ThreadLocal叫做線程變量, 意思是ThreadLocal中填充的變量屬于當前線程, 該變量對其他線程而言是隔離的, 也就是說該變量是當前線程獨有的變量。

        在RestController里面根據(jù)需要提前設置好當前需要訪問的數(shù)據(jù)源key,即調用setDataSource方法,訪問數(shù)據(jù)的時候調用getDataSource方法獲取到數(shù)據(jù)源key,最終傳遞給DynamicDataSource。

        public class DataSourceContextHolder {    //默認數(shù)據(jù)源primary=dataSource    private static final String DEFAULT_DATASOURCE = "dataSource";
        //保存線程連接的數(shù)據(jù)源 private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
        private static final ThreadLocal<String> HEADER_HOLDER = new ThreadLocal<>();
        public static String getDataSource() { String dataSoure = CONTEXT_HOLDER.get(); if (dataSoure != null) { return dataSoure; } else { return DEFAULT_DATASOURCE; } }
        public static void setDataSource(String key) { if ("primary".equals(key)) { key = DEFAULT_DATASOURCE; } CONTEXT_HOLDER.set(key); }
        public static void cleanDataSource() { CONTEXT_HOLDER.remove(); }
        public static void setHeaderDataSource(String key) { HEADER_HOLDER.set(key); }
        public static String getHeaderDataSource() { String dataSoure = HEADER_HOLDER.get(); if (dataSoure != null) { return dataSoure; } else { return DEFAULT_DATASOURCE; } }}

        動態(tài)數(shù)據(jù)庫提供者——DynamicDataSourceProvider

        程序啟動時候,讀取配置文件application.properties中數(shù)據(jù)源信息,構建DataSource并通過接口setTargetDataSources設置從數(shù)據(jù)源。數(shù)據(jù)源的key和DataSourceContextHolder中key一一對應

        @Component@EnableConfigurationProperties(DataSourceProperties.class)@ConfigurationProperties(prefix = "spring.datasource.hikari")public class DynamicDataSourceProvider implements DataSourceProvider {  @Autowired  private DynamicDataSource dynamicDataSource;
        private List<Map<String, DataSourceProperties>> dataSources;
        private Map<Object,Object> targetDataSourcesMap;
        @Resource private DataSourceProperties dataSourceProperties;
        private DataSource buildDataSource(DataSourceProperties prop) { DataSourceBuilder<?> builder = DataSourceBuilder.create(); builder.driverClassName(prop.getDriverClassName()); builder.username(prop.getUsername()); builder.password(prop.getPassword()); builder.url(prop.getUrl()); return builder.build(); }
        @Override public List<DataSource> provide() { Map<Object,Object> targetDataSourcesMap = new HashMap<>(); List<DataSource> res = new ArrayList<>(); if (dataSources != null) { dataSources.forEach(map -> { Set<String> keys = map.keySet(); keys.forEach(key -> { DataSourceProperties properties = map.get(key); DataSource dataSource = buildDataSource(properties); targetDataSourcesMap.put(key, dataSource);
        }); });
        //更新dynamicDataSource this.targetDataSourcesMap = targetDataSourcesMap; dynamicDataSource.setTargetDataSources(targetDataSourcesMap); dynamicDataSource.afterPropertiesSet(); }
        return res; }
        @PostConstruct public void init() { provide(); }
        public List<Map<String, DataSourceProperties>> getDataSources() { return dataSources; }
        public void setDataSources(List<Map<String, DataSourceProperties>> dataSources) { this.dataSources = dataSources; }
        public List<Map<String, String>> getDataSourceNames() { List<Map<String, String>> dataSourceNames = new ArrayList<Map<String, String>>(); Map<String, String> dataSourceNameMap = new HashMap<String, String>(); dataSourceNameMap.put("name", "primary"); dataSourceNameMap.put("caption", "主數(shù)據(jù)源"); dataSourceNameMap.put("database", parseDatabaseName(dataSourceProperties)); dataSourceNames.add(dataSourceNameMap);
        if (dataSources != null) { dataSources.forEach(map -> { Set<Map.Entry<String, DataSourceProperties>> entrySet = map.entrySet(); for (Map.Entry<String, DataSourceProperties> entry : entrySet) { Map<String, String> t = new HashMap<String, String>(); t.put("name", entry.getKey()); t.put("caption", entry.getKey()); DataSourceProperties p = entry.getValue(); t.put("database", parseDatabaseName(p));
        dataSourceNames.add(t); } }); }
        return dataSourceNames; }
        public String getDatabaseName() { List<Map<String, String>> dataSourceNames = this.getDataSourceNames(); String dataSource = DataSourceContextHolder.getDataSource();
        Optional<Map<String, String>> op = dataSourceNames.stream() .filter(t -> t.get("name").toString().equals(dataSource)) .findFirst(); if (op.isPresent()) { return op.get().get("database"); } else { return dataSourceNames.stream() .filter(t -> t.get("name").toString().equals("primary")) .findFirst().get().get("database"); } }

        private String parseDatabaseName(DataSourceProperties p) { String url = p.getUrl(); String databaseName = ""; if (url.toLowerCase().indexOf("databasename") >= 0) { String[] urlArr = p.getUrl().split(";"); for (String u : urlArr) { if (u.toLowerCase().indexOf("databasename") >= 0) { String[] uArr = u.split("="); databaseName = uArr[uArr.length - 1]; } } } else { String[] urlArr = p.getUrl().split("\\?")[0].split("/"); databaseName = urlArr[urlArr.length - 1]; }
        return databaseName; }
        public Map<Object,Object> getTargetDataSourcesMap() { return targetDataSourcesMap; }}

        動態(tài)數(shù)據(jù)源配置——DynamicDataSourceConfig

        首先取消系統(tǒng)自動數(shù)據(jù)庫配置,設置exclude = { DataSourceAutoConfiguration.class }

        @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })public class ServiceApplication {    public static void main(String[] args) {        SpringApplication.run(ServiceApplication.class, args);    }}

        然后自定義Bean,分別定義主數(shù)據(jù)源dataSource和動態(tài)數(shù)據(jù)源dynamicDataSource,并且注入到JdbcTemplate,NamedParameterJdbcTemplate,和DataSourceTransactionManager中,在訪問數(shù)據(jù)時候自動識別對應的數(shù)據(jù)源。

        //數(shù)據(jù)源配置類@Configuration@EnableConfigurationProperties(DataSourceProperties.class)public class DynamicDataSourceConfig {    private static final Logger log = LoggerFactory.getLogger(DynamicDataSourceConfig.class);
        @Resource private DataSourceProperties dataSourceProperties;
        @Bean(name = "dataSource") public DataSource getDataSource(){ DataSourceBuilder<?> builder = DataSourceBuilder.create(); builder.driverClassName(dataSourceProperties.getDriverClassName()); builder.username(dataSourceProperties.getUsername()); builder.password(dataSourceProperties.getPassword()); builder.url(dataSourceProperties.getUrl()); return builder.build(); }
        @Primary //當相同類型的實現(xiàn)類存在時,選擇該注解標記的類 @Bean("dynamicDataSource") public DynamicDataSource dynamicDataSource(){ DynamicDataSource dynamicDataSource = new DynamicDataSource(); //默認數(shù)據(jù)源 dynamicDataSource.setDefaultTargetDataSource(getDataSource());
        Map<Object,Object> targetDataSourcesMap = new HashMap<>(); dynamicDataSource.setTargetDataSources(targetDataSourcesMap); return dynamicDataSource; }
        //事務管理器DataSourceTransactionManager構造參數(shù)需要DataSource //這里可以看到我們給的是dynamicDS這個bean @Bean public PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(dynamicDataSource()); }
        //這里的JdbcTemplate構造參數(shù)同樣需要一個DataSource,為了實現(xiàn)數(shù)據(jù)源切換查詢, //這里使用的也是dynamicDS這個bean @Bean(name = "jdbcTemplate") public JdbcTemplate getJdbc(){ return new JdbcTemplate(dynamicDataSource()); }
        //這里的JdbcTemplate構造參數(shù)同樣需要一個DataSource,為了實現(xiàn)數(shù)據(jù)源切換查詢, //這里使用的也是dynamicDS這個bean @Bean(name = "namedParameterJdbcTemplate") public NamedParameterJdbcTemplate getNamedJdbc(){ return new NamedParameterJdbcTemplate(dynamicDataSource()); }}

        請求頭過濾器——HeadFilter

        攔截所有http請求,從header里面解析出當前需要訪問的數(shù)據(jù)源,然后設置到線程變量HEADER_HOLDER中。

        @WebFilter(filterName = "headFilter", urlPatterns = "/*")public class HeadFilter extends OncePerRequestFilter {    private static final Logger log = LoggerFactory.getLogger(HeadFilter.class);
        @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (!"/api/auth/login".equals(request.getRequestURI()) && !"/api/auth/jwt/login".equals(request.getRequestURI()) && !"/api/auth/logout".equals(request.getRequestURI()) && !"/api/metadata/dataSources".equals(request.getRequestURI())) { String dataSource = request.getParameter("dataSource"); HeadRequestWrapper headRequestWrapper = new HeadRequestWrapper(request); if (StringUtils.isEmpty(dataSource)) { dataSource = headRequestWrapper.getHeader("dataSource"); if (StringUtils.isEmpty(dataSource)) { dataSource = "primary"; headRequestWrapper.addHead("dataSource", dataSource); } }
        DataSourceContextHolder.setHeaderDataSource(dataSource);
        // finish filterChain.doFilter(headRequestWrapper, response); } else { filterChain.doFilter(request, response); } }}

        實際應用

        前面動態(tài)數(shù)據(jù)源配置準備工作已經完成,最后我們定義切面DataSourceAspect

        @Aspectpublic class DataSourceAspect {  private static final Logger log = LoggerFactory.getLogger(DataSourceAspect.class);
        @Pointcut("within(cn.crudapi.api.controller..*)") public void applicationPackagePointcut() { }
        @Around("applicationPackagePointcut()") public Object dataSourceAround(ProceedingJoinPoint joinPoint) throws Throwable { String dataSource = DataSourceContextHolder.getHeaderDataSource(); DataSourceContextHolder.setDataSource(dataSource); try { return joinPoint.proceed(); } finally { DataSourceContextHolder.cleanDataSource(); } }}

        在API對應的controller中攔截,獲取當前的請求頭數(shù)據(jù)源key,然后執(zhí)行joinPoint.proceed(),最后再恢復數(shù)據(jù)源。當然在service內部還可以多次切換數(shù)據(jù)源,只需要調用DataSourceContextHolder.setDataSource()即可。比如可以從mysql數(shù)據(jù)庫讀取數(shù)據(jù),然后保存到oracle數(shù)據(jù)庫中。

        前端集成

        在請求頭里面設置dataSource為對應的數(shù)據(jù)源,比如primary表示主數(shù)據(jù)源,postgresql表示從數(shù)據(jù)源postgresql,具體可以名稱和application.properties配置保持一致。

        首先調用的地方配置dataSource

        const table = {  list: function(dataSource, tableName, page, rowsPerPage, search, query, filter) {    return axiosInstance.get("/api/business/" + tableName,      {        params: {          offset: (page - 1) * rowsPerPage,          limit: rowsPerPage,          search: search,          ...query,          filter: filter        },        dataSource: dataSource      }    );  },}

        然后在axios里面統(tǒng)一攔截配置

        axiosInstance.interceptors.request.use(  function(config) {    if (config.dataSource) {      console.log("config.dataSource = " + config.dataSource);      config.headers["dataSource"] = config.dataSource;    }
        return config; }, function(error) { return Promise.reject(error); });

        效果如下?

        0e23f94f865a61b3c28127a22e4bf36a.webp


        小結

        本文主要介紹了多數(shù)據(jù)源功能,在同一個Java程序中,通過多數(shù)據(jù)源功能,不需要一行代碼,我們就可以得到不同數(shù)據(jù)庫的基本crud功能,包括API和UI。

        注公眾號回復:crudapi,即可獲得源碼和SDK下載地址!

        瀏覽 44
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            欧洲AV在线| 亚洲色五月| 青青草原网址| 逼特逼在线视频| 黑人在线播放| 国产精品久久久91| 激情导航| 黄片无码| 超碰乱伦| 婷婷精品国产a久久综合| 国产成人在线免费| 二区三区免费视频| 色婷婷18正码国产| 免费视频亚洲| 中国操B视频| 日本无码片| 北条麻妃一区二区三区-免费免费高清观看 | 人妻丝袜中出北条麻妃| 伊人在线| 无码av在线观看| 亚洲AV高清| 免费播放婬乱男女婬视频国产| 97人妻人人澡人人爽人人| 高清无码一级片| 操国产美女| 大香蕉精品欧美色综合2025 | www人人操| 91无码国产| 好想被c秘好爽n网址| 天堂在线| 日本无码专区| 午夜福利资源| AV日韩无码| 翔田千里50岁无码| 午夜精品人妻无码| 97九色| 美女国产精品| 国精产品一区一区三区有限公司杨| 伊人五月丁香| 夜夜躁狠狠躁| 成人国产AV网站| 最新中文字幕视频| 猫咪视频大全视频| 99热这里有精品| 综合久久网| 亚洲天堂无码视频| 久久精品视频免费观看| 99精品久久久久久无码| 亚洲无码成人视频| 无码成人午夜在线影院| 福利三区| 亚洲中文综合| 欧美在线视频播放| 91九色91蝌蚪91成人| 日产电影一区二区三区| 无码不卡视频在线| 51乱伦| 強姦婬片A片AAA毛片Mⅴ| 日韩性爱无码| 亚洲成人免费网站| 日韩欧美A片| a片在线免费看| 台湾一区二区| 中文字幕在线国产| 精品视频第一页| 亚洲天堂日本| 综合久久网| 无码人妻精品一区二区三| 69视频国产| 波多野结衣高清无码视频| 91jiujiu| 国产一二区| www.av在线播放| 亚洲美女喷水视频| 女人的天堂AAA| 欧美国产日韩综合在线观看170 | 色天堂在线观看| 伊人中文字幕| 亚洲777| 操逼网123| 日韩成人精品| 中文字幕乱码亚洲中文在线| 青误乐在线播放| 丁香婷婷男人天堂| 大色欧美综合| 小H片在线观看| 人妻超碰在线| 亚洲中文字幕在线观看免费| 思思操在线视频| 国产特黄级AAAAA片免| 性欧美丰满熟妇XXXX性久久久 | 高清一区二区| 88av在线| 波多野结衣视频网站| 日日干日日操| 五月丁香在线观看| 久久毛| 韩国GOGOGO高清| 91大神久久| 91操美女视频| 无码乱伦AV| 亚洲三级自拍| 久久久久久久极品内射| 91婷婷| www.第四色| 久久久久国产视频| 亚洲欧洲免费视频| 国产一级黄色| 肏屄视频在线播放| 天堂va欧美va亚洲va在线| 欧美成人免费A级在线观看| 粉嫩av懂色av蜜臀av熟妇| 日韩无码电| 麻豆AV在线观看| 国产剧情在线| 蜜芽无码| 夜夜躁狠狠躁日日躁av| 操逼小电影| 国产精品免费久久影院| 精品欧美片在线观看步骤| 人人爽亚洲AV人人爽AV人人片| 黑人AV在线播放| 一级成人电影| 中文人妻无码| 亚洲尤物在线| 特级西西444www大精品| 亚洲无码成人视频| 香蕉伊人在线| 99综合| 手机在线小视频| 国内一级A片| 国产一二三区在线| 国产美女免费视频| 99精品国自产在线| 26uuu亚洲| 俺去久久| 伊人成色| 国产欧美在线观看| 久久人妻无码| 97精品人妻一区| 国产91无码精品秘入口| ChineSe露脸老女人| 大香蕉欧美在线| 欧美黄色免费观看| 精品一区在线| 青娱乐极品久久| 51成人免费| 欧美精品在线免费观看| 1000部毛片A片免费视频| h片在线免费观看视频| 911精品人妻一区二区三区A片 | 成人精品在线观看| 99re欧美激情| 亚洲中文字幕无码在线观看| 91久九九| 欧美婷婷综合| 特级西西44www无码| 国产成人99久久亚洲综合精品| 亚洲激情在线| 三级国产网站| 操鸡视频在线观看| 亚洲免费视频网| 五月涩| 国产美女精品| 亚洲一区| 国产精品扒开腿| 国产一级片无码| 天天日天天操天天摸天天干天日射天天插 | 男同人到爽无套狂欢| 99久久精彩视频| 麻豆91蜜桃传媒在线观看| 熟女在线视频| 精品乱子伦一区二区三区免费播放| 手机免费AV| 中文字幕在线免费观看| 麻豆精品在线播放| 国产激情一区二区三区| 三级国产AV| 亚洲AV无码成人精品区欧洲| 国产精品久久久久久久久免费无码 | 四川女人毛多水多A片| 97资源在线| 一本色道88久久加勒比精品| 欧美精品一级| 日韩性爱小说| 99热在线免费| 一区二区视频免费| 黄色视频网站亚洲| 狠狠干天天操| 东京热小视频| 91天天干| 亚洲啊v| 操b视频在线播放| 丁香社区五月天| 国产区精品| 18禁黄网站| 中文字幕无码A片久久| 人人操超碰在线观看| 亚洲a∨| 国产精品一区二区视频| 操骚B| 91视频在线观看免费大全| 伊人国产视频| 亚洲无码A片在线观看| 天天爱天天操| 国产黄色一级电影| 国产精品porn| 亚洲天堂精品在线观看| 柒私黄片| 日韩视频中文字幕在线| 九九久久99| 亚洲91精品| 麻豆MD传媒MD0071| 亚洲av网站在线观看| 狠狠狠狠狠| 99re视频播放| 国产无码操逼视频| 人人看人人摸人人搞| 欧美人与禽乱婬A片| 久久中文字幕免费| 操逼激情视频| 婷婷无码在线| 91人人爽| 亚洲高清视频无码| 国产精品综合| 国产高清免费| 日本高清色清di免费观看| 91丨PORN首页| 久草在线播放| 少妇搡BBBB搡BBBB毛多多| 国产黄色视频观看| 精品成人影视| 国产又爽又黄免费视频免费| 色香蕉视频在线观看| 91啦丨熟女露脸| 北条麻妃黄色视频| 大香蕉国产精品| 成人做爰黄级A片免费看土方| 国外成人性视频免费| а√最新版天堂中文在线| 久久免费操| 亚洲婷婷综合网| 97精品国产97久久久久久免费| 第一页在线| 欧美日韩免费在线视频| 久久99网站| 91偷拍视频| 九九天堂网| 精品超碰| 五月激情丁香| 亚洲护士无码| 99久久99久久精品免费看小说。 | 麻豆91在线| 国产乱国产乱老熟300视频| 天天干天天日| 婷婷精品国产a久久综合| 91在线无码精品秘网站| 四川美人搡BBw搡BBw| 日韩免费视频一区二区| 亚洲人妻电影一区| 日韩视频久久| 日韩无码激情| 亚洲欧洲久久| 精品色| 黄色伊人| 波多野吉衣av| 超碰在线国产| 中文字幕视频一区日日骚| jlzzzjlzzz国产免费观看| 日本激情网站| 爱视频福利网| 91精片| 无码电影网站| 2021国产精品视频| 亚洲黄色小视频| 亚洲精品一区二区二区的游戏情况| 久久精品女同亚洲女同13| 国产熟妇婬乱A片免费看牛牛 | 俺来也俺也啪WWW色| 国产一级美女操逼视频免费播放| 17c白丝喷水自慰| 免费黄色成人视频| 久久综合久久鬼色| 韩国三级HD久久精品HD| 免费毛片网站| 青青草网址| 熟女视频网站| 无码视屏| 超碰免费观看| 精品乱子伦一区二区三区,亚洲国产成| 国产乱子伦真实精品!| 亚洲欧美日韩综合| 日韩美女做爱| 超碰在线无码| 日韩免费在线视频| AV在线导航| 伊人狠狠| 国产av影音| 国产无套内射在线观看| 99成人在线| 无码潮喷| 操逼A片| 特级444www| 亚洲一级在线观看| 男女91| 97午夜福利| а√天堂中文最新版8| 三级片视频在线观看| 中文字幕无码av| 在线免费观看成人视频| 日本一级黄色电影| 国产黄色直播| 久久久穴| 欧美视频A| 懂色av蜜臀av粉嫩av分享| 黄网国产手机在线观看| 久久精品一二三| 国产熟妇| 91无码一区二区三区| 亚洲精品免费观看| 91麻豆精品A片国产在线观看| 日韩一本| 国产三级毛片| 黄色色情小说| 100国产精品人妻无码| 蜜芽成人在线视频| 国产色av| 高潮无码在线观看| 无码国产精品一区二区免费式直播| 亚洲精品黄色电影| 777免费视频| 国产成人自拍视频在线观看| 亚洲日韩av在线| 中国老女人操逼| 超碰观看| 九九乱伦| 嫩草A片www在线观看| 国产一级a毛一级a做免费图片| 国产九九精品| 久久99人妻无码精品一区| 四虎国产精品成人久久| 美女大香蕉| 手机看片福利永久| 亚洲乱伦图片| 曰本精品综合网在线| 色屁屁草草影院ccyycom| 婷婷丁香五月激情一区综合网| 久久久久97| 色眯眯久久爱| 黄色电影一区二区| 美妇肥臀一区二区三区-久久99精品国| 69亚洲精品| 日本大胆中出| 91精品久久久久久久久久| 91国黄色毛片在线观看| 青娱乐91视频| 天堂成人在线视频| 日韩av中文字幕在线| 国外亚洲成AV人片在线观看| 久操视频网站| 欧美男人天堂网| 国产操逼视频网站| 日韩无码一区二区三| 人人澡人人爱| 特黄色A级片视频| 91资源在线| 婷婷无码成人精品俺来俺去| 亚洲WWW| 91大奶熟女| 国产欧美熟妇另类久久久| 中文字幕国产在线观看| h无码| 人妻在线免费视频| 国产精品操逼| 青青在线免费视频| 国产精品AV在线观看| 日韩精品成人专区无码| 婷婷久久婷婷| 日韩A区| 国产精品夜夜爽7777777| 爱爱电影无码| 中文字幕网址在线| 91婷婷射| 麻豆91麻豆国产传媒| 12—13女人毛片毛片| 青草影视久久| 亚洲国产熟妇无码日韩| 一级黄色影片| 日韩av免费在线观看| 日本久久成人| 刘玥91精品一区二区三区| 一级a免一级a做片免费| 国产顶级理伦| 欧美日韩爱爱| 日韩资源站| 麻豆免费视频| 免费成人在线看片黄| 欧美日逼| AV天天看| 人与鲁牲交| 91精品久久香蕉国产线看观看 | 无码主播| 日韩一级a| 晚上碰视频| 大香蕉伊人| 北条麻妃无码一区二区| 亚洲中文字幕免费观看视频| 双飞人妻13p| 国产乱子伦无码视频免费| 国产亚洲视频完整在线观看| 男女拍拍免费视频| 五月丁香色色| 日韩毛| 狼人一区二区| 在线观看毛片网站| 婷婷AV在线| 日本A在线播放| 无码高清视频| av天天看| 躁BBB躁BBB躁BBBBBB日视频| 精品国产乱子伦一区二区三区最新章| 日本免费爱爱| 水多多成人网站A片| 欧美成人在线观看视频| 九色PORNY丨自拍蝌蚪| 99热在线观看| 色老板亚洲| 特黄色A级片视频| 色77777| 日韩大屌| 亚洲AV永久无码精品国产精| 丰滿老婦BBwBBwBBw| 日韩无码精品一区二区三区| 天天天天色| 中文字幕人妻日韩在线| 黄色天堂| 欧美亚洲综合在线观看| 成人欧美| 亚洲成人无码精品| 国产在线观看97| 亚洲AV无码成人精品区国产| www高清无码| 水多多成人网站A片| 熟女一区二区| 亚洲自拍小说| 免费av毛片| 欧美不卡一区| 青娱乐Av| 亚洲无码十八禁| 黄色片在线播放| 四川少妇BBBB| 中国12一13毛片| 国产成人秘一区二区三区东京热| 麻豆亚洲AV成人无码久久精品| 大香蕉中文视频| 欧美黄色电影在线观看| 综合中文字幕| 国产精品资源在线观看| 夫妻成人免费看片一区二区| 中文字幕乱码亚州无线码日韩理论电 | 97人人爽人人爽人人爽| 一道本在线| caopor在线| 无码人妻一区二区三区蜜桃视频| 日韩人妻精品无码久久边| 北条麻妃网址| 影音先锋亚洲AV| AV天堂小说网| 无码人妻一区二区| 天天插一插| 无码AA| 成人性生活一级片| 九色PORNY国产成人| 欧美成人无码一区二区三区| 亚洲一级二级片| 无码电影网站| 91人妻人人澡人人澡人人精品| av亚洲波多野结衣白嫩水多波 | 人妻电影亚洲av| 97在线观看免费| 十八女人高潮A片免费| 日韩黄色电影在线| 国产综合久久| 国产av一级片| AV大片在线观看| 国产精品毛片一区视频播| 大香蕉手机视频| 黄色视频免费播放| 久久国色| 肏逼网站在线观看| 成人免费无码婬片在线| 久一视频| 91久久婷婷亚洲精品成人| 亚洲中文自拍| 爱爱视频日本| 日韩免费看| 天天干天天操天天爽| 免费看a的网站| 久草99| av网站免费观看| 成人丁香五月| 久操新在线| 男人天堂网站| 人人澡人人添人人爽人人| 国产成人无码精品| 免费福利视频网站| 韩国午夜电影| 黄色小视频免费看| 91福利视频网站| 免费成人视频在线观看| 亚洲高清无码在线观看视频| 91视频网址| 国产精品成人无码a无码| 99热这里只有精品7| 天天草天天日| 艾操网| 伊人久久婷婷| a一级黄片| 国产精品久久久久久久免牛肉蒲| 毛片毛片毛片毛片| 韩国无码一区| 手机看片亚洲| 一级a一级a爰片免费免免在线| 丁香五月在线| 国产2区| 少妇做爱| 国产91免费| 毛片网| 日本免费爱爱| 九热视频| 午夜视频99| 久久久久久亚洲| 一级无码高清| 中文资源在线a中文| 成年人性生活免费视频| 黄片大全在线观看| 拍真实国产伦偷精品| 欧美色图另类图片| 夜色精品视频| 天天肏屄| 日本做爱视频| 中文字幕免费av| 91大鸡巴| 国产经典午夜福利视频合集| 天天草av| 夜夜操狠狠操| 大屌av| 中文字幕一区二区无码成人| 91香蕉在线观看| 蜜臀av在线观看| 国产噜噜噜噜久久久久久久久| 亚洲AV无码乱码| 美女福利导航| 国产A片精品| 国产成人精品一区二区| 怡春院在线| 91福利视频网站| 国产噜噜噜噜久久久久久久久| 亚洲熟妇在线观看| 亚欧洲精品视频| 日韩国产欧美精品一区| 国产无码毛片| 豆花视频成人精品视频| 99热5| 日日操日日摸| 日批无码| 桃色Av| 精品无码久久| 高清无码一区二区三区| 久久国产AV| 亚洲性爱无码| 99福利视频| 狼人综合在线| 亚洲AV成人无码一区二区三区| 在线观看中文字幕无码| 97人妻人人操| 免费v片在线| 成年人视频网站| 特级西西人体大胆无码| 日韩一级在线播放| 亚洲国产熟妇无码日韩| 日B无码| 国产免费www| 台湾中文字幕网| 久久思热国产| 五月婷婷开心| 狠狠色一区| 国产午夜视频| 国产一级AAAAA片免费| 福利导航网| 亚洲456| 欧美性少妇| 狠狠欧美| 91麻豆精品无码人妻| 亚洲色图欧美| 91网站观看| 国产乱伦影片| 88国产精品| 特级丰满少妇免费观看| 欧美亚洲天堂| 亚洲日韩AV在线| AAA片| 色色看片| 大香蕉操逼网| 日本二区三区| 成人片无码| 毛片精品| 热久久伊人| 欧美亚洲日韩一区二区| 1区2区视频| 久久久久久大香蕉| 久久久国产AV| 国产波霸爆乳一区二区| 人人操人人爱人人摸| 美女久草| 中文字幕乱码亚洲无线码按摩| 一级黄色蜜芽视频| 伊人久久综合| 青青草原亚洲| 少妇一级片| 久久蜜桃| 手机免费av| 91偷拍视频| 亚洲AⅤ无码一区二区波多野按摩| 亚洲丁香五月天| 亚州成熟少妇视频在线观看| 欧美成人在线观看视频| 少妇bbw搡bbbb搡bbbb| 亚洲日韩欧美一区二区| 亚洲欧美日韩免费| 亚洲国产区| 亚洲精品一区二区三区四区高清 | 亚洲无码大全| 免费观看成人| 最新日韩无码| 成人亚洲A片V一区二区三区蜜月| 欧美高清无码视频| 人人爱天天做| 日本一区二区三区在线播放| 18禁av在线| 熟女少妇一区二区三区| 精品综合| 亚洲逼逼| 亚洲欧美成人在线观看| 日韩精品久久久| 狼人香蕉网| 成人久久久久| 97精品视频在线观看| 在线免费观看亚洲| 东北老女人操逼视频| 久久久久久久久久久成人| 一级内射视频| 男人天堂色| 国产无遮挡A片又黄又爽小直播| 人妻乱码| 97人妻精品一区二区三区视频| 99在线精品视频免费观看20| 日本親子亂子倫XXXX50路| 丁香五月婷婷网| 老熟女-ThePorn| 日本黄色小视频| 日韩欧美在线免费观看| 色99999| 日韩欧美高清视频| 欧美视频免费| 波多野结衣高清无码| 国产精品9999| 色眯眯久久爱| 日本成人中文字幕在线观看| 午夜黄色操逼视频| 国产AV日韩AⅤ亚洲AV中文 | 欧美视频色| 足交| 加勒比无码综合| 黄页免费无码| 久久福利电影| 亚洲黄色视频在线观看网站| 国产无码AV成在线| 婷婷欧美日韩| 免费看毛片网站| 亚洲国产精品午夜福利| avwww| 亚洲免费小视频| 亚洲专区视频| 久久大鸡吧| 亚洲无码在线免费观看| 欧美色综合| 木下凛凛子AV888AV在线观看 | 黄色天堂| 亚洲无码1区| 国产精品成人在线| 色婷婷视频在线播放| 精品1234| www.av在线| 成人网站在线看| 久久毛片人妻| 午夜精品久久久久久久久无码99热| 调教人妻视频| 毛片A片免费看| 苍井空无码在线观看| 国产又爽又黄免费| 在线观看的av网站| 91人人在线| 你懂的在线观看| 黄色成人网站在线免费观看| 91丨人妻丨国产丨丝袜| 秒播福利| 精品乱子伦一区二区三区下载 | 亚洲高清无码在线| 亚洲欧美色图| 青青草成人免费在线视频| 日韩免费在线观看| www99精品| 亚洲成人AAAAA| 熟妇女人妻丰满少妇中文字幕| 日本视频一区二区三区| 一区二区三区高清| 无码人妻一区二区三区| 91成人片| 91黄在线观看| 在线观看中文字幕亚洲| 你懂得视频| 亚洲肏屄网| 欧美香蕉视频| 亚洲无码网址| 最近中文字幕免费mv第一季歌词強上 | 在线免费看A片| 五月婷在线| 蜜桃视频一区| 五月色婷婷撸| A片免费的| 精品视频免费在线观看| 韩日在线视频| 激情五月天在线观看| 西西特级WWW444无码| 97午夜福利| 91性视频| 在线免费看黄色| 日韩图片区小说视频区日| AV电影天堂网| 天天日天天干天天草| 国产精品欧美一区二区| 91亚洲精品乱码久久久久久蜜桃 | 日韩有码中文字幕在线观看| 久草视频首页| 亚洲少妇一区| 久久性视频| 日韩激情无码视频精选| 中国操逼电影| 91麻豆精品国产91久久久久久 | 激情六月丁香| 日韩AV免费在线| 电影91久久久| 中文字幕的色| 亚洲91无码精品一区在线播放| ww亚洲ww| 四虎A片| 色婷婷AV国产精品| 日韩一级片在线观看| 亚洲wwwwww| 国产一级性爱| 一本色道久久综合| 中文字幕人成人乱码亚洲电影| 日韩AV在线电影| 综合天堂网| 亚洲欧美日韩免费| 欧美精产国品一二三区别| 波多野结衣高清无码视频| 免费日逼| 按摩忍不住BD中文字幕| 妹子色综合| 99re国产视频| 另类老妇奶BBBBwBB| 男人天堂网在线| footjobvk| 69国产成人精品二区| 五月婷婷色播| 日本丰满老熟妇乱子伦| 国产a级毛片| 91精品人妻人人爽| 一级a免一级a做免费线看内裤| 一区二区三区久久久久〖网:.〗| 另类罕见稀奇videos| 日本东京热视频| 视频一区在线播放| 俺去俺来也在线www色情网| 在线观看免费A片| 成人日韩| 日韩乱轮小说与视频| 香蕉在线观看| 69福利视频| 亚洲香蕉在线| 欧美城综合在线观看网| 波多野结衣av一区| 日韩av高清| 国产精品午夜福利| 亚洲综合伊人| 精品乱子伦一区二区在线播放| 欧美日韩在线视频免费观看| 亚洲乱伦视频| 伊人在线视频| 日韩bbbb| 国产l精品久久久久久久久久| 中出在线| 91内射| 午夜福利av电影| 久久久成人免费视频| 婷婷五月天无码| 国产精品秘久久久久久网站| 亚洲色一| 亚洲撸撸| 色综合久久88色综合天天99| 日韩AV三级片| 中韩日美免费看的电影| 日批网站视频| 无码视频免费在线观看| 无码精品人妻一区二区| 国产精品每日更新| 精品乱子伦一区二区三区免费播放| 日逼视频网站| 欧美熟妇擦BBBB擦BBBB| 内射无码视频| 色搞搞| 操逼第二页| 一级香蕉视频| 翔田千里一区二区三区| 亚洲无码精品视频| 操穴网| 黄色电影网站在线观看| 亚洲一级Av无码毛片久久精品| 人妻人人干| 日本a在线免费观看| 天天肏屄| 日都一级A片| 国产热| 国产综合久久777777麻豆| 亚洲综合伊人| 四虎影院污| 簧片网站在线观看| 久久婷婷视频| 国产—级a毛—a毛免费视频| 三级片高清无码| 操碰视频| 超碰天天射| 亚洲天堂av网| 福利视频网站| 国产成人三级在线| 综合操逼网| 777久久久| 18禁网站网址| 激情久久av| 日本黄色大片| 中文在线最新版天堂8| 成人在线综合| 98国产精品| AAA三级视频| 亚洲欧美成人在线视频| 成年人网站在线免费观看| h在线观看h| 迷情校园综合| 国产电影一区二区三区| 少妇熟女视频一区二区三区 | 伊人五月天| 日韩A电影| 色五月婷婷丁香五月| 3d动漫精品一区二区三区在线观看| 国产精品成人免费精品自在线观看 | 91人人在线| youjizzcom日本| 亚洲男同Gay一区二区| 精品欧美一区二区精品久久 | 美女性爱视频网站| 中文字幕AⅤ在线| 欧美操女人| 婷婷五月天影视| 中文字幕在线亚洲| 亚洲无码人妻一区| 一级a免一级a做免费线看内裤的注意事项 | 超碰人人搞| 久久久久久久网站| 亚洲成人少妇老妇a视频在线 | 国产精品码ls字幕影视| 黄色视频亚洲| 午夜福利电影无码| 欧美操b视频| 国产精品97| 97欧美日韩| 男人天堂视频网| 伊人在综合| 91成人小视频| 久久99免费视频| 青青草视频免费在线观看| 日韩无码操逼视频| 国产高清AV| 日韩中文字幕视频在线观看| 黄网在线免费观看| 91久久精品国产91久久公交车 | 国产97在线观看| 欧美一区二区三区视频| 亚洲中文字幕成人|