欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Spring Data JPA中Repository的接口查詢方法

 更新時(shí)間:2022年04月28日 10:47:49   作者:嫣夜來(lái)  
repository代理有兩種方式從方法名中派生出特定存儲(chǔ)查詢:通過(guò)直接從方法名派生查詢和通過(guò)使用一個(gè)手動(dòng)定義的查詢。本文將通過(guò)示例詳細(xì)講解Spring Data JPA中Repository的接口查詢方法,需要的可以參考一下

1.查詢方法定義詳解

repository代理有兩種方式從方法名中派生出特定存儲(chǔ)查詢。

  • 通過(guò)直接從方法名派生查詢。
  • 通過(guò)使用一個(gè)手動(dòng)定義的查詢。

可用的選項(xiàng)取決于實(shí)際的商店。然而,必須有一個(gè)策略來(lái)決定創(chuàng)建什么實(shí)際的查詢。

2.搜索查詢策略

下列策略可用于repository解決基礎(chǔ)設(shè)施查詢。對(duì)于 XML 配置,你可以通過(guò) query-lookup-strategy 屬性在命名空間配置該策略。對(duì)于 Java 配置,你可以使用 Enable${store}Repositories 注解的 queryLookupStrategy屬性。某些策略可能不被特定的數(shù)據(jù)存儲(chǔ)所支持。

  • CREATE; 試圖從查詢方法的名稱中構(gòu)建一個(gè)特定于存儲(chǔ)的查詢。一般的做法是,從方法名中刪除一組已知的前綴,然后解析方法的其余部分。
  • USE_DECLARED_QUERY; 試圖找到一個(gè)已聲明的查詢,如果找不到則拋出一個(gè)異常。查詢可以由某個(gè)注解來(lái)定義,也可以通過(guò)其他方式來(lái)聲明。請(qǐng)參閱特定存儲(chǔ)的文檔以找到該存儲(chǔ)的可用選項(xiàng)。如果版本庫(kù)基礎(chǔ)設(shè)施在啟動(dòng)時(shí)沒(méi)有為該方法找到一個(gè)已聲明的查詢,則會(huì)失敗。
  • CREATE_IF_NOT_FOUND;(默認(rèn))結(jié)合了 CREATE 和 USE_DECLARED_QUERY。它首先查找一個(gè)已聲明的查詢,如果沒(méi)有找到已聲明的查詢,它將創(chuàng)建一個(gè)基于方法名的自定義查詢。這是默認(rèn)的查詢策略,因此,如果你沒(méi)有明確地配置任何東西,就會(huì)使用這種策略。它允許通過(guò)方法名快速定義查詢,但也可以根據(jù)需要通過(guò)引入已聲明的查詢對(duì)這些查詢進(jìn)行自定義調(diào)整。

3.查詢創(chuàng)建

內(nèi)置在Spring Data repository基礎(chǔ)框架中,查詢生成器機(jī)制對(duì)于在repository的實(shí)體上建立約束性查詢非常有用。

例1. 從方法名創(chuàng)建查詢

interface PersonRepository extends Repository<Person, Long> {
  List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

  // 查詢中添加去重關(guān)鍵字
  List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
  List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

  // 查詢中關(guān)鍵字忽略大小寫(xiě)
  List<Person> findByLastnameIgnoreCase(String lastname);
  
  // Enabling ignoring case for all suitable properties
  List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

  // 查詢使用使用靜態(tài)排序規(guī)則
  List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
  List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}

解析查詢方法名稱分為 主語(yǔ)和 謂語(yǔ)。

第一部分(find…By, exists…By)定義了查詢的主語(yǔ),

第二部分構(gòu)成了謂語(yǔ)。引入句(主語(yǔ))可以包含進(jìn)一步的表達(dá)。

在find(或其他引入關(guān)鍵詞)和By之間的任何文本都被認(rèn)為是描述性的,除非使用一個(gè)限制結(jié)果的關(guān)鍵詞,如Distinct在要?jiǎng)?chuàng)建的查詢上設(shè)置一個(gè)不同的標(biāo)志,或Top/First來(lái)限制查詢結(jié)果。

附錄中包含了查詢方法主語(yǔ)關(guān)鍵詞和查詢方法謂語(yǔ)關(guān)鍵詞的完整列表,包括排序和字母修飾語(yǔ)。然而,第一個(gè)By作為分界符,表示實(shí)際條件謂詞的開(kāi)始。在一個(gè)非?;镜膶用嫔?,你可以在實(shí)體屬性上定義條件,并用And和Or來(lái)連接它們。

