最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis配置文件解析與MyBatis實(shí)例演示

 更新時(shí)間:2022年04月07日 08:36:24   投稿:wdc  
這篇文章主要介紹了MyBatis配置文件解析與MyBatis實(shí)例演示以及怎樣編譯安裝MyBatis,需要的朋友可以參考下

MyBatis介紹

MyBatis是一個(gè)持久層的ORM框架,使用簡(jiǎn)單,學(xué)習(xí)成本較低。可以執(zhí)行自己手寫的SQL語(yǔ)句,比較靈活。但是MyBatis的自動(dòng)化程度不高,移植性也不高,有時(shí)從一個(gè)數(shù)據(jù)庫(kù)遷移到另外一個(gè)數(shù)據(jù)庫(kù)的時(shí)候需要自己修改配置,所以稱只為半自動(dòng)ORM框架

傳統(tǒng)JDBC和Mybatis相比的弊病

傳統(tǒng)JDBC

@Test
public  void test() throws SQLException {
    Connection conn=null;
    PreparedStatement pstmt=null;
    try {
        // 1.加載驅(qū)動(dòng)
        Class.forName("com.mysql.jdbc.Driver");

        // 2.創(chuàng)建連接
        conn= DriverManager.
                getConnection("jdbc:mysql://localhost:3306/mybatis_example", "root", "123456");


        // SQL語(yǔ)句
        String sql="select id,user_name,create_time from t_user where id=?";

        // 獲得sql執(zhí)行者
        pstmt=conn.prepareStatement(sql);
        pstmt.setInt(1,1);

        // 執(zhí)行查詢
        //ResultSet rs= pstmt.executeQuery();
        pstmt.execute();
        ResultSet rs= pstmt.getResultSet();

        rs.next();
        User user =new User();
        user.setId(rs.getLong("id"));
        user.setUserName(rs.getString("user_name"));
        user.setCreateTime(rs.getDate("create_time"));
        System.out.println(user.toString());
    } catch (Exception e) {
        e.printStackTrace();
    }
    finally{
        // 關(guān)閉資源
        try {
            if(conn!=null){
                conn.close();
            }
            if(pstmt!=null){
                pstmt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

傳統(tǒng)JDBC的問題如下:

1.數(shù)據(jù)庫(kù)連接創(chuàng)建,釋放頻繁造成西戎資源的浪費(fèi),從而影響系統(tǒng)性能,使用數(shù)據(jù)庫(kù)連接池可以解決問題。
2.sql語(yǔ)句在代碼中硬編碼,造成代碼的不已維護(hù),實(shí)際應(yīng)用中sql的變化可能較大,sql代碼和java代碼沒有分離開來(lái)維護(hù)不方便。
3.使用preparedStatement向有占位符傳遞參數(shù)存在硬編碼問題因?yàn)閟ql中的where子句的條件不確定,同樣是修改不方便/
4.對(duì)結(jié)果集中解析存在硬編碼問題,sql的變化導(dǎo)致解析代碼的變化,系統(tǒng)維護(hù)不方便。

mybatis對(duì)傳統(tǒng)的JDBC的解決方案

1、數(shù)據(jù)庫(kù)連接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費(fèi)從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫(kù)連接池可解決此問題。
解決:在SqlMapConfig.xml中配置數(shù)據(jù)連接池,使用連接池管理數(shù)據(jù)庫(kù)鏈接。

2、Sql語(yǔ)句寫在代碼中造成代碼不易維護(hù),實(shí)際應(yīng)用sql變化的可能較大,sql變動(dòng)需要改變java代碼。
解決:將Sql語(yǔ)句配置在XXXXmapper.xml文件中與java代碼分離。

3、向sql語(yǔ)句傳參數(shù)麻煩,因?yàn)閟ql語(yǔ)句的where條件不一定,可能多也可能少,占位符需要和參數(shù)一一對(duì)應(yīng)。
解決:Mybatis自動(dòng)將java對(duì)象映射至sql語(yǔ)句,通過(guò)statement中的parameterType定義輸入?yún)?shù)的類型。

4、對(duì)結(jié)果集解析麻煩,sql變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫(kù)記錄封裝成pojo對(duì)象解析比較方便。
解決:Mybatis自動(dòng)將sql執(zhí)行結(jié)果映射至java對(duì)象,通過(guò)statement中的resultType定義輸出結(jié)果的類型。

