質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

JSP

JSP(Java Server Pages)とは、ウェブアプリケーションの表示レイヤーに使われるサーバーサイドの技術のことです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Q&A

解決済

2回答

2629閲覧

【JSP・Servlet・SQL】DBからの結果表示がうまくできない

ysda

総合スコア65

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

JSP

JSP(Java Server Pages)とは、ウェブアプリケーションの表示レイヤーに使われるサーバーサイドの技術のことです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

0グッド

1クリップ

投稿2020/09/03 09:00

編集2020/09/07 02:44

発生している問題・エラーメッセージ

試験の成績表を出力するプログラムの作成中で、以下のテーブルを使用しています。

studentテーブル

student_id(生徒ID)student_name(生徒名)student_furigana(生徒カナ)school_year(学年)school_class(クラス)

イメージ説明

subjectテーブル

subject_id(教科ID)subject_name(教科名)

イメージ説明

test_resultsテーブル

student_id(外部キー)subject_id(外部キー)score(得点)test_day(試験日)

イメージ説明

下記のような成績表を出力したいと考えています。
イメージ説明](77080b8ae922464ee958865e1c678e8c.png)

最初の成績表はうまく出力されているのですが、
2つ目以降の成績表は上部の学年・クラス・生徒ID・名前のみしか出力されていない状態になっております。

↓理想形
イメージ説明

↓現状
イメージ説明

該当のソースコード

TestResultsRegistEditServlet.java
test-results-regist.jsp(後述)の検索押下時に実行

//インポート省略 public class TestResultsRegistEditServlet extends HttpServlet{ Connection conn = null; PreparedStatement ps = null; ResultSet result = null; ResultSet result2 = null; ResultSet preTestDayResult = null; String user = "suser"; String password = "spass"; String url = "jdbc:mysql://localhost:3306/mydb?autoReconnect=true&useSSL=false"; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ request.setCharacterEncoding("UTF-8"); String mode = request.getParameter("mode"); String status = "Success!"; boolean existRegistErr = false; String student_id = request.getParameter("student_id"); String student_name = request.getParameter("student_name"); String school_year = request.getParameter("school_year"); String school_class = request.getParameter("school_class"); String test_day = request.getParameter("test_day"); String subject_id = request.getParameter("subject_id"); String score = request.getParameter("score"); //中略 try { System.out.println(mode); Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url, user, password); String preTestDaySql = "select distinct test_day from test_results order by test_day"; ps = conn.prepareStatement(preTestDaySql); ps.execute(); preTestDayResult = ps.executeQuery(); request.setAttribute("preTestDayResult", preTestDayResult); StringBuffer testResultsSql = new StringBuffer(); testResultsSql.append("select distinct student.school_year, student.school_class, student.student_id, student.student_name "); testResultsSql.append("from test_results inner join student on student.student_id = test_results.student_id inner join subject on subject.subject_id = test_results.subject_id "); testResultsSql.append("where test_day like '%"); testResultsSql.append(test_day + "%'"); StringBuffer sql2 = new StringBuffer(); sql2.append("select test_results.student_id, test_results.subject_id, subject.subject_name, score, test_day from test_results "); sql2.append("inner join student on student.student_id = test_results.student_id "); sql2.append("inner join subject on subject.subject_id = test_results.subject_id "); sql2.append("where test_day like '%"); sql2.append(test_day + "%'"); if(!school_year.equals("") && !school_class.equals("")) {//学年クラスともに入力済み testResultsSql.append("and student.student_id in (select student_id from student where school_year = "); testResultsSql.append(school_year); testResultsSql.append(" and school_class = "); testResultsSql.append(school_class); testResultsSql.append(") order by student.student_id, subject.subject_id"); sql2.append("and student.student_id in (select student_id from student where school_year = "); sql2.append(school_year); sql2.append(" and school_class = "); sql2.append(school_class); sql2.append(") order by student.student_id, subject.subject_id"); } else if(school_year.equals("") || school_class.equals("")) { if(school_year.equals("") && school_class.equals("")) { testResultsSql.append(" order by student.student_id, subject.subject_id"); sql2.append(" order by student.student_id, subject.subject_id"); } else if(!school_year.equals("")) { testResultsSql.append("and student.student_id in (select student_id from student where school_year = "); testResultsSql.append(school_year); testResultsSql.append(") order by student.student_id, subject.subject_id"); sql2.append("and student.student_id in (select student_id from student where school_year = "); sql2.append(school_year); sql2.append(") order by student.student_id, subject.subject_id"); } else if(!school_class.equals("")) { testResultsSql.append("and student.student_id in (select student_id from student where school_class = "); testResultsSql.append(school_class); testResultsSql.append(") order by student.student_id, subject.subject_id"); sql2.append("and student.student_id in (select student_id from student where school_class = "); sql2.append(school_class); sql2.append(") order by student.student_id, subject.subject_id"); } } ps = conn.prepareStatement(new String(testResultsSql)); System.out.println(ps); ps.execute(); result = ps.executeQuery(); ps = conn.prepareStatement(new String(sql2)); System.out.println(ps); ps.execute(); result2 = ps.executeQuery(); request.setAttribute("result", result); request.setAttribute("result2", result2); request.getRequestDispatcher("test-results-regist.jsp").forward(request, response); } catch(Exception e) { e.printStackTrace(); } finally { try { conn.close(); } catch (SQLException e) { System.out.println("MySQLのクローズに失敗しました。"); } } //以下省略

test-results-regist.jsp