解析方法的實(shí)際結(jié)果取決于你為之創(chuàng)建查詢的持久性存儲(chǔ)。然而,有一些一般性約束需要注意:

  • 表達(dá)式通常是屬性遍歷與可以串聯(lián)的運(yùn)算符的結(jié)合。你可以用AND和OR來(lái)組合屬性表達(dá)式。你還可以得到對(duì)運(yùn)算符的支持,如屬性表達(dá)式的Between、LessThan、GreaterThan和Like。支持的運(yùn)算符可能因數(shù)據(jù)存儲(chǔ)的不同而不同,所以請(qǐng)查閱參考文檔的適當(dāng)部分。
  • 方法解析器支持為單個(gè)屬性(例如,findByLastnameIgnoreCase(…))或支持忽略大小寫(xiě)的類型的所有屬性(通常是字符串實(shí)例–例如,findByLastnameAndFirstnameAllIgnoreCase(…))設(shè)置忽略大小寫(xiě)標(biāo)志。是否支持忽略大小寫(xiě)可能因商店而異,所以請(qǐng)查閱參考文檔中的相關(guān)章節(jié),了解特定商店的查詢方法。
  • 你可以通過(guò)在引用屬性的查詢方法中附加一個(gè)OrderBy子句,并提供一個(gè)排序方向(Asc或Desc)來(lái)應(yīng)用靜態(tài)排序。要?jiǎng)?chuàng)建一個(gè)支持動(dòng)態(tài)排序的查詢方法,請(qǐng)參閱 “特殊參數(shù)處理”。

4.屬性表達(dá)式

屬性表達(dá)式只能引用被管理實(shí)體的一個(gè)直接屬性,如前面的例子所示。在查詢創(chuàng)建時(shí),你已經(jīng)確保解析的屬性是被管理的實(shí)體類的一個(gè)對(duì)應(yīng)屬性。然而,你也可以通過(guò)遍歷嵌套屬性來(lái)定義約束。考慮一下下面的方法簽名。

例2

List<Person> findByAddressZipCode(ZipCode zipCode);

假設(shè)一個(gè)人有一個(gè)帶有ZipCode的地址。在這種情況下,該方法創(chuàng)建x.address.zipCode屬性遍歷。解析算法首先將整個(gè)部分(AddressZipCode)解釋為屬性,并檢查實(shí)體類中是否有該名稱的屬性(未加首字母)。如果算法成功,它就使用該屬性。如果沒(méi)有,該算法將原始的駱駝字母部分從右側(cè)分割成頭和尾,并試圖找到相應(yīng)的屬性–在我們的例子中,是AddressZip和Code。如果該算法找到了具有該頭部的屬性,它就取其尾部,并從那里繼續(xù)向下構(gòu)建樹(shù),以剛才描述的方式將尾部分割開(kāi)來(lái)。如果第一次分割不匹配,該算法將分割點(diǎn)移到左邊(Address, ZipCode),然后繼續(xù)。

雖然這在大多數(shù)情況下應(yīng)該是有效的,但該算法有可能選擇錯(cuò)誤的屬性。假設(shè)人的類也有一個(gè)addressZip屬性。該算法將在第一輪分割中已經(jīng)匹配,選擇錯(cuò)誤的屬性,并且失?。ㄒ?yàn)閍ddressZip的類型可能沒(méi)有代碼屬性)。

為了解決這種模糊性,你可以在你的方法名里面使用_來(lái)手動(dòng)定義遍歷點(diǎn)。所以我們的方法名將如下。

例3

List<Person> findByAddress_ZipCode(ZipCode zipCode);

因?yàn)槲覀儼严聞澗€字符當(dāng)作一個(gè)保留字符,所以我們強(qiáng)烈建議遵循標(biāo)準(zhǔn)的Java命名慣例(也就是說(shuō),不要在屬性名中使用下劃線,而是使用駱駝大寫(xiě))。

5.特殊參數(shù)處理

為了處理你的查詢中的參數(shù),定義方法參數(shù),正如在前面的例子中已經(jīng)看到的。除此之外,基礎(chǔ)設(shè)施還能識(shí)別某些特定的類型,如 Pageable和 Sort,以動(dòng)態(tài)地將 分頁(yè)和 排序應(yīng)用于你的查詢。下面的例子演示了這些功能。

例4 在查詢方法中使用分頁(yè)、切割、排序

Page<User> findByLastname(String lastname, Pageable pageable);
Slice<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);