Mybaits整體體系圖

在這里插入圖片描述

 

在這里插入圖片描述

一個(gè)Mybatis最簡(jiǎn)單的使用例子如下:

public class App {
    public static void main(String[] args) {
        String resource = "mybatis-config.xml";
        Reader reader;
        try {
            //將XML配置文件構(gòu)建為Configuration配置類
            reader = Resources.getResourceAsReader(resource);
            // 通過(guò)加載配置文件流構(gòu)建一個(gè)SqlSessionFactory  DefaultSqlSessionFactory
            SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
            // 數(shù)據(jù)源 執(zhí)行器  DefaultSqlSession
            SqlSession session = sqlMapper.openSession();
            try {
                // 執(zhí)行查詢 底層執(zhí)行jdbc
                //User user = (User)session.selectOne("com.tuling.mapper.selectById", 1);

                UserMapper mapper = session.getMapper(UserMapper.class);
                System.out.println(mapper.getClass());
                User user = mapper.selectById(1L);
                System.out.println(user.getUserName());
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                session.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

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>
    <!--properties 掃描屬性文件.properties  -->
    <properties resource="db.properties"></properties>


    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

   <plugins>
       <plugin interceptor="com.tuling.plugins.ExamplePlugin" ></plugin>
    </plugins>

    <environments default="development">
        <environment id="development">
           <transactionManager type="JDBC"/>
            <!--//  mybatis內(nèi)置了JNDI、POOLED、UNPOOLED三種類型的數(shù)據(jù)源,其中POOLED對(duì)應(yīng)的實(shí)現(xiàn)為org.apache.ibatis.datasource.pooled.PooledDataSource,它是mybatis自帶實(shí)現(xiàn)的一個(gè)同步、線程安全的數(shù)據(jù)庫(kù)連接池 一般在生產(chǎn)中,我們會(huì)使用c3p0或者druid連接池-->
            <dataSource type="POOLED">
            <property name="driver" value="${mysql.driverClass}"/>
            <property name="url" value="${mysql.jdbcUrl}"/>
            <property name="username" value="${mysql.user}"/>
            <property name="password" value="${mysql.password}"/>
        </dataSource>
        </environment>
    </environments>



    <mappers>
        <!--1.必須保證接口名(例如IUserDao)和xml名(IUserDao.xml)相同,還必須在同一個(gè)包中-->
        <package name="com.tuling.mapper"/>

        <!--2.不用保證同接口同包同名
         <mapper resource="com/mybatis/mappers/EmployeeMapper.xml"/>

        3.保證接口名(例如IUserDao)和xml名(IUserDao.xml)相同,還必須在同一個(gè)包中
        <mapper class="com.mybatis.dao.EmployeeMapper"/>

        4.不推薦:引用網(wǎng)路路徑或者磁盤路徑下的sql映射文件 file:///var/mappers/AuthorMapper.xml
         <mapper url="file:E:/Study/myeclipse/_03_Test/src/cn/sdut/pojo/PersonMapper.xml"/>-->

    </mappers>
</configuration>

總結(jié)下就是分為下面四個(gè)步驟:

  • 從配置文件(通常是XML文件)得到SessionFactory;
  • 從SessionFactory得到SqlSession;
  • 通過(guò)SqlSession進(jìn)行CRUD和事務(wù)的操作;
  • 執(zhí)行完相關(guān)操作之后關(guān)閉Session。

MyBatis 源碼編譯

1.下載mybatis源碼

下載地址:https://github.com/mybatis/mybatis-3

這里寫圖片描述

我下載的最新的 mybatis-3-mybatis-3.4.6,下載完后解壓。打開pom.xml

 <parent>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-parent</artifactId>
    <version>30</version>
    <relativePath />
  </parent>

發(fā)現(xiàn)mybatis源碼依賴mybatis-parent 所以編譯前要先下載mybatis-parent

2.下載mybatis-parent源碼

下載地址:https://github.com/mybatis/parent

這里寫圖片描述

下載的mybatis-parent版本要和mybatis源文件pom.xml 版本一致。

3.編譯mybatis-parent源碼

切換到你下載的mybatis-parent目錄:

mvn clean install

3.編譯mybatis源碼

切換到你下載的mybatis源碼目錄:

mvn clean 

mvn install -Dmaven.test.skip=true

如果出現(xiàn)如下錯(cuò)誤:

這里寫圖片描述

打開pom.xml 文件注釋掉 maven-pdf-plugin 插件

  <!--
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-pdf-plugin</artifactId>
      </plugin>
      -->

然后重新編譯

4.導(dǎo)入IDEA

導(dǎo)入方式就不多說(shuō),按maven項(xiàng)目導(dǎo)入即可!導(dǎo)入成功后:

這里寫圖片描述

如果希望在spring源碼中引入你自己的這份源碼,可以做如下操作

1.修改你mybatis源碼的pom的 這樣可以和官方的區(qū)分開來(lái)

<version>3.5.3-xsls</version>

2.這樣你在spring源碼中就可以引入這份mybatis源碼了.

  • 如果引入mybatis-spring 同樣需要做1、3步驟
compile("org.mybatis:mybatis-spring:2.0.3-xsls")  
compile("org.mybatis:mybatis:3.5.3-xsls")

3.當(dāng)然,如果你想在spring這邊看到你mybatis源碼相關(guān)的注釋,還得在mybatis源碼的pom里面加入plugin,使它生成 jar 的同時(shí) 生成 sources 包

<plugin>
  <artifactId>maven-source-plugin</artifactId>
  <version>3.0.1</version>
  <configuration>
    <attach>true</attach>
  </configuration>
  <executions>
    <execution>
      <phase>compile</phase>
      <goals>
        <goal>jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Mybatis啟動(dòng)流程分析

String resource = "mybatis-config.xml";
//將XML配置文件構(gòu)建為Configuration配置類
reader = Resources.getResourceAsReader(resource);
// 通過(guò)加載配置文件流構(gòu)建一個(gè)SqlSessionFactory  DefaultSqlSessionFactory
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);

通過(guò)上面代碼發(fā)現(xiàn),創(chuàng)建SqlSessionFactory的代碼在SqlSessionFactoryBuilder中,進(jìn)去一探究竟:

//整個(gè)過(guò)程就是將配置文件解析成Configration對(duì)象,然后創(chuàng)建SqlSessionFactory的過(guò)程
//Configuration是SqlSessionFactory的一個(gè)內(nèi)部屬性
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }
    
  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

下面我們看下解析配置文件過(guò)程中的一些細(xì)節(jié)。
先給出一個(gè)配置文件的例子:

<?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>
    <!--SqlSessionFactoryBuilder中配置的配置文件的優(yōu)先級(jí)最高;config.properties配置文件的優(yōu)先級(jí)次之;properties標(biāo)簽中的配置優(yōu)先級(jí)最低 -->
    <properties resource="org/mybatis/example/config.properties">
      <property name="username" value="dev_user"/>
      <property name="password" value="F2Fa3!33TYyg"/>
    </properties>

    <!--一些重要的全局配置-->
    <settings>
    <setting name="cacheEnabled" value="true"/>
    <!--<setting name="lazyLoadingEnabled" value="true"/>-->
    <!--<setting name="multipleResultSetsEnabled" value="true"/>-->
    <!--<setting name="useColumnLabel" value="true"/>-->
    <!--<setting name="useGeneratedKeys" value="false"/>-->
    <!--<setting name="autoMappingBehavior" value="PARTIAL"/>-->
    <!--<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>-->
    <!--<setting name="defaultExecutorType" value="SIMPLE"/>-->
    <!--<setting name="defaultStatementTimeout" value="25"/>-->
    <!--<setting name="defaultFetchSize" value="100"/>-->
    <!--<setting name="safeRowBoundsEnabled" value="false"/>-->
    <!--<setting name="mapUnderscoreToCamelCase" value="false"/>-->
    <!--<setting name="localCacheScope" value="STATEMENT"/>-->
    <!--<setting name="jdbcTypeForNull" value="OTHER"/>-->
    <!--<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>-->
    <!--<setting name="logImpl" value="STDOUT_LOGGING" />-->
    </settings>

    <typeAliases>

    </typeAliases>

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--默認(rèn)值為 false,當(dāng)該參數(shù)設(shè)置為 true 時(shí),如果 pageSize=0 或者 RowBounds.limit = 0 就會(huì)查詢出全部的結(jié)果-->
            <!--如果某些查詢數(shù)據(jù)量非常大,不應(yīng)該允許查出所有數(shù)據(jù)-->
            <property name="pageSizeZero" value="true"/>
        </plugin>
    </plugins>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://10.59.97.10:3308/windty"/>
                <property name="username" value="windty_opr"/>
                <property name="password" value="windty!234"/>
            </dataSource>
        </environment>
    </environments>

    <databaseIdProvider type="DB_VENDOR">
        <property name="MySQL" value="mysql" />
        <property name="Oracle" value="oracle" />
    </databaseIdProvider>

    <mappers>
        <!--這邊可以使用package和resource兩種方式加載mapper-->
        <!--<package name="包名"/>-->
        <!--<mapper resource="./mappers/SysUserMapper.xml"/>-->
        <mapper resource="./mappers/CbondissuerMapper.xml"/>
    </mappers>

</configuration>

下面是解析配置文件的核心方法:

private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      //解析properties標(biāo)簽,并set到Configration對(duì)象中
      //在properties配置屬性后,在Mybatis的配置文件中就可以使用${key}的形式使用了。
      propertiesElement(root.evalNode("properties"));
      
      //解析setting標(biāo)簽的配置
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      //添加vfs的自定義實(shí)現(xiàn),這個(gè)功能不怎么用
      loadCustomVfs(settings);
        
      //配置類的別名,配置后就可以用別名來(lái)替代全限定名
      //mybatis默認(rèn)設(shè)置了很多別名,參考附錄部分
      typeAliasesElement(root.evalNode("typeAliases"));
        
      //解析攔截器和攔截器的屬性,set到Configration的interceptorChain中
      //MyBatis 允許你在已映射語(yǔ)句執(zhí)行過(guò)程中的某一點(diǎn)進(jìn)行攔截調(diào)用。默認(rèn)情況下,MyBatis 允許使用插件來(lái)攔截的方法調(diào)用包括:
      //Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
        //ParameterHandler (getParameterObject, setParameters)
        //ResultSetHandler (handleResultSets, handleOutputParameters)
        //StatementHandler (prepare, parameterize, batch, update, query)
      pluginElement(root.evalNode("plugins"));
      
      //Mybatis創(chuàng)建對(duì)象是會(huì)使用objectFactory來(lái)創(chuàng)建對(duì)象,一般情況下不會(huì)自己配置這個(gè)objectFactory,使用系統(tǒng)默認(rèn)的objectFactory就好了
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
       
      //設(shè)置在setting標(biāo)簽中配置的配置
      settingsElement(settings);
   
      //解析環(huán)境信息,包括事物管理器和數(shù)據(jù)源,SqlSessionFactoryBuilder在解析時(shí)需要指定環(huán)境id,如果不指定的話,會(huì)選擇默認(rèn)的環(huán)境;
      //最后將這些信息set到Configration的Environment屬性里面
      environmentsElement(root.evalNode("environments"));
        
      //
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
        
      //無(wú)論是 MyBatis 在預(yù)處理語(yǔ)句(PreparedStatement)中設(shè)置一個(gè)參數(shù)時(shí),還是從結(jié)果集中取出一個(gè)值時(shí), 都會(huì)用類型處理器將獲取的值以合適的方式轉(zhuǎn)換成 Java 類型。解析typeHandler。
      typeHandlerElement(root.evalNode("typeHandlers"));
      //解析Mapper
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
}

在這里插入圖片描述

上面解析流程結(jié)束后會(huì)生成一個(gè)Configration對(duì)象,包含所有配置信息,然后會(huì)創(chuàng)建一個(gè)SqlSessionFactory對(duì)象,這個(gè)對(duì)象包含了Configration對(duì)象。

簡(jiǎn)單總結(jié)

對(duì)于MyBatis啟動(dòng)的流程(獲取SqlSession的過(guò)程)這邊簡(jiǎn)單總結(jié)下:

