Це дуже поширене питання, тому я вирішив перетворити цю відповідь також у статтю .
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
}
]
}
"""
)
);
З тих пір, як я використовував C # у 2004 році, я хотів мати цю функцію на Java, і тепер ми її нарешті маємо.
string1 + string2
виділяєте новий об'єкт рядка та копіюєте символи з обох вхідних рядків. Якщо ви додаєте n рядків разом, ви б робили виділення n-1 і приблизно (n ^ 2) / 2 копії символів. StringBuilder, з іншого боку, копіює та перерозподіляє рідше (хоча це все одно робить обидва, коли ви перевищуєте розміри внутрішнього буфера). Теоретично існують випадки, коли компілятор міг перетворити + для використання StringBuilder, але на практиці хто це знає.