注意:采取Sort和Pageable的API希望將非空值交到方法中。如果你不想應(yīng)用任何排序或分頁(yè),請(qǐng)使用Sort.unsorted()和Pageable.unpaged()方法。

第一個(gè)方法讓你把org.springframework.data.domain.Pageable實(shí)例傳遞給query方法,以動(dòng)態(tài)地將分頁(yè)添加到你靜態(tài)定義的查詢中。一個(gè)Page知道可用的元素和頁(yè)面的總數(shù)。它是通過(guò)基礎(chǔ)設(shè)施觸發(fā)一個(gè)計(jì)數(shù)查詢來(lái)計(jì)算總數(shù)量。

由于這可能是昂貴的(取決于使用的存儲(chǔ)),你可以改成返回一個(gè)Slice。一個(gè)Slice只知道下一個(gè)Slice是否可用,這在走過(guò)一個(gè)較大的結(jié)果集時(shí)可能就足夠了。

排序選項(xiàng)也是通過(guò)Pageable實(shí)例處理的。如果你只需要排序,可以在你的方法中添加一個(gè)org.springframework.data.domain.Sort參數(shù)。正如你所看到的,返回一個(gè)List也是可能的。在這種情況下,構(gòu)建實(shí)際的Page實(shí)例所需的額外元數(shù)據(jù)并沒(méi)有被創(chuàng)建(這反過(guò)來(lái)意味著不需要發(fā)出額外的計(jì)數(shù)查詢)。相反,它限制了查詢,只查詢給定范圍的實(shí)體。

要想知道你在整個(gè)查詢中得到多少頁(yè),你必須觸發(fā)一個(gè)額外的計(jì)數(shù)查詢。默認(rèn)情況下,這個(gè)查詢是由你實(shí)際觸發(fā)的查詢派生出來(lái)的。

分頁(yè)和排序

我們可以通過(guò)使用屬性名稱來(lái)定義簡(jiǎn)單的排序表達(dá)式。你可以將表達(dá)式連接起來(lái),將多個(gè)標(biāo)準(zhǔn)收集到一個(gè)表達(dá)式中。

例5 定義排序表達(dá)式

Sort sort = Sort.by("firstname").ascending()
  .and(Sort.by("lastname").descending());

對(duì)于定義排序表達(dá)式的更加類型安全的方式,從定義排序表達(dá)式的類型開(kāi)始,使用方法引用來(lái)定義排序的屬性。

例6 通過(guò)使用類型安全的API來(lái)定義排序表達(dá)式

TypedSort<Person> person = Sort.sort(Person.class);

Sort sort = person.by(Person::getFirstname).ascending()
  .and(person.by(Person::getLastname).descending());

TypedSort.by(…)通過(guò)(通常)使用CGlib來(lái)使用運(yùn)行時(shí)代理,這在使用Graal VM Native等工具時(shí)可能會(huì)干擾本地圖像的編譯。

如果你的存儲(chǔ)實(shí)現(xiàn)支持Querydsl,你也可以使用生成的元模型類型來(lái)定義排序表達(dá)式。

例7 通過(guò)使用Querydsl API定義排序表達(dá)式

QSort sort = QSort.by(QPerson.firstname.asc())
  .and(QSort.by(QPerson.lastname.desc()));

6.限制查詢結(jié)果

你可以通過(guò)使用first或top關(guān)鍵字來(lái)限制查詢方法的結(jié)果,這兩個(gè)關(guān)鍵字可以互換使用。你可以在top或first后面附加一個(gè)可選的數(shù)值,以指定要返回的最大結(jié)果大小。如果不加數(shù)字,就會(huì)假定結(jié)果大小為1。下面的例子顯示了如何限制查詢的大小。

例8. 用Top和First限制查詢結(jié)果的大小

User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();

Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);

對(duì)于支持不同查詢的數(shù)據(jù)集,限制表達(dá)式也支持Distinct關(guān)鍵字。另外,對(duì)于將結(jié)果集限制為一個(gè)實(shí)例的查詢,支持用Optional關(guān)鍵字將結(jié)果包入。

如果分頁(yè)或切片應(yīng)用于限制性查詢的分頁(yè)(以及可用頁(yè)數(shù)的計(jì)算),則會(huì)在限制性結(jié)果內(nèi)應(yīng)用。

通過(guò)使用排序參數(shù)將結(jié)果與動(dòng)態(tài)排序相結(jié)合,可以讓你表達(dá)對(duì) "K "最小元素和 "K "最大元素的查詢方法。