  • SqlSessionFactoryBuilder解析配置文件,包括屬性配置、別名配置、攔截器配置、環(huán)境(數(shù)據(jù)源和事務(wù)管理器)、Mapper配置等;解析完這些配置后會(huì)生成一個(gè)Configration對(duì)象,這個(gè)對(duì)象中包含了MyBatis需要的所有配置,然后會(huì)用這個(gè)Configration對(duì)象創(chuàng)建一個(gè)SqlSessionFactory對(duì)象,這個(gè)對(duì)象中包含了Configration對(duì)象;

這里解析的東西比較多,大致概況:會(huì)把所有的信息都解析到Configration對(duì)象中,比較簡(jiǎn)單不多介紹。

更多關(guān)于MyBatis配置文件解析MyBatis實(shí)例演示以及怎樣編譯安裝MyBatis請(qǐng)查看下面的相關(guān)鏈接

相關(guān)文章

  • Spring IOC 能降低耦合的問題分析及解決方法

    Spring IOC 能降低耦合的問題分析及解決方法

    這篇文章主要介紹了Spring IOC 為什么能降低耦合,依賴注入是調(diào)用者僅通過(guò)聲明某個(gè)組件就可以獲得組件的控制權(quán),而對(duì)該組件的依賴關(guān)系管理、查找、加載由外部完成,需要的朋友可以參考下
    2022-06-06
  • 深入理解Java中線程間的通信

