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 允許類路徑上的任何任意 .jar,或者實際上是另一個包中的程式碼,透過 Spring.factories 服務工廠機制為 Spring Data 儲存庫機制貢獻擴充套件
  • Spring Data JPA 中大大減少的查詢解析開銷
  • Spring Data MongoDB 中 @TimeSeries 的過期時間
  • Spring Data for Apache Cassandra 中表和使用者定義型別的鍵空間限定
  • Spring Data Cassandra 中使用 CqlGenerator 改進的 CQL 生成
  • Spring Data Redis 中事務和管道操作中的 Jedis Lua 指令碼支援
  • 使用 JedisClientConfigBuilderCustomizer 介面自定義 JedisClientConfig
  • 還有更多!

我想談談一個可能會改變我的事情的功能:值表示式的最終實現,這是一種花哨的說法,即可以使用 Spring 表示式語言 (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,該字串依次具有屬性佔位符 ${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 社群中所有即將舉行的活動。

檢視全部