カテゴリ: Thymeleaf 更新日: 2025/12/13

Thymeleafのth:eachの使い方!ループ回数やindexなどの繰り返し処理を学ぼう

Thymeleafのth:eachの使い方
Thymeleafのth:eachの使い方

先生と生徒の会話形式で理解しよう

生徒

「Thymeleafで複数のデータを表示する方法ってありますか?」

先生

「はい、Thymeleafではth:each属性を使って、リストや配列のデータを簡単にループ表示できます。」

生徒

「どうやって使うんですか?」

先生

「では、基本的な使い方を説明していきましょう!」

1. th:each属性とは?

1. th:each属性とは?
1. th:each属性とは?

Thymeleafのth:each属性は、HTML内でループを作成し、リストや配列の要素を順番に表示するために使用します。例えば、商品一覧やユーザーリストをページに表示したいときに役立ちます。

基本的な構文は次の通りです:


<ul>
    <li th:each="item : ${items}">
        [[${item}]]
    </li>
</ul>

このコードでは、${items}にリストがバインドされていると、各要素がitemとしてループ内に展開されます。

2. 実際の例で学ぶth:eachの使い方

2. 実際の例で学ぶth:eachの使い方
2. 実際の例で学ぶth:eachの使い方

それでは、具体的なサンプルコードを見てみましょう。以下は、商品リストを表示する例です:


<table class="table table-striped">
    <thead>
        <tr>
            <th>商品名</th>
            <th>価格</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="product : ${productList}">
            <td>[[${product.name}]]</td>
            <td>[[${product.price}]]円</td>
        </tr>
    </tbody>
</table>

この例では、${productList}に商品データのリストが入っていると、productオブジェクトのnamepriceの情報がテーブルとして表示されます。

3. th:eachの変数を使いこなそう

3. th:eachの変数を使いこなそう
3. th:eachの変数を使いこなそう

th:each属性を使うと、インデックス情報や偶数・奇数行の識別など、便利な変数も利用できます:


<tr th:each="product, iterStat : ${productList}" th:class="${iterStat.odd ? 'table-secondary' : ''}">
    <td>[[${iterStat.index + 1}]]</td>  <!-- インデックス (0から始まるので+1) -->
    <td>[[${product.name}]]</td>
    <td>[[${product.price}]]円</td>
</tr>

このように、iterStatを使用することでインデックスや行の状態(奇数・偶数)を管理できます。

4. th:eachを使うときの注意点

4. th:eachを使うときの注意点
4. th:eachを使うときの注意点

繰り返し処理を行う際、Nullのリストや空のリストに注意が必要です。th:eachで使用するオブジェクトがnullの場合、例外が発生する可能性があります。そのため、事前にデータがあるか確認するか、Thymeleafのth:ifを組み合わせることで安全に表示できます:


<div th:if="${productList != null && !productList.isEmpty()}">
    <!-- th:eachによるループ -->
</div>

5. ループ回数を制御する(上位N件・ページング)

5. ループ回数を制御する(上位N件・ページング)
5. ループ回数を制御する(上位N件・ページング)

「上位N件だけ表示したい」「ページングしたい」ときは、subListth:withで範囲を切ってからth:eachに渡すのがシンプルです。SEO的にも一覧の表示量を抑えて表示速度を高めるのは有効です。


<!-- 上位5件のみ -->
<ul>
  <li th:each="p : ${productList.subList(0, productList.size() >= 5 ? 5 : productList.size())}">
    [[${p.name}]] / [[${p.price}]]円
  </li>
</ul>

<!-- 簡易ページング:クエリ ?page=0&size=10 を想定(endは排他的) -->
<div th:with="
    page=${param.page ?: 0},
    size=${param.size ?: 10},
    start=${page * size},
    end=${start + size},
    last=${productList.size()},
    from=${start < last ? start : last},
    to=${end <= last ? end : last}
">
  <table>
    <tr th:each="p,st : ${productList.subList(from, to)}">
      <td>[[${from + st.index + 1}]]</td>
      <td>[[${p.name}]]</td>
      <td>[[${p.price}]]円</td>
    </tr>
  </table>
