MyBatis使用XML映射文件(mybatis的xml映射文件)

      網(wǎng)友投稿 2839 2022-05-30

      1.概述

      這一次想把MyBatis的XML聲明SQL的方式大概說一下。使用的demo可以參考:

      《spring boot整合Mybatis3.5.4使用XML定義SQL》

      MyBatis可以通過注解使用聲明,也可以xml文件來聲明SQL。前者簡(jiǎn)單,不靈活,后者不僅方便靈活,還方便優(yōu)。通過XML來編寫映射的SQL也是MyBatis所推薦的。MyBatis的一個(gè)映射器類就對(duì)象一個(gè)xml文件,xml文件寫SQL語句。

      xml文件的根元素是mapper,mppper元素可以包含以下子元素:

      cache:指定的命名空間的緩存配置

      cache-ref:引用其他命名空間緩存配置

      resultMap:描述如何從數(shù)據(jù)庫結(jié)果集中加載到對(duì)象中

      parameterMap:在MyBatis3.5.4中棄用了!

      sql:定義可重用的SQL塊

      insert:用于聲明INSERT語句

      update:用于聲明UPDATE語句

      delete:用于聲明DELETE語句

      select:用于聲明SELECT語句

      下面逐一講解。

      2.元素講解

      2.1.cache

      默認(rèn)情況下:

      1

      只啟用本地會(huì)話緩存,只在會(huì)話期間緩存數(shù)據(jù)。有如下特點(diǎn):

      所有查詢出來的結(jié)果集都會(huì)被緩存起來;

      所有在映射聲明文件中的insert、update、delete語句都會(huì)被放到緩存里;

      使用最近最少使用的(LRU)逐出算法 ;

      緩存不會(huì)按任何基于時(shí)間的計(jì)劃刷新

      緩存可以存儲(chǔ)1024個(gè)列表或?qū)ο蟮膫€(gè)引用;

      緩存可讀可寫,意味著緩存的對(duì)象是不共享的,因此能夠被調(diào)用者安全地修改,因?yàn)椴淮嬖谄渌{(diào)用者或線程潛在的修改。

      緩存配置只會(huì)對(duì)cache標(biāo)記所在的映射文件中的語句有起作用。如果不想用默認(rèn)的配置,可以修改以上緩存的屬性,如:

      1

      2

      3

      4

      5

      創(chuàng)建一個(gè)FIFO緩存,并且每隔60秒就刷新一次,最多可以存儲(chǔ)512個(gè)返回的結(jié)果對(duì)象或列表或?qū)ο蟮囊茫揖彺嬷荒茏x不能寫。 因?yàn)閷懣赡軙?huì)在多個(gè)調(diào)用者或線程之間才生沖突。

      緩存用的逐出策略有以下這些:

      LRU(默認(rèn)的):最近最少使用,移除那些長(zhǎng)時(shí)間不使用的對(duì)象

      FIFO:先進(jìn)先出, 按照他們進(jìn)入緩存的順序移除對(duì)象

      SOFT:軟引用,基于垃圾收集器狀態(tài)和軟引用移除對(duì)象。

      WEAK:弱引用, 更積極地基于垃圾收集器狀態(tài)和弱引用規(guī)則移除對(duì)象

      cache元素的屬性:

      使用自定義的cache:

      1

      自定義cache要實(shí)現(xiàn)org.apache.ibatis.cache.Cache接口,MyBatis的Cache接口是這樣的:

      public interface Cache { String getId(); int getSize(); void putObject(Object key, Object value); Object getObject(Object key); boolean hasKey(Object key); Object removeObject(Object key); void clear(); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      實(shí)現(xiàn)Cache接口:

      public class MyCustomCache implements Cache{ // ... }

      1

      2

      3

      點(diǎn)到為止,更多內(nèi)容請(qǐng)到網(wǎng)上查閱!

      2.2.cache-ref

      MyBatis使用XML映射文件(mybatis的xml映射文件)

      引用其他命名空間的緩存配置。

      1

      2.3.resultMap

      resultMap是MyBatis中最重要的元素,因?yàn)閷⒔Y(jié)果集映射到對(duì)象中,基本都用resultMap來完成。使用resultMap可以讓你省去90%的JDBC代碼,resultMap其甚至可以實(shí)現(xiàn)一些JDBC做不到的事。MyBatis自動(dòng)創(chuàng)建ResultMap,基于名稱自動(dòng)映射列到JavaBean的屬性上, 如果列名和JavaBean的屬性匹配不上,我們可以在列名上使用select子句別名(標(biāo)準(zhǔn)SQL特性)來創(chuàng)建標(biāo)簽匹配:

      1

      2

      3

      4

      5

      6

      7

      8

      除了上面這種給列名取個(gè)與JavaBean屬性匹配得了的別名外,還可以使用標(biāo)簽來建立數(shù)據(jù)庫表的列名與JavaBean屬性的對(duì)應(yīng)關(guān)系:

      (1)第一步:使用resultMap標(biāo)簽建立列名與屬性名的對(duì)應(yīng)關(guān)系

      1

      2

      3

      4

      5

      (2)第二步:引用resultMap

      1

      2

      3

      4

      5

      resultMap不能和resultType同時(shí)使用,繼續(xù)閱讀你就明白的了。

      數(shù)據(jù)庫很難做到時(shí)時(shí)刻刻都能夠和我們的JavaBean的屬性匹配上。而且不是所有數(shù)據(jù)庫都能很好的實(shí)現(xiàn)數(shù)據(jù)庫設(shè)計(jì)第三范式或BCNF范式。這些問題都使處有時(shí)并不能簡(jiǎn)單地通過自動(dòng)映射來完成,對(duì)于這些復(fù)雜的映射關(guān)系的處理可以用resultMap來解決表列名與JavaBean字段映射的問題。這也是它存在的原因。舉例說明,下面這個(gè)復(fù)雜的SQL的映射問題:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      從上面這個(gè)例子,我們可以看到resultMap標(biāo)簽有很多子標(biāo)簽,下面我們一個(gè)一個(gè)來看。

      (1)constructor :在類實(shí)例化時(shí)將結(jié)果注入到類的構(gòu)造函數(shù)中,如將結(jié)果果集的內(nèi)容注入到下面這個(gè)類的構(gòu)造函數(shù)中:

      public class User { //... public User(Integer id, String username, int age) { //... } //... }

      1

      2

      3

      4

      5

      6

      7

      使用constructor時(shí),要保證結(jié)果集內(nèi)容的順序要和構(gòu)造函數(shù)的參數(shù)順序一致,如下面的映射,MyBatis會(huì)搜索定義了三個(gè)參數(shù)(java.lang.Integer ,java.lang.String ,int)且出現(xiàn)順序一樣的構(gòu)造函數(shù):

      1

      2

      3

      4

      5

      如果不想維護(hù)arg元素的順序,可以為每一個(gè)arg元素指定一個(gè)名稱,使其與構(gòu)造函數(shù)名稱對(duì)應(yīng)上(對(duì)應(yīng)的注解方式是使用@Param ):

      1

      2

      3

      4

      5

      constructor元素的子元素:

      (2)id & result:

      1

      2

      這兩個(gè)是結(jié)果映射中最基本的元素。id和result都是映射一個(gè)列值到一個(gè)簡(jiǎn)單類型(String, int, double, Date等)的屬性或字段。 它們唯一的區(qū)別是id結(jié)果標(biāo)識(shí)為一個(gè)標(biāo)識(shí)符屬性,在比較對(duì)象實(shí)例時(shí)使用,有助于提高總體性能。特別是提高緩存和嵌套result映射的性能,如SQL中帶join語句的映射。

      它們有以下屬性:

      JDBC支持的類型:

      (3)association:復(fù)雜類型的組合,它是處理 “has-one” 這種關(guān)系的,例如Blog類中有個(gè)Author類型時(shí)的屬性。MyBatis有以下兩種方式來實(shí)現(xiàn)association加載:

      嵌套Select:通過執(zhí)行另一個(gè)SQL語句來返回這種嵌套的復(fù)雜類型,但這種式對(duì)大數(shù)量的查詢的性能不是很好。

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      嵌套result:

      先介紹association的一些屬性:

      下面是嵌套result的例子:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      上面我們把a(bǔ)uthor獨(dú)立寫了個(gè)resultMap這樣author部分就可以重用了,如果我們不想重用,可以將其寫在一起,如:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      如果Blog中有兩個(gè)字段author、coauthor,它們都是Author對(duì)象,resultMap又該如何寫呢?select語句如下:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      resultMap可以這樣寫:

      1

      2

      3

      4

      5

      6

      association處理多結(jié)果集(調(diào)用存儲(chǔ)過程):從MyBatis 3.2.3開始支持。有一些數(shù)據(jù)庫允許調(diào)存儲(chǔ)過程來執(zhí)行一或多條語句,并返回一或多個(gè)結(jié)果集。這種可以不使用join連接查詢。假設(shè)我們調(diào)用數(shù)據(jù)庫里存儲(chǔ)過程來執(zhí)行以下查詢并返回兩個(gè)結(jié)果集(blogs,authors):

      SELECT * FROM BLOG WHERE ID = #{id} SELECT * FROM AUTHOR WHERE ID = #{id}

      1

      2

      在xml映射文件中,使用resultSets屬性指定結(jié)果集名稱,多個(gè)結(jié)果集名稱之間用逗號(hào)分隔:

      1

      2

      3

      現(xiàn)在我們可以把a(bǔ)uthors結(jié)果集數(shù)據(jù)填充到 “author” association中:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      (4)collection:復(fù)雜類型的集合。collection元素與association元素很像,但后者是解決“has-one",前者是解決”has-many“這種關(guān)系。舉個(gè)例子:

      Blog有許多Posts(帖子),在Blog類里,帖子被定義列表:

      private List posts;

      1

      那么resultMap就應(yīng)該這樣寫:

      1

      2

      3

      4

      5

      與association元素一樣,collection元素也有兩種方式來處理結(jié)果集:

      嵌套select:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      嵌套result:

      首先,來看看根據(jù)blog id拿帖子的SQL:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      resultMap我們可以這樣寫:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      也可以將Post的resultMap單獨(dú)寫,以便重用:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      collection處理多個(gè)resultSet的情況(調(diào)用存儲(chǔ)過程):

      和前面association一樣,我們可以調(diào)用一個(gè)存儲(chǔ)過程來執(zhí)行兩個(gè)查詢,并返回兩個(gè)結(jié)果集,一個(gè)是Blogs的,別一個(gè)是Posts的:

      SELECT * FROM BLOG WHERE ID = #{id} SELECT * FROM POST WHERE BLOG_ID = #{id}

      1

      2

      在xml映射文件中,使用resultSets指定每個(gè)結(jié)果集的名字,多個(gè)結(jié)果集名稱之間用逗號(hào)隔開:

      1

      2

      3

      將posts集合填充到對(duì)象:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      collection的相關(guān)屬性:

      (5)discriminator :

      1

      2

      3

      有時(shí)候一個(gè)數(shù)據(jù)庫查詢可能會(huì)返回許多不同的數(shù)據(jù)類型的結(jié)果集。discriminator元素就是設(shè)計(jì)用來處理這種情況的。discriminator有點(diǎn)java中的switch語句。discriminator的定義指定column和javaType屬性,column就是MyBatis將要對(duì)比的值所在的地方。javaType是確保對(duì)比的類型正確。

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      與下面是等價(jià)的:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      在上面這個(gè)例子里,MyBatis會(huì)收到結(jié)果集中每條記錄,然后對(duì)比它的vehicle_ type的值,如果它匹配上了discriminator cases,那么就用指定的resultMap。如果沒有一個(gè)匹配上,那么MyBatis將使用定義在discriminator塊外的resultMap。carResult定義如下,如果vehicle_type是1,那么它就被使用:

      1

      2

      3

      我們知道car也是vehicle,所以我們想使用carResult的同時(shí)也把vehicleResult的字段加載進(jìn)來,這其實(shí)就是car繼承vehicle,那么resultMap也是可以繼承的,上面的carResult可以繼承vehicleResult,這樣也會(huì)把vehicleResult的字段加載進(jìn)來:

      1

      2

      3

      2.4.sql

      這個(gè)元素是用于定義一些可重用的SQL片段,這些片段可以被包含在其他的語句中。如定義以下SQL片段:

      ${alias}.id,${alias}.username,${alias}.password

      1

      在select語句中包含此片段:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      屬性值也可以用于include refid屬性里,或者include子句內(nèi)的屬性值,如:

      ${prefix}Table from

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      2.5.insert、update、delete

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      insert、update、delete的屬性:

      列子:

      insert into Author (id,username,password,email,bio) values (#{id},#{username},#{password},#{email},#{bio}) update Author set username = #{username}, password = #{password}, email = #{email}, bio = #{bio} where id = #{id} delete from Author where id = #{id}

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      insert語句自動(dòng)生成id列:

      insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})

      1

      2

      3

      4

      5

      如果數(shù)據(jù)庫支持同時(shí)多行插入,那么我們可以給對(duì)象傳個(gè)list或數(shù)組:

      insert into Author (username, password, email, bio) values (#{item.username}, #{item.password}, #{item.email}, #{item.bio})

      1

      2

      3

      4

      5

      6

      如果數(shù)據(jù)庫不支持自動(dòng)生成列類型或者還不支持JDBC驅(qū)動(dòng)自動(dòng)生成keys,那么可以使用以下selectKey方式來生成key,下面這個(gè)列子是隨機(jī)生成一個(gè)ID:

      select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1 insert into Author (id, username, password, email,bio, favourite_section) values (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=

      1

      2

      3

      4

      5

      6

      7

      8

      9

      selectKey子元素:

      1

      2

      3

      4

      5

      2.6.select

      SELECT * FROM PERSON WHERE ID = #{id}

      1

      2

      3

      2.7.參數(shù)類型

      一般來說,我們可以通過parameterType指定參數(shù)類型,如果指定的類型與數(shù)據(jù)庫中的類型不一樣的話,MyBatis提供一種方式給我們指定參數(shù)類型,格式:

      #{property,javaType=int,jdbcType=NUMERIC}

      1

      javaType通常由參數(shù)對(duì)象決定,除非對(duì)象是一個(gè)HashMap。指定javaType可以確保使用正確的TypeHandler。jdbcType是 JDBC需要的,用于所有可以為空的列,如果null作為一個(gè)值傳遞的話,就應(yīng)該指定jdbcType。

      我們還可以指定TypeHandler類或別名:

      #{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}

      1

      對(duì)于數(shù)字類型,有一個(gè)numericScale可以決定精確到小數(shù)點(diǎn)后幾位:

      #{height,javaType=double,jdbcType=NUMERIC,numericScale=2}

      1

      mode模式屬性可以是IN 、OUT、INOUT,如果是OUT或INOUT,那么參數(shù)對(duì)象屬性的真實(shí)值會(huì)被改變。如果模式是OUT或INOUT ,并且jdbcType=CURSOR

      ,那么你必須指定一個(gè)resultMap來映射ResultSet到參數(shù)類型,此時(shí)javaType屬性是可選的:

      #{department, mode=OUT, jdbcType=CURSOR, javaType=ResultSet, resultMap=departmentRes}

      1

      MyBatis也支持高級(jí)數(shù)據(jù)類型,如結(jié)構(gòu)體structs,但你必須告知語句類型名字:

      #{middleInitial, mode=OUT, jdbcType=STRUCT, jdbcTypeName=MY_TYPE, resultMap=departmentRes}

      1

      大多數(shù)時(shí)候,我們都只簡(jiǎn)單地指定屬性名,然后MyBatis就會(huì)幫我們搞掂剩下的這些。因此,我們只需要為可空的列指定jdbcType就可以了,如:

      #{firstName} #{middleInitial,jdbcType=VARCHAR} #{lastName}

      1

      2

      3

      2.8.置換字符串

      默認(rèn)情況下,使用#{}語法,會(huì)讓MyBatis生成PreparedStatement屬性,并將值安全地設(shè)置到PreparedStatement的參數(shù)里。這種方式既安全又快速。有時(shí),我們想直接在SQL語句注入未修改的字符串,當(dāng)SQL語句中的元數(shù)據(jù)(如表名,列名)是動(dòng)態(tài)變化的,字符串置換就顯得很有用了。例如,你要從一張表中通過任意一個(gè)列來選擇:

      @Select("select * from user where ${column} = #{value}") User findByColumn(@Param("column") String column, @Param("value") String value);

      1

      2

      接受從用戶輸入或提供SQL語句中未修改的元數(shù)據(jù)名稱是不安全的。這存在潛在的SQL注入攻擊。因此如果使用這種方式,我們要做到不允許用戶輸入這些字段,我們自己應(yīng)該做好轉(zhuǎn)義和檢查,以此來提高安全性。

      3.別名

      使用別名,你就不需要寫全限定路徑了。

      在springboot的application.yml加入以下配置:

      mybatis: # 指定MyBatis的配置文件位置 config-location: classpath:config/mybatis-mapper-config.xml # 指定映射器的xml文件的位置 mapper-locations: classpath:mybatis/mapper/*.xml

      1

      2

      3

      4

      5

      ~/Desktop/MyBatisXMLDemo$ touch src/main/resources/config/mybatis-mapper-config.xml ~/Desktop/MyBatisXMLDemo$ touch src/main/resources/mybatis/mapper/PersonMapper.xml

      1

      2

      1

      2

      3

      4

      5

      6

      7

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      還可以把數(shù)據(jù)庫連接的信息從application.yml文件中移到MyBatis的配置文件mybatis-mapper-config.xml中:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      4.動(dòng)態(tài)SQL

      MyBatis可以實(shí)現(xiàn)動(dòng)態(tài)SQL。

      if

      choose (when, otherwise)

      trim (where, set)

      foreach

      4.1.if

      1

      2

      3

      4

      5

      6

      7

      再如:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      4.2.choose (when, otherwise)

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      4.3.trim (where, set)

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      where元素可以很方便處理SQL的where子句,當(dāng)where元素中的if元素有符合的即需要插入where子句的),where元素就會(huì)在SQL語句后面添加where子句。如果where子句是以 “AND” 或 "OR"開頭,它會(huì)把它去掉,再添加到where后面。如果where元素都還滿足不了你的需求,Mybatis提供trim元素讓你來自定義,如下面的trim等價(jià)于where元素:

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      prefix是要插入的,prefixOverrides是要移除的。prefixOverrides屬性接受要重寫的以管道分隔的文本列表,注意空格的地方,它是必要的。簡(jiǎn)單點(diǎn)來說,trim的結(jié)果就是prefix屬性的值加上trim元素里的值,如果trim里沒有值,則不在SQL里插入,如果trim里的值是以prefixOverrides里的值開頭的則先移除再和prefix屬性值一起插入到SQL語句里。

      有一種相似的動(dòng)態(tài)update語句的解決方案叫set。set元素可以用來動(dòng)態(tài)包含要更新的列,而排除不需要更新的列:

      update Author username=#{username}, password=#{password}, email=#{email}, bio=#{bio} where id=#{id}

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      上面也可以用trim來自定義,如:

      update Author username=#{username}, password=#{password}, email=#{email}, bio=#{bio} where id=#{id}

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      4.4.foreach

      1

      2

      3

      4

      5

      6

      7

      8

      foreach元素允許我們指定一個(gè)集合collection,聲明item和index變量,這兩個(gè)變量可以在foreach元素內(nèi)部使用。foreach也允許我們指定開始和結(jié)束的字符串,和添加在迭代之間的分隔符 。foreach元素不會(huì)意外地附加額外的分隔符,這一點(diǎn)可以放心。

      我們可以傳遞任何迭代對(duì)象,如List、Set等,同樣也可傳遞Map或Array對(duì)象到foreach作為集合參數(shù)。當(dāng)使用Iterable 或 Array,index表示當(dāng)前迭代的下標(biāo),item表示當(dāng)前的值。當(dāng)使用Map,如 Map.Entry 對(duì)象的集合,index就是key對(duì)象,item就是值對(duì)象。

      4.5.script

      在映射器類里使用注解的方式使用動(dòng)態(tài)SQL,需要使用script 元素:

      @Update({""}) void updateAuthorValues(Author author);

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      4.6.bind

      bind元素可以讓你在OGNL表達(dá)式之外,創(chuàng)建一個(gè)變量,并將其綁定到上下文中:

      1

      2

      3

      4

      5

      5. 多數(shù)據(jù)庫供應(yīng)商支持

      說白了就是連接多個(gè)數(shù)據(jù)庫。如果有一個(gè)databaseIdProvider配置了“_databaseId"變量并且對(duì)于動(dòng)態(tài)代碼來說是可用的。那么,我們可以根據(jù)不同的數(shù)據(jù)庫提供商來建不同的語句,如:

      select seq_users.nextval from dual select nextval for seq_users from sysibm.sysdummy1" insert into users values (#{id}, #{name})

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      上面大概把MyBatis使用xml映射文件說了一遍。

      MyBatis XML

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:excel表格組合圖表的方法步驟(Excel表格組合圖)
      下一篇:Lock和synchronized比較詳解(談?wù)剆ynchronized和lock的區(qū)別)
      相關(guān)文章
      亚洲一区二区三区夜色| 亚洲成人动漫在线| 亚洲精品高清视频| 亚洲M码 欧洲S码SSS222| 亚洲精品动漫在线| 亚洲精品白色在线发布| 亚洲人成在线电影| 亚洲精品私拍国产福利在线| 国产亚洲精品无码成人| 久久精品夜色噜噜亚洲A∨| 亚洲AV蜜桃永久无码精品| 日韩亚洲人成在线综合| 亚洲国产欧美日韩精品一区二区三区| 亚洲最大av资源站无码av网址| 亚洲性线免费观看视频成熟| 99久久婷婷国产综合亚洲| 中文字幕在线观看亚洲日韩| 亚洲欧美国产国产综合一区 | 精品亚洲视频在线观看| 亚洲欧洲日本在线| 国产午夜亚洲精品国产成人小说| 亚洲乱码日产精品a级毛片久久| 亚洲第一福利网站在线观看| 亚洲综合精品网站在线观看| 亚洲综合伊人久久大杳蕉| 亚洲小说区图片区另类春色| 亚洲av片劲爆在线观看| 久久精品国产亚洲av影院| 91亚洲精品自在在线观看| 亚洲 日韩 色 图网站| 亚洲爆乳无码精品AAA片蜜桃| 日本亚洲中午字幕乱码| 中文字幕亚洲日韩无线码| 亚洲国产综合无码一区| 久久亚洲日韩看片无码| 亚洲乱码卡一卡二卡三| 亚洲AV永久无码精品网站在线观看 | 亚洲人成网站日本片| 亚洲午夜理论片在线观看| 久久亚洲中文字幕无码| 中文字幕亚洲日韩无线码|