    深入理解Java中線程間的通信

    一般來(lái)講,線程內(nèi)部有自己私有的線程上下文,互不干擾。但是當(dāng)我們需要多個(gè)線程之間相互協(xié)作的時(shí)候,就需要我們掌握J(rèn)ava線程的通信方式。本文將介紹Java線程之間的幾種通信原理,需要的可以參考一下
    2022-11-11
  • Java 如何實(shí)現(xiàn)POST(x-www-form-urlencoded)請(qǐng)求

    Java 如何實(shí)現(xiàn)POST(x-www-form-urlencoded)請(qǐng)求

    這篇文章主要介紹了Java 實(shí)現(xiàn)POST(x-www-form-urlencoded)請(qǐng)求,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • MyBatis的MapKey注解實(shí)例解析

    MyBatis的MapKey注解實(shí)例解析

    這篇文章主要為大家介紹了MyBatis的MapKey注解實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • java string的一些細(xì)節(jié)剖析

    java string的一些細(xì)節(jié)剖析

    首先說(shuō)明這里指的是Java中String的一些細(xì)節(jié)部分,需要的朋友可以參考
    2012-11-11
  • springboot如何通過(guò)@Value,@ConfigurationProperties獲取配置

    springboot如何通過(guò)@Value,@ConfigurationProperties獲取配置