</div>

6. 反復ステータスを極める(index/count/size/odd・even/first・last)

6. 反復ステータスを極める(index/count/size/odd・even/first・last)
6. 反復ステータスを極める(index/count/size/odd・even/first・last)

th:each="item, stat : ${list}"の第2変数statには便利なプロパティが揃っています。行番号や奇数偶数、先頭末尾を使って装飾・区切り・No.付与ができます。


<tr th:each="product, stat : ${productList}"
    th:class="${stat.odd} ? 'table-secondary' : ''">
  <td>No. [[${stat.count}]] / 全[[${stat.size}]]件</td>   <!-- countは1始まり -->
  <td>[[${product.name}]]</td>
  <td>[[${product.price}]]円
    <span th:if="${stat.first}" class="badge bg-info ms-2">NEW</span>
    <span th:if="${stat.last}" class="badge bg-secondary ms-1">LAST</span>
  </td>
</tr>

<!-- 区切り文字の制御:最後のカンマを出さない -->
<span th:each="tag, s : ${product.tags}">
  [[${tag}]]<span th:if="${!s.last}">, </span>
</span>

7. ネストしたループとMapの反復(親子リスト/key・value)

7. ネストしたループとMapの反復(親子リスト/key・value)
7. ネストしたループとMapの反復(親子リスト/key・value)

カテゴリごとに商品を出すなどの「親子リスト」や、Mapのkey/valueを回す方法です。親ループのstatで章番号を付けるなど、構造化された一覧に強いです。



<div th:each="cat, cStat : ${categoryList}" class="mb-3">
  <h4>[[${cStat.count}]]. [[${cat.name}]]</h4>
  <ol>
    <li th:each="p, pStat : ${cat.products}">
      [[${cStat.count}]].[[${pStat.count}]] [[${p.name}]]([[${p.price}]]円)
    </li>
  </ol>
</div>

<!-- Mapをループ:エントリ(key/value)  -->
<table class="table">
  <tr><th>キー</th><th>値</th></tr>
  <tr th:each="e : ${priceMap}">
    <td>[[${e.key}]]</td>
    <td>[[${e.value}]]</td>
  </tr>
</table>

大きなコレクションはページングや「上位N件」に分割し、表示速度と可読性を両立しましょう(「Thymeleaf th:each ページング」「index 行番号」などの検索ニーズにもマッチ)。

まとめ

まとめ
まとめ

今回は、Thymeleafのth:each属性を使った繰り返し処理について詳しく解説しました。th:eachを使用することで、HTML内でのループが簡単に実現でき、Webアプリケーションにおいてリストデータや配列を動的に表示する場面で非常に役立つことを学びました。また、iterStatを用いることでインデックス情報や偶数・奇数の識別など、便利な機能も活用できる点を紹介しました。さらに、データがnullや空のリストである際の対処方法として、th:ifとの併用も有効であることを示しました。

繰り返し処理を活用することで、ユーザビリティの高いページを作成でき、エラーの発生を防ぐために事前のデータチェックも欠かせません。これらのポイントを理解しておくと、Web開発の幅が広がり、動的なコンテンツ生成が一層効率化されます。

以下は、簡単なサンプルプログラムを再度示したものです:


<table class="table table-striped">
    <thead>
        <tr>
            <th>#</th>
            <th>商品名</th>
            <th>価格</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="product, iterStat : ${productList}" th:class="${iterStat.odd ? 'table-secondary' : ''}">
            <td>[[${iterStat.index + 1}]]</td> <!-- インデックス (0から始まるので+1) -->
            <td>[[${product.name}]]</td>
            <td>[[${product.price}]]円</td>
        </tr>
    </tbody>
</table>
先生と生徒の振り返り会話

生徒

「Thymeleafのth:eachを使った繰り返し処理について、よく分かりました。インデックスや行のスタイルを簡単にコントロールできるのが便利ですね。」

先生

「そうですね。iterStatなどの変数を活用すれば、さらに細かな制御が可能になります。実際の開発でも試してみてください。」

