在本期文章中,我們將介紹Java 14中的新特性及其在構建基於SpringBoot的應用程序中的應用。

開始,我們需要使用Java的最新版本,也是最棒的版本,Java 14,它現在還沒有發佈。預計將於2020年初發運。上下載早期訪問版本。Java.net。您也可以考慮使用SDKManager(
sdk
),這使得安裝新JVM版本確實是一件小事。
記住,每6個月就有新的Java版本。這些新版本可以在生產中使用,但只支持一個版本和下一個版本之間的六個月。Java項目不時也會發佈一個長期支持(LTS)版本。目前的版本是Java 11,Java 14在Java 15發佈之前只是一個可行的生產目標。事實上,我們要研究的是預覽功能,人們可能會說,這根本不應該在生產中。你被警告了!
如果使用SDKManager,可以運行以下咒語來安裝Java 14。
sdk install java 14.ea.36-open
去Spring Initializr並使用SpringBoot2.3或更高版本生成一個新項目。您還需要選擇
JDBC
和
PostgreSQL
.
SpringBoot的舊版本還不支持Java 14運行時。當然,為了編輯這個版本的Java,您需要將它導入到IDE中。不過,在您這樣做之前,讓我們修改一下
pom.xml
要將構建配置為支持Java 14,通常,當您轉到SpringInitializr時,您還指定了Java的一個版本。目前還不支持Java 14,因此我們希望手動配置一些東西。
通過更改
java.version
財產:
<properties>
<java.version>14/<java.version>
這允許我們的構建使用Java 14和該版本中所有發佈的特性,但是要真正體驗Java 14的新奇之處,我們需要打開預覽功能-發行版中提供的但默認情況下不活動的特性。
在
<plugins>.../<plugins>
節,添加以下插件配置,以啟用Java 14的預覽功能。
<plugin>
<artifactid>maven-compiler-plugin/<artifactid>
<configuration>
<release>14/<release>
<compilerargs>
<forcejavaccompileruse>true/<forcejavaccompileruse>
<parameters>true/<parameters>
<plugin>
<artifactid>maven-surefire-plugin/<artifactid>
<configuration>
<argline>--enable-preview/<argline>
現在你可以走了!讓我們看看一些Java代碼。SpringInitializr為我們提供了一個項目和一個基本入口點類:
package com.example.fourteen;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.sql.Types;
import java.util.List;
@SpringBootApplication
public class FourteenApplication {
public static void main(String[] args) {
SpringApplication.run(FourteenApplication.class, args);
}
}
我們將創建一個簡單的JDBC驅動服務,它使用SQL將其數據寫入數據庫。我們需要一個映射到數據庫表中數據的對象
people
.
此時,我通常要麼使用IDE的代碼生成工具來編寫Javabean對象,要麼使用Lombok來註釋我的方式到具有geters、setter的編譯器合成的對象,
toString
的實現
equals
。我甚至可能會勉強引用其他語言的能力,使這種乏味的工作變得瑣碎。Scala支持案例類。科特林支持數據類.
Java 14支持_Record_s。
record Person(Integer id, String name, int emotionalState) {
}
還不錯吧?這個語法包了一個Wallop!它提供了一個具有構造函數和構造函數參數、屬性、實現的新對象。
equals
和
toString
還有更多。我們可以像其他對象一樣實例化這個對象的實例。嘗試取消對象中的引用屬性,那麼我們的構造函數屬性就會變成
id()
/
id(int)
,
name()
/
name(String)
,和
emotionalState()
/
emotionalState(int)
。對這麼小的人來說還不錯!
讓我們看一下
PeopleService
.
這個
PeopleService
使用
JdbcTemplate
將數據庫查詢的結果轉換為Java對象的簡短工作。如果您曾經使用過
JdbcTemplate
(誰沒有)?我留下了一些未實現的部分,這樣我們就可以直接重新討論這些部分了。
@Service
class PeopleService {
private final JdbcTemplate template;
//todo
private final String findByIdSql = null;
private final String insertSql = null;
private final RowMapper<person> personRowMapper =/<person>
(rs, rowNum) -> new Person(rs.getInt("id"), rs.getString("name"), rs.getInt("emotional_state"));
PeopleService(JdbcTemplate template) {
this.template = template;
}
public Person create(String name, EmotionalState state) {
//todo
}
public Person findById(Integer id) {
return this.template.queryForObject(this.findByIdSql, new Object[]{id}, this.personRowMapper);
}
}
首先,我們將使用一些SQL查詢。在我的生活中,為了避免在Java代碼中鍵入SQL查詢,我付出了很大的代價。我的天啊,如果人們知道自己能用Java來表達SQL查詢,他們會經常使用ORM嗎?
Strings
?對於任何稍微複雜的內容,我都會將SQL查詢提取到屬性文件中,然後用Spring的配置屬性機制加載這些文件。
但是,我們可以在Java 14中做得更好!多行字符串終於出現在Java上了!它現在加入了Python、Ruby、C++、C#、Rust、PHP、Kotlin、Scala、Groovy、Go、JavaScript、Clojure以及其他十幾種語言的行列。我很高興它終於來了!
替換
sql
private final String findByIdSql =
"""
select * from PEOPLE
where ID = ?
""";
private final String insertSql =
"""
insert into PEOPLE(name, emotional_state)
values (?,?);
""";
太好了,那個!有一些方法可以用來修剪邊距等等。還可以使用反斜槓轉義序列(
\\
)在每一行的末尾,指示下一行應該從那裡開始,否則換行符就會被逐字解釋。
讓我們看看
create
方法。
存儲
Person
氏
emotionalState
在數據庫中作為
int
是實現細節。我不想讓用戶有這種想法。讓我們用一個枚舉來描述每個人的情緒狀態
Person
:
enum EmotionalState {
SAD, HAPPY, NEUTRAL
}
我想這是個開始。讓我們來討論實現。我們馬上就有機會在Java 14中使用另一個很好的新特性:智能開關表達式。Switch表達式為我們提供了一種從開關大小寫的分支返回值的方法,然後將其賦值給變量。語法是差不多了和我們以前用過的一樣,只是每個箱子都是用箭頭從樹枝上射出的,->,不是:,沒有必要break聲明。
在下面的示例中,我們分配int變量的值index,我們不需要指定它的類型,因為最近Java迭代中的另一個很好的特性是自動類型推斷var.
public Person create(String name, EmotionalState state) {
var index = switch (state) {
case SAD -> -1;
case HAPPY -> 1;
case NEUTRAL -> 0;
};
// todo
}
帶著
index
在手,我們可以創造必要的
PreparedStatement
需要對數據庫執行SQL語句。我們可以執行準備好的語句並傳入一個
KeyHolder
它將用於收集從新插入的行返回的生成密鑰。
public Person create(String name, EmotionalState state) {
var index = switch (state) {
case SAD -> -1;
case HAPPY -> 1;
case NEUTRAL -> 0;
};
var declaredParameters = List.of(
new SqlParameter(Types.VARCHAR, "name"),
new SqlParameter(Types.INTEGER, "emotional_state"));
var pscf = new PreparedStatementCreatorFactory(this.insertSql, declaredParameters) {
{
setReturnGeneratedKeys(true);
setGeneratedKeysColumnNames("id");
}
};
var psc = pscf.newPreparedStatementCreator(List.of(name, index));
var kh = new GeneratedKeyHolder();
this.template.update(psc, kh);
// todo
}
唯一的問題是返回的密鑰是
Number
,而不是
Integer
或者是
Double
或者任何更具體的東西。這讓我們有機會在Java 14中使用另一個有趣的新特性,即智能轉換。智能轉換允許我們在測試
instanceof
測試一下。它更進一步,給出了一個變量名,通過它我們可以引用測試範圍中的自動強制轉換變量。
public Person create(String name, EmotionalState state) {
var index = switch (state) {
case SAD -> -1;
case HAPPY -> 1;
case NEUTRAL -> 0;
};
var declaredParameters = List.of(
new SqlParameter(Types.VARCHAR, "name"),
new SqlParameter(Types.INTEGER, "emotional_state"));
var pscf = new PreparedStatementCreatorFactory(this.insertSql, declaredParameters) {
{
setReturnGeneratedKeys(true);
setGeneratedKeysColumnNames("id");
}
};
var psc = pscf.newPreparedStatementCreator(List.of(name, index));
var kh = new GeneratedKeyHolder();
this.template.update(psc, kh);
if (kh.getKey() instanceof Integer id) {
return findById(id);
}
throw new IllegalArgumentException("we couldn't create the " + Person.class.getName() + "!");
}
我們需要一個
int
才能把它傳遞給
findById(Integer)
這種方法對我們來說是可行的。方便,嗯?
一切正常,所以讓我們用一個簡單的
ApplicationListener<applicationreadyevent>
:
@Component
class Runner {
private final PeopleService peopleService;
Runner(PeopleService peopleService) {
this.peopleService = peopleService;
}
@EventListener(ApplicationReadyEvent.class)
public void exercise() throws Exception {
var elizabeth = this.peopleService.create("Elizabeth", EmotionalState.SAD);
System.out.println(elizabeth);
}
}
運行它,您將看到對象已經寫入數據庫,而且--最好的是--您得到了一個漂亮的新
toString()
打印結果時的結果。
Person
反對!
我們剛剛開始觸及Java 14中所有新特性的表面!在這個視頻中,我們已經開始在語言中引入了大量的新特性,並且在運行時本身有更多的安全性和性能特性。我非常誠懇地建議您找到擺脫JDK舊版本的方法(看看您,Java 8用戶!)轉移到最新的。
為感謝您對我們的認可,特意準備了一些IT入門和進階的乾貨
包括:Java、UI設計、H5前端、Python+人工智能、軟件測試和新媒體運營六大學科視頻資料。以及IT就業大禮包。
線上視頻、音頻,隨時學習觀看
關注我們並私信“資料”即可獲取。
"/<applicationreadyevent>閱讀更多 源碼時代 的文章
關鍵字: 技巧 PostgreSQL 深入研究