    這篇文章主要介紹了springboot如何通過(guò)@Value,@ConfigurationProperties獲取配置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java浮點(diǎn)類數(shù)字運(yùn)算方式

    Java浮點(diǎn)類數(shù)字運(yùn)算方式

    在進(jìn)行浮點(diǎn)數(shù)的加減運(yùn)算時(shí),直接使用+和-可能會(huì)引入精度誤差,為了比較浮點(diǎn)數(shù),可以使用Double的compareTo()方法,或者通過(guò)定義一個(gè)容差值(Epsilon)來(lái)判斷兩個(gè)浮點(diǎn)數(shù)是否相等,此外,Double.compare()方法也能比較兩個(gè)double值
    2024-10-10
  • 詳解IntelliJ IDEA 2020 的Debug功能

    詳解IntelliJ IDEA 2020 的Debug功能

    這篇文章主要介紹了IntelliJ IDEA 2020 的Debug功能,本文通過(guò)實(shí)例截圖相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • JPA中@JoinColumn的name和referencedColumnName屬性的區(qū)別及說(shuō)明

    JPA中@JoinColumn的name和referencedColumnName屬性的區(qū)別及說(shuō)明

    這篇文章主要介紹了JPA中@JoinColumn的name和referencedColumnName屬性的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • SpringBoot的HTTPS配置實(shí)現(xiàn)

    SpringBoot的HTTPS配置實(shí)現(xiàn)

    本文主要介紹了SpringBoot的HTTPS配置實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評(píng)論

登封市| 三穗县| 柯坪县| 西丰县| 黄石市| 重庆市| 长葛市| 德令哈市| 高邮市| 驻马店市| 眉山市| 忻州市| 仙居县| 佳木斯市| 湘阴县| 平远县| 徐闻县| 元朗区| 祁连县| 察哈| 江北区| 大新县| 沂源县| 集安市| 聂荣县| 体育| 东莞市| 若羌县| 依安县| 肇庆市| 拜泉县| 安庆市| 赞皇县| 寿宁县| 房山区| 平顶山市| 米泉市| 城口县| 武清区| 宁晋县| 霍州市|