領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多釋出公告博文很好地強調了 Spring Data 2024.1 中的一些新功能。請記住:Spring Data 是一個總括專案,聚合了支援 Couchbase、Redis、MongoDB、JDBC、R2DBC、Neo4J、Apache Cassandra 等資料儲存的模組。它是將資料儲存連線到應用程式的最簡單方法。事實上,我們可以寫一本小書來介紹這裡的所有新功能!
以下是一些引起我注意的功能。
.jar 檔案,或者其他包中的程式碼,透過 Spring.factories 服務工廠機制向 Spring Data 倉庫機制貢獻擴充套件。@TimeSeries 過期CqlGenerator refined CQL 生成JedisClientConfigBuilderCustomizer 介面來自定義 JedisClientConfig。我想談談一個可能改變我遊戲規則的功能:值表示式的出現,這是一個花哨的說法,意思是可以使用 Spring Expression Language (SpEL) 或屬性佔位符解析表示式中的一個或兩個來引數化 Spring Data 模組中的查詢。
值表示式的功能是基於一個您可以在應用程式中使用的漂亮的底層 API。
package com.example.bootiful_34.data;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import org.springframework.data.expression.ValueEvaluationContext;
import org.springframework.data.expression.ValueExpressionParser;
import org.springframework.data.expression.ValueParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.test.context.DynamicPropertyRegistrar;
import org.springframework.test.context.DynamicPropertyRegistry;
@SpringBootTest
@Import(ValueExpressionDynamicPropertyRegistrar.class)
class ValueExpressionTest {
@Test
void test(@Autowired Environment environment) {
var configuration = (ValueParserConfiguration) SpelExpressionParser::new;
var context = ValueEvaluationContext.of(environment, new StandardEvaluationContext());
var parser = ValueExpressionParser.create(configuration);
var expression = parser.parse("${message}-#{ (6 * 7) + ''}");
var result = expression.evaluate(context);
Assertions.assertEquals("ni hao-42", result);
}
}
@Configuration
class ValueExpressionDynamicPropertyRegistrar implements DynamicPropertyRegistrar {
@Override
public void accept(DynamicPropertyRegistry registry) {
registry.add("message", () -> "ni hao");
}
}
在此示例中,我正在測試中使用底層 ValueEvaluationContext,在該測試中,我動態添加了一個屬性:message,其值為問候語 ni hao。該測試會解析一個 String,該 String 包含一個屬性佔位符 ${message} 和一個 SpEL 表示式 #{ (6 * 7) + ''},在其中我們將兩個數字相乘,然後將結果表示式轉換為 String。結果正如您所料:ni hao-42。
現在您已經看到了可能性,讓我們在 Spring Data JDBC 儲存庫的查詢方法定義中檢查其中一些。
package com.example.bootiful_34.data;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.ListCrudRepository;
import java.util.Collection;
interface CustomerRepository extends ListCrudRepository<Customer, Integer> {
@Query(" select * from #{ #tableName }")
Collection<Customer> all();
@Query(" select * from customer where language = :#{locale.language} ")
Collection<Customer> findCustomersBySystemLanguage();
// this is new! support for property placeholder resolution in queries!
@Query("select * from customer where os = :${os.name} ")
Collection<Customer> findCustomersHavingSameOperatingSystemAsUs();
}
第一個查詢依賴於一個 SpEL 上下文,該上下文提供了查詢方法中引用的實體的表名(在本例中,Customer 屬於 customer SQL 資料庫)。
在第二個示例查詢中,我們匹配透過 EvaluationContextExtension 貢獻的自定義上下文。此擴充套件程式僅在 SpEL 執行期間使使用者的 Locale 可用。
💡 提示
您是否知道 LocaleContextHolder?它自 Spring Framework 1.2 以來就一直存在於 Spring 中!它可以獲取當前使用者的 Locale 物件。因此,想象一下有一個 HTTP 請求進來;Spring MVC 會確定使用者的 Locale,然後將其安裝在這裡。只要您在與請求相同的執行緒中,就可以隨時讀取它。很棒。
package com.example.bootiful_34.data;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.spel.spi.EvaluationContextExtension;
import org.springframework.stereotype.Component;
import java.util.Locale;
@Component
class LocaleEvaluationContextExtension implements EvaluationContextExtension {
@Override
public String getExtensionId() {
return "locale";
}
@Override
public Locale getRootObject() {
return LocaleContextHolder.getLocale();
}
}
在第三個示例查詢中,我們匹配一個系統屬性 os.name,它返回使用者當前的作業系統(Mac OS X、類 Unix、Windows)。