这是一个非常常见的问题,所以我决定也将这个答案变成一篇文章。
Java 13及更高版本
Java现在通过文本块支持多行字符串。在Java 13和14中,此功能要求您––enable–preview
在构建和运行项目时设置选项。查看此Java文档以获取更多详细信息。
现在,在Java 13之前,这是您编写查询的方式:
List<Tuple> posts = entityManager
.createNativeQuery(
"SELECT *\n" +
"FROM (\n" +
" SELECT *,\n" +
" dense_rank() OVER (\n" +
" ORDER BY \"p.created_on\", \"p.id\"\n" +
" ) rank\n" +
" FROM (\n" +
" SELECT p.id AS \"p.id\",\n" +
" p.created_on AS \"p.created_on\",\n" +
" p.title AS \"p.title\",\n" +
" pc.id as \"pc.id\",\n" +
" pc.created_on AS \"pc.created_on\",\n" +
" pc.review AS \"pc.review\",\n" +
" pc.post_id AS \"pc.post_id\"\n" +
" FROM post p\n" +
" LEFT JOIN post_comment pc ON p.id = pc.post_id\n" +
" WHERE p.title LIKE :titlePattern\n" +
" ORDER BY p.created_on\n" +
" ) p_pc\n" +
") p_pc_r\n" +
"WHERE p_pc_r.rank <= :rank\n",
Tuple.class)
.setParameter("titlePattern", "High-Performance Java Persistence %")
.setParameter("rank", 5)
.getResultList();
感谢Java 13文本块,您可以按以下方式重写此查询:
List<Tuple> posts = entityManager
.createNativeQuery("""
SELECT *
FROM (
SELECT *,
dense_rank() OVER (
ORDER BY "p.created_on", "p.id"
) rank
FROM (
SELECT p.id AS "p.id",
p.created_on AS "p.created_on",
p.title AS "p.title",
pc.id as "pc.id",
pc.created_on AS "pc.created_on",
pc.review AS "pc.review",
pc.post_id AS "pc.post_id"
FROM post p
LEFT JOIN post_comment pc ON p.id = pc.post_id
WHERE p.title LIKE :titlePattern
ORDER BY p.created_on
) p_pc
) p_pc_r
WHERE p_pc_r.rank <= :rank
""",
Tuple.class)
.setParameter("titlePattern", "High-Performance Java Persistence %")
.setParameter("rank", 5)
.getResultList();
更具可读性,对不对?
IDE支持
IntelliJ IDEA支持将旧式String
串联块转换为新的多行String
格式:
JSON,HTML,XML
String
在编写JSON,HTML或XML时,多行特别有用。
考虑一下使用String
串联构建JSON字符串文字的示例:
entityManager.persist(
new Book()
.setId(1L)
.setIsbn("978-9730228236")
.setProperties(
"{" +
" \"title\": \"High-Performance Java Persistence\"," +
" \"author\": \"Vlad Mihalcea\"," +
" \"publisher\": \"Amazon\"," +
" \"price\": 44.99," +
" \"reviews\": [" +
" {" +
" \"reviewer\": \"Cristiano\", " +
" \"review\": \"Excellent book to understand Java Persistence\", " +
" \"date\": \"2017-11-14\", " +
" \"rating\": 5" +
" }," +
" {" +
" \"reviewer\": \"T.W\", " +
" \"review\": \"The best JPA ORM book out there\", " +
" \"date\": \"2019-01-27\", " +
" \"rating\": 5" +
" }," +
" {" +
" \"reviewer\": \"Shaikh\", " +
" \"review\": \"The most informative book\", " +
" \"date\": \"2016-12-24\", " +
" \"rating\": 4" +
" }" +
" ]" +
"}"
)
);
由于转义字符以及大量的双引号和加号,您几乎无法读取JSON。
使用Java文本块,可以这样编写JSON对象:
entityManager.persist(
new Book()
.setId(1L)
.setIsbn("978-9730228236")
.setProperties("""
{
"title": "High-Performance Java Persistence",
"author": "Vlad Mihalcea",
"publisher": "Amazon",
"price": 44.99,
"reviews": [
{
"reviewer": "Cristiano",
"review": "Excellent book to understand Java Persistence",
"date": "2017-11-14",
"rating": 5
},
{
"reviewer": "T.W",
"review": "The best JPA ORM book out there",
"date": "2019-01-27",
"rating": 5
},
{
"reviewer": "Shaikh",
"review": "The most informative book",
"date": "2016-12-24",
"rating": 4
}
]
}
"""
)
);
自从2004年使用C#以来,我一直希望在Java中具有此功能,现在终于有了它。
string1 + string2
您分配新的字符串对象并从两个输入字符串中复制字符时,StringBuilder.append()都比plus更可取。如果将n个字符串加在一起,则将进行n-1个分配和大约(n ^ 2)/ 2个字符的复制。另一方面,StringBuilder的复制和重新分配的频率降低了(尽管当您超出其内部缓冲区的大小时,它仍然会进行复制和重新分配)。从理论上讲,在某些情况下,编译器可以将+转换为使用StringBuilder,但实际上是谁知道的。