//省略 <% ResultSet preStudentResult = (ResultSet) request.getAttribute("preStudentResult"); ResultSet preSubjectResult = (ResultSet) request.getAttribute("preSubjectResult"); ResultSet preTestDayResult = (ResultSet) request.getAttribute("preTestDayResult"); ResultSet result = (ResultSet) request.getAttribute("result"); ResultSet result2 = (ResultSet) request.getAttribute("result2"); String student_id = (String) request.getAttribute("student_id"); String student_name = (String) request.getAttribute("student_name"); String test_day = (String) request.getAttribute("test_day"); String school_year = (String) request.getAttribute("school_year"); String school_class = (String) request.getAttribute("school_class"); String score = (String)request.getAttribute("score"); %> //中略 <div id="search" class="tab-pane active"> <h2>試験結果検索</h2> <div class="input-form"> <form action="testResultsRegistEdit" method="post"> <table class="input-form-table"> <tr> <td>試験日</td> <td> <select name="test_day"> <option value="">すべての試験日</option> <% if(preTestDayResult != null) { %> <% while(preTestDayResult.next()) { %> <option value="<%=preTestDayResult.getString(1) %>"><%=preTestDayResult.getString(1) %></option> <% } %> <% } %> </select> </td> </tr> <tr> <td>学年</td> <td> <%if(school_year_searched != null) {%> <input type="text" id="year" name="school_year" maxlength='10' value="<%=school_year_searched %>" placeholder="学年(半角数字)"> <%} else {%> <input type="text" id="year" name="school_year" maxlength='10' placeholder="学年(半角数字)"> <%} %> </td> </tr> <tr> <td>クラス</td> <td> <%if(school_class_searched != null) {%> <input type="text" id="class" name="school_class" maxlength='10' value="<%=school_class_searched %>" placeholder="クラス(半角数字)"> <%} else {%> <input type="text" id="class" name="school_class" maxlength='10' placeholder="クラス(半角数字)"> <%} %> </td> </tr> </table> <div class="submit-button text-center"> <input type="hidden" name="mode" value="search"> <input type="submit" value="検索" > </div> </form> </div> <% ResultSet result = (ResultSet) request.getAttribute("result"); ResultSet result2 = (ResultSet) request.getAttribute("result2"); %> <%if(result != null && result2 != null) {%> <% while(result.next()) {%> <table class="table table-bordered search-result-table"> <thead> <tr> <th>学年</th> <th>クラス</th> <th>生徒ID</th> <th>名前</th> </tr> </thead> <tbody> <tr> <td><%=result.getString(1)%></td> <td><%=result.getString(2)%></td> <td><%=result.getString(3)%></td> <td><%=result.getString(4)%></td> </tr> </tbody> <thead> <tr> <th>科目</th> <th>得点</th> <th>試験日</th> <th>更新</th> <th>削除</th> </tr> </thead> <tbody> <%while(result2.next()) {%> <%if(result2.getString(1).equals(result.getString(3))) { %> <tr> <td><%=result2.getString(3) %></td> <td><%=result2.getString(4) %></td> <td><%=result2.getString(5) %></td> <td>更新</td> <td>削除</td> </tr> <%} %> <%} %> </tbody> </table> <%} %> <%} %> </div> //以下省略

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A-pZ

2020/09/03 11:02

投入されているデータならびにSQLの実行条件(SQLが動的に変更されているため)がないと判断がつかないかと。
ysda

2020/09/04 01:58

申し訳ございません。ただいまテーブルのデータとサーブレットの実行条件を追記しました。
guest

回答2

0

ベストアンサー

サーブレット側で検索した結果(ResultSet)のままJSPに渡すのでも実現はできるのですが、ResultSetの内容を取り出してListに格納→これをリクエスト属性へ格納→JSPはそれを繰り返し表示するだけの方がJSPのコードが書きやすくなります。

また、PreparedStatementの実行部分で少し余分な実装があります。

java

1PreparedStatement statement = conn.createStatement(); 2ResultSet rs = statement.executeQuery(sql); 3 4List<TestResult> testResults = new ArrayList<>(); 5whie (rs.next()) { 6 String schoolYear = rs.getString(1); // rs.getString("school_year"); でも可 7 .... 8 9 TestResult testResult = new TestResult(); 10 testResult.setSchoolYear(schoolYear); 11 .... 12 13 testResults.add(testResult); 14} 15 16request.setAttribute("testResults", testResults); 17...

java

1public class TestResult { 2 private String schoolYear; 3 public void setSchoolYear(String schoolYear) { 4 this.schoolYear = schoolYear; 5 } 6 public String getSchoolYear() { 7 return schoolYear; 8 } 9 10..(他test_Resultの検索結果を格納する列の数だけフィールドとメソッドを追加)... 11}

こうすればJSPでは、testResultsの内容を繰り返し表示するだけです。もう1つの方も別途ループを作成すれば問題なく表示できるでしょう。

なお、ResultSetのget**** メソッドは、その番号を指定する方法以外にも、SQLの項目名を指定する方法もできます。(番号指定は、SQLの内容が変わったときにメンテナンスしにくくなりやすいです)

投稿2020/09/07 03:21

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ysda

2020/09/07 07:28

丁寧なご回答をいただきまして誠にありがとうございます。 こちらのソースを参考に、実装を試みます。
ysda

2020/09/07 08:04

いただいたソースをもとに、期待通りの結果を得ることができました。 DBからの取得した内容をListにするやり方について、理解することができました。 ありがとうございました。
guest

0

調べてみたところ、どうやらResultSetのnextは一回きりしか行えないようでした。
(nextメソッドを走らせたら、終了時にはResultSetの中身は消える?ようです)
そのため、現在の構造だとそもそも不可能であるため、JSPの作り自体を変える必要があるみたいです。
別の方法で修正ができた際には、改めて記載したいと考えています。

投稿2020/09/07 02:41

ysda

総合スコア65

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問