7. repository方法返回Collections or Iterables

當(dāng)查詢方法返回多個(gè)結(jié)果時(shí),可以使用標(biāo)準(zhǔn)的Java Iterable、List和Set來(lái)接受返回結(jié)果。除此之外,我們還支持返回Spring Data的Streamable,這是Iterable的一個(gè)自定義擴(kuò)展,以及Vavr提供的集合類型。請(qǐng)參考附錄中對(duì)所有可能的查詢方法返回類型的解釋。

例9 使用Streamable作為查詢方法的返回類型

interface PersonRepository extends Repository<Person, Long> {
Streamable`<Person>` findByFirstnameContaining(String firstname);
Streamable`<Person>` findByLastnameContaining(String lastname);
}

Streamable `<Person>` result = repository.findByFirstnameContaining("av")
.and(repository.findByLastnameContaining("ea"));

例10 返回類型為自定義的Streamable包裝類

Streamable包裝類是為集合類提供的一種特殊的封裝類型, 是一種常用的模式,為返回多個(gè)元素的查詢結(jié)果提供API。通常,這些類型是通過(guò)調(diào)用返回類似集合類型的repository方法,并手動(dòng)創(chuàng)建包裝器類型的實(shí)例來(lái)使用。你可以避免這個(gè)額外的步驟,因?yàn)镾pring Data允許你使用這些包裝器類型作為查詢方法的返回類型,如果它們滿足以下條件:

  • 該類型實(shí)現(xiàn)了Streamable。
  • 該類型暴露了一個(gè)構(gòu)造函數(shù)或一個(gè)名為of(…)或valueOf(…)的靜態(tài)工廠方法,它將Streamable作為參數(shù)。

下面的列表顯示了一個(gè)例子。

class Product {                                       
  MonetaryAmount getPrice() { … }
}

@RequiredArgsConstructor(staticName = "of")
class Products implements Streamable<Product> {       

  private final Streamable<Product> streamable;

  public MonetaryAmount getTotal() {                  
    return streamable.stream()
      .map(Priced::getPrice)
      .reduce(Money.of(0), MonetaryAmount::add);
  }


  @Override
  public Iterator<Product> iterator() {               
    return streamable.iterator();
  }
}

interface ProductRepository implements Repository<Product, Long> {
  Products findAllByDescriptionContaining(String text); 
}

一個(gè)Product實(shí)體類對(duì)象暴露了訪問(wèn)產(chǎn)品價(jià)格的API。

一個(gè)Streamable<Product>的封裝類型,可以通過(guò)使用Products.of(…)(用Lombok注解創(chuàng)建的工廠方法)構(gòu)建。使用Streamable<Product>的標(biāo)準(zhǔn)構(gòu)造函數(shù)也可以做到。

封裝類型暴露了一個(gè)額外的API,計(jì)算Streamable<Product>上的新值。

實(shí)現(xiàn)Streamable接口并委托給實(shí)際結(jié)果。

那個(gè)包裝類型的Products可以直接作為查詢方法的返回類型使用。你不需要返回Streamable<Product>并在版本庫(kù)客戶端的查詢后手動(dòng)包裝它。
對(duì)于Vavr類型集合的支持

Vavr是一個(gè)擁抱Java中函數(shù)式編程概念的庫(kù)。它帶有一組自定義的集合類型,你可以將其作為查詢方法的返回類型,如下表所示。

Vavr 集合類被使用的Vavr 實(shí)現(xiàn)類有效的Java源類型
io.vavr.collection.Seqio.vavr.collection.Listjava.util.Iterable
io.vavr.collection.Setio.vavr.collection.LinkedHashSetjava.util.Iterable
io.vavr.collection.Mapio.vavr.collection.LinkedHashMapjava.util.Map

你可以使用第一列中的類型(或其子類型)作為查詢方法的返回類型,并根據(jù)實(shí)際查詢結(jié)果的Java類型(第三列),獲得第二列中的類型作為實(shí)現(xiàn)類型使用。

或者,你可以聲明Traversable(相當(dāng)于Vavr Iterable),然后我們從實(shí)際返回值中派生出實(shí)現(xiàn)類。也就是說(shuō),java.util.List會(huì)變成Vavr List或Seq,java.util.Set會(huì)變成Vavr LinkedHashSet Set,以此類推。

8.repository方法處理Null