生徒

「はい、ありがとうございます!th:ifを使ってデータの有無をチェックする方法も覚えておきます。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Thymeleafのth:eachと通常のループ処理の違いは何ですか?

th:eachはHTMLテンプレート内でリストや配列を繰り返し処理するためのThymeleaf専用の属性です。通常のループ処理とは異なり、HTML要素に直接データをバインドできる点が特徴です。

初心者でも簡単にth:eachを使いこなせますか?

はい、簡単です。基本的にはth:each="変数 : ${リスト}"の形式で書くだけで、リストや配列の要素を順番にHTMLに表示できます。

th:eachで使用できる特別な変数には何がありますか?

th:eachではiterStatという変数が利用可能で、インデックス番号、奇数・偶数行の情報、最初や最後の要素かどうかを簡単に取得できます。

Thymeleafでth:eachを使うときの注意点はありますか?

注意点として、対象となるリストがnullや空の場合、エラーが発生する可能性があります。そのため、th:ifで事前にデータの有無をチェックするのがおすすめです。

th:eachを使って商品リストをテーブル表示する方法を教えてください。

商品リストを表示するには、th:each="product : ${productList}"を使用してテーブル行をループさせ、各列に商品の情報を埋め込みます。これにより、リスト内の全商品が動的に表示されます。

奇数行や偶数行にスタイルを付けたいとき、th:eachでどうすればいいですか?

th:eachiterStatを使い、th:class="${iterStat.odd ? 'odd-class' : 'even-class'}"のように条件分岐を記述すると、奇数行と偶数行に異なるスタイルを適用できます。

リストが空の場合にメッセージを表示するにはどうしたらいいですか?

th:ifを使用して、リストが空のときだけ特定のメッセージを表示するコードを記述します。これにより、リストが空の状態でも適切なフィードバックが表示されます。

インデックス番号を表示したい場合、th:eachでどう記述すればいいですか?

インデックス番号はiterStat.indexで取得できます。これを使用して、リスト内の要素に対して順序を付けて表示できます。

Thymeleafのth:eachを使ったコードが長くなる場合、どのように管理すれば良いですか?

コードが長くなる場合、CSSクラスやJavaScriptを併用してスタイルや動作を簡略化することをおすすめします。また、Thymeleafのフラグメント機能を活用してHTMLパーツを再利用することも効果的です。

th:eachで配列をループする場合のポイントは何ですか?

配列をループする場合もリストと同じように扱えます。Java側で配列をリストに変換しておくと、Thymeleafでより柔軟に操作できます。
カテゴリの一覧へ
新着記事
Thymeleafのth:fragmentを使ったテンプレートの再利用方法を完全ガイド!初心者でもわかる使い方
Javaの@PathVariableアノテーションの使い方を徹底解説!初心者でもわかるパスパラメータの基本と応用
SpringのBindingResult完全ガイド!初心者でもわかる入力チェックとgetTargetの使い方
Thymeleafのth:data-*属性を使いこなす!初心者向け完全解説
人気記事
No.1
Java&Spring記事人気No1
Javaのラムダ式で配列を扱う!Arrays.streamの基本と注意点を初心者向けに解説
No.2
Java&Spring記事人気No2
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.3
Java&Spring記事人気No3
JavaのRuntimeExceptionを完全解説!初心者でもわかるjava.langパッケージの基礎
No.4
Java&Spring記事人気No4
JavaのIntegerクラスの使い方を完全ガイド!初心者でもわかる整数操作
No.5
Java&Spring記事人気No5
JavaのBigDecimalクラスcompareToメソッド完全ガイド!初心者でもわかる大小比較の基本
No.6
Java&Spring記事人気No6
Springの@Serviceアノテーションの使い方を徹底解説!初心者でもわかるSpring フレームワーク入門
No.7
Java&Spring記事人気No7
JavaのHttpSessionを徹底解説!初心者でもわかるセッション管理の基本
No.8
Java&Spring記事人気No8
JSPとは何か?初心者向けにできること・仕組み・特徴をやさしく解説