Bootiful Spring Boot 3.4:Spring Data

工程 | Josh Long | 2024 年 11 月 24 日 | ...

釋出公告博文很好地強調了 Spring Data 2024.1 中的一些新功能。請記住:Spring Data 是一個總括專案,聚合了支援 Couchbase、Redis、MongoDB、JDBC、R2DBC、Neo4J、Apache Cassandra 等資料儲存的模組。它是將資料儲存連線到應用程式的最簡單方法。事實上,我們可以寫一本小書來介紹這裡的所有新功能!

以下是一些引起我注意的功能。

  • 一個新的 Repository fragments SPI 允許 classpath 上的任何任意 .jar 檔案,或者其他包中的程式碼,透過 Spring.factories 服務工廠機制向 Spring Data 倉庫機制貢獻擴充套件。
  • Spring Data JPA 中查詢解析開銷大大降低
  • Spring Data MongoDB 中的 @TimeSeries 過期
  • Spring Data for Apache Cassandra 中表和使用者定義型別的 keyspace 限定
  • Spring Data Cassandra 中使用 CqlGenerator refined CQL 生成
  • Spring Data Redis 在事務和管道操作中支援 Jedis Lua 指令碼
  • 使用 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、類 UnixWindows)。

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有