從Spring Data 2.0開(kāi)始,返回單個(gè)聚合實(shí)例的存儲(chǔ)庫(kù)CRUD方法使用Java 8的Optional來(lái)處理空值。除此之外,Spring Data還支持在查詢方法上返回以下封裝類型。

  • com.google.common.base.Optional
  • scala.Option
  • io.vavr.control.Option

另外,查詢方法可以選擇完全不使用包裝類型。沒(méi)有查詢結(jié)果會(huì)通過(guò)返回null來(lái)表示。Repository 方法返回集合、集合替代物、包裝器和流,保證不會(huì)返回 null,而是返回相應(yīng)的空表示。詳見(jiàn) “Repository 查詢返回類型”。

注解處理Null

你可以通過(guò)使用Spring Framework的nullability注解來(lái)表達(dá)repository方法的nullability約束。它們提供了一種工具友好的方法,并在運(yùn)行時(shí)選擇加入空值檢查,如下所示。

  • @NonNullApi: 在包的層面上使用,聲明參數(shù)和返回值的默認(rèn)行為分別是不接受也不產(chǎn)生空值。
  • @NonNull。用于不得為空的參數(shù)或返回值(在適用@NonNullApi的參數(shù)和返回值上不需要)。
  • @Nullable。用在可以為空的參數(shù)或返回值上。

Spring注解是用JSR 305注解(一個(gè)休眠但廣泛使用的JSR)進(jìn)行元注解的。JSR 305元注釋讓工具供應(yīng)商(如IDEA、Eclipse和Kotlin)以通用的方式提供null-safety支持,而無(wú)需對(duì)Spring注釋進(jìn)行硬編碼支持。為了在運(yùn)行時(shí)檢查查詢方法的無(wú)效性約束,你需要通過(guò)在package-info.java中使用Spring的@NonNullApi,在包級(jí)別上激活無(wú)效性,如下例所示。

例11 在 package-info.java中聲明Non-nullability

@org.springframework.lang.NonNullApi
package com.acme;

一旦非空默認(rèn)到位,repository的查詢方法調(diào)用就會(huì)在運(yùn)行時(shí)被驗(yàn)證是否有空值約束。如果查詢結(jié)果違反了定義的約束,就會(huì)拋出一個(gè)異常。這種情況發(fā)生在方法會(huì)返回null,但被聲明為non-nullable(在版本庫(kù)所在的包上定義注解的默認(rèn)值)。如果你想再次選擇加入可歸零的結(jié)果,可以有選擇地在個(gè)別方法上使用@Nullable。使用本節(jié)開(kāi)頭提到的結(jié)果封裝類型繼續(xù)按預(yù)期工作:一個(gè)空的結(jié)果被翻譯成代表不存在的值。

下面的例子展示了剛才描述的一些技術(shù)。

例12. 使用不同的無(wú)效性約束

package com.acme;                                                 
import org.springframework.lang.Nullable;

interface UserRepository extends Repository<User, Long> {
  User getByEmailAddress(EmailAddress emailAddress);              
  @Nullable
  User findByEmailAddress(@Nullable EmailAddress emailAdress);    
  Optional<User> findOptionalByEmailAddress(EmailAddress emailAddress); 
}

repository駐留在一個(gè)包(或子包)中,我們?yōu)槠涠x了非空的行為。

當(dāng)查詢沒(méi)有產(chǎn)生結(jié)果時(shí),拋出一個(gè)EmptyResultDataAccessException。

當(dāng)交給該方法的emailAddress為空時(shí),拋出一個(gè)IllegalArgumentException。

當(dāng)查詢沒(méi)有產(chǎn)生結(jié)果時(shí),返回null。也接受null作為emailAddress的值。

當(dāng)查詢沒(méi)有產(chǎn)生結(jié)果時(shí)返回Optional.empty()。當(dāng)交給該方法的emailAddress為null時(shí),拋出一個(gè)IllegalArgumentException。

9.查詢結(jié)果流

你可以通過(guò)使用Java 8 Stream <T>作為返回類型來(lái)增量地處理查詢方法的結(jié)果。如下面的例子所示,不把查詢結(jié)果包裹在Stream中,而是使用數(shù)據(jù)存儲(chǔ)的特定方法來(lái)執(zhí)行流式處理。

例13 用Java 8 Stream <T>串聯(lián)查詢的結(jié)果

@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();

Stream<User> readAllByFirstnameNotNull();

@Query("select u from User u")
Stream<User> streamAllPaged(Pageable pageable);

