C'est une question très courante, j'ai donc décidé de transformer cette réponse en article également .
Java 13 et au-delà
Les chaînes multilignes sont désormais prises en charge en Java via les blocs de texte . En Java 13 et 14, cette fonctionnalité nécessite que vous définissiez l' ––enable–preview
option lors de la création et de l'exécution de votre projet. Consultez cette documentation Java pour plus de détails.
Maintenant, avant Java 13, voici comment vous écririez une requête:
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();
Grâce aux blocs de texte Java 13, vous pouvez réécrire cette requête comme suit:
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();
Beaucoup plus lisible, non?
Prise en charge IDE
IntelliJ IDEA prend en charge la transformation des String
blocs de concaténation hérités au nouveau String
format multiligne :
JSON, HTML, XML
La multiligne String
est particulièrement utile lors de l'écriture de JSON, HTML ou XML.
Considérez cet exemple en utilisant la String
concaténation pour créer un littéral de chaîne 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" +
" }" +
" ]" +
"}"
)
);
Vous pouvez à peine lire le JSON en raison des caractères qui s'échappent et de l'abondance de guillemets doubles et de signes plus.
Avec Java Text Blocks, l'objet JSON peut être écrit comme ceci:
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
}
]
}
"""
)
);
Depuis que j'ai utilisé C # en 2004, je voulais avoir cette fonctionnalité en Java, et maintenant nous l'avons enfin.
string1 + string2
vous allouez un nouvel objet chaîne et copiez les caractères des deux chaînes d'entrée. Si vous ajoutez n chaînes ensemble, vous feriez n-1 allocations et environ (n ^ 2) / 2 copies de caractères. StringBuilder, en revanche, copie et réaffecte moins fréquemment (bien qu'il fasse toujours les deux lorsque vous dépassez la taille de son tampon interne). Théoriquement, il y a des cas où le compilateur pourrait convertir + pour utiliser StringBuilder mais en pratique qui sait.