一個(gè)流可能包裹了底層數(shù)據(jù)存儲(chǔ)的特定資源,因此,在使用后必須關(guān)閉。你可以通過(guò)使用close()方法來(lái)手動(dòng)關(guān)閉Stream,或者使用Java 7 try-with-resources塊來(lái)關(guān)閉,如下面的例子中所示。

例14 在 try-with-resources 塊中處理一個(gè) Stream <T> 的結(jié)果

try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
  stream.forEach(…);
}

目前并非所有的Spring Data模塊都支持Stream <T>作為返回類型。

10.異步查詢結(jié)果

你可以通過(guò)使用Spring的異步方法運(yùn)行能力來(lái)異步運(yùn)行repository查詢。這意味著該方法在調(diào)用后立即返回,而實(shí)際的查詢發(fā)生在一個(gè)已經(jīng)提交給Spring TaskExecutor的任務(wù)中。異步查詢與反應(yīng)式查詢不同,不應(yīng)混合使用。關(guān)于響應(yīng)式支持的更多細(xì)節(jié),請(qǐng)參見(jiàn)store-specific文檔。下面的例子顯示了一些異步查詢的情況。

例15. 異步查詢結(jié)果

@Async
Future<User> findByFirstname(String firstname);         

@Async
CompletableFuture<User> findOneByFirstname(String firstname); 

@Async
ListenableFuture<User> findOneByLastname(String lastname);  

使用java.util.concurrent.Future作為返回類型。

使用Java 8 java.util.concurrent.CompletableFuture作為返回類型。

使用org.springframework.util.concurrent.ListenableFuture作為返回類型。

以上就是詳解Spring Data JPA中Repository的接口查詢方法的詳細(xì)內(nèi)容,更多關(guān)于Repository接口查詢的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java使用建造者模式實(shí)現(xiàn)辦理手機(jī)套餐功能詳解

    Java使用建造者模式實(shí)現(xiàn)辦理手機(jī)套餐功能詳解

    這篇文章主要介紹了Java使用建造者模式實(shí)現(xiàn)辦理手機(jī)套餐功能,較為詳細(xì)的描述了建造者模式的概念、原理并結(jié)合實(shí)例形式分析了Java使用建造者模式實(shí)現(xiàn)的辦理手機(jī)套餐功能具體步驟與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-05-05
  • Maven實(shí)戰(zhàn)之搭建Maven私服和鏡像的方法(圖文)

    Maven實(shí)戰(zhàn)之搭建Maven私服和鏡像的方法(圖文)

    本篇文章主要介紹了搭建Maven私服和鏡像的方法(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • 使用spring boot通過(guò)自定義注解打印所需日志

    使用spring boot通過(guò)自定義注解打印所需日志

    這篇文章主要介紹了使用spring boot通過(guò)自定義注解打印所需日志的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java計(jì)算代碼段執(zhí)行時(shí)間的詳細(xì)過(guò)程

    Java計(jì)算代碼段執(zhí)行時(shí)間的詳細(xì)過(guò)程

    java里計(jì)算代碼段執(zhí)行時(shí)間可以有兩種方法,一種是毫秒級(jí)別的計(jì)算,另一種是更精確的納秒級(jí)別的計(jì)算,這篇文章主要介紹了java計(jì)算代碼段執(zhí)行時(shí)間,需要的朋友可以參考下
    2023-02-02
  • MyBatis中map的應(yīng)用與模糊查詢實(shí)現(xiàn)代碼

    MyBatis中map的應(yīng)用與模糊查詢實(shí)現(xiàn)代碼

    這篇文章主要介紹了MyBatis中map的應(yīng)用與模糊查詢實(shí)現(xiàn)代碼,文中通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • 基于redis key占用內(nèi)存量分析

    基于redis key占用內(nèi)存量分析

    這篇文章主要介紹了基于redis key占用內(nèi)存量分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • springboot如何解決跨域后session獲取不到sessionId不一致

    springboot如何解決跨域后session獲取不到sessionId不一致

    這篇文章主要介紹了springboot如何解決跨域后session獲取不到sessionId不一致問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理

    Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理

    這篇文章主要介紹了Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 關(guān)于RequestMapping注解的作用說(shuō)明

    關(guān)于RequestMapping注解的作用說(shuō)明

    這篇文章主要介紹了關(guān)于RequestMapping注解的作用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
    2022-01-01
  • FineReport中自定義登錄界面的方法

    FineReport中自定義登錄界面的方法

    這篇文章主要介紹了 FineReport中自定義登錄界面的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-03-03

最新評(píng)論