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

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

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

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

Q&A

解決済

1回答

655閲覧

java DAOを使って取得ができない

kyakya

総合スコア1

Java

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

1グッド

0クリップ

投稿2024/07/17 02:51

編集2024/07/18 13:47

実現したいこと

mysqlにて、userテーブル

fieldtypenullkeyDefaultExtra
idvarchar(5)NONULL
namevarchar(20)YESNULL
passvarchar(20)YESNULL
depintYESNULL

depテーブル

FieldTypeNullKeyDefaultExtra
idvarchar(5)NONULL
namevarchar(20)YESNULL

を作成し、
userテーブルには、

idnamepassdep
1山田 太郎pass11
2山田 花子pass22
3山田 三郎pass31

depテーブルには、

idname
1管理部
2システム開発部
3教育事業部

を登録しました。
login.jsp よりidとpassを入力しログインボタンを押すと、LoginUserServletConf.javaからUserDao.javaへ行き、userテーブルとdepテーブルから参照取得してLoginUserServletConf.javaに戻り、 menu.jspで”部署:○○ 氏名:○○”と表示させたい。

発生している問題・分からないこと

遷移はするが、部署がNULLで返ってきます。

エラーメッセージ

error

1遷移はされる為、エラーメッセージはありません。

該当のソースコード

java

1import java.io.IOException; 2import javax.servlet.RequestDispatcher; 3import javax.servlet.ServletException; 4import javax.servlet.http.HttpServlet; 5import javax.servlet.http.HttpServletRequest; 6import javax.servlet.http.HttpServletResponse; 7import javax.servlet.http.HttpSession; 8 9 public class UserDao extends HttpServlet { 10 11 public void doGet (HttpServletRequest req, HttpServletResponse res) 12 throws ServletException, IOException { 13 doPost( req, res ); 14 } 15 16 public void doPost(HttpServletRequest req, HttpServletResponse res) 17 throws ServletException, IOException { 18 19 res.setContentType("text/html;charset=UTF-8"); 20 req.setCharacterEncoding("UTF-8"); 21 22 //セッションの取得 23 HttpSession session = req.getSession(true); 24 25 String forward=null; 26 27 //ログインがおされた 28 if(req.getParameter("submit").equals("ログイン")){ 29 30 String uid=req.getParameter("uid"); 31 String upass=req.getParameter("upass"); 32 33 //DAOをインスタンス化 34 UserDao logindao= new UserDao(); 35 //DAOを使用してID・パスワードをチェックする 36 UserBean bean=logindao.loginCheck(uid, upass); 37 DepBean bean2=logindao.loginCheck2(uid,upass); 38 //もし該当者がいれば 39 if(bean != null){ 40 session.setAttribute("uname",bean.getName()); 41 session.setAttribute("dname",bean2.getName()); 42 forward="/web/menu.jsp"; 43 }else{ 44 req.setAttribute("errMsg","※ログインID・パスワードが違います"); 45 forward="/web/login.jsp"; 46 } 47 } 48 RequestDispatcher rd = req.getRequestDispatcher(forward); 49 rd.forward(req, res); 50 } 51 }

java

1import java.sql.PreparedStatement; 2import java.sql.ResultSet; 3import java.sql.SQLException; 4 5public class extends DBAccess{ 6 7 //ユーザーIDとパスワードを使用し、情報を取得し返却する 8 public UserBean loginCheck(String uid ,String upass) { 9 10 UserBean user=null; 11 12 String sql1 = "select * from user where id=? && pass=?"; 13 try { 14 connect(); 15 // ステートメントの作成 16 PreparedStatement ps = getConnection().prepareStatement(sql1); 17 ps.setString(1, uid); 18 ps.setString(2, upass); 19 //select文の実行(値を取得) 20 ResultSet rs=ps.executeQuery(); 21 //値が取得してこれたら 22 if(rs.next()){ 23 //UserBeanを実体化 24 user= new UserBean(); 25 //値の格納 26 user.setName(rs.getString("name")); 27 user.setId(rs.getString("id")); 28 user.setPass(rs.getString("pass")); 29 user.setDep(rs.getInt("dep")); 30 } 31 } catch (SQLException e) { 32 e.printStackTrace(); 33 } finally { 34 disconnect(); 35 } 36 return user; 37 } 38 39 //ユーザーIDとパスワードを使用し、情報を取得し返却する 40 public DepBean loginCheck2(String uid , String upass) { 41 UserBean user=null; 42 DepBean dep =null; 43 String sql2 ="SELECT dep.name FROM user INNER JOIN dep ON user.dep = dep.id WHERE user.id = ? AND user.pass = ?"; 44 try { 45 connect(); 46 // ステートメントの作成 47 PreparedStatement ps2 = getConnection().prepareStatement(sql2); 48 ps2.setString(1, uid); 49 ps2.setString(2, upass); 50 //select文の実行(値を取得) 51 ResultSet rs2=ps2.executeQuery(); 52 //値が取得してこれたら 53 if(rs2.next()){ 54 //DepBeanを実体化 55 dep= new DepBean(); 56 //値の格納 57 dep.setName(rs2.getString("id")); 58 dep.setId(rs2.getString("name")); 59 } 60 } catch (SQLException e) { 61 e.printStackTrace(); 62 } finally { 63 disconnect(); 64 } 65 return dep; 66}

java

1import java.io.Serializable; 2public class DepBean implements Serializable { 3 private String id; 4 private String name; 5 6 7 public String getId() { 8 return id; 9 } 10 public void setId(String id) { 11 this.id = id; 12 } 13 14 15 public String getName() { 16 return name; 17 } 18 public void setName(String name) { 19 this.name = name; 20 } 21} 22

java

1import java.io.Serializable; 2public class UserBean implements Serializable{ 3 private String id; 4 private String name; 5 private String pass; 6 private int dep; 7 8 9 public String getName() { 10 return name; 11 } 12 public void setName(String name) { 13 this.name = name; 14 } 15 16 17 public String getId() { 18 return id; 19 } 20 public void setId(String id) { 21 this.id = id; 22 } 23 24 25 public String getPass() { 26 return pass; 27 } 28 public void setPass(String pass) { 29 this.pass = pass; 30 } 31 32 33 public int getDep() { 34 return dep; 35 } 36 public void setDep(int dep) { 37 this.dep = dep; 38 } 39 40} 41

html

1<%@ page contentType="text/html;charset=UTF-8" language="java"%> 2<html> 3<head> 4<title>aaa</title> 5<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 6</head> 7<body> 8 <div align="center"> 9 <strong>部署:<%=session.getAttribute("dname") %></strong><br> 10 <strong>氏名:<%=session.getAttribute("uname") %></strong> 11 </div> 12</body> 13</html>

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

int型とvarchar型だから?と思い、CAST(user.dep AS CHAR)にしました。
結果、同じく部署のみNULLでした。

補足

値を取得後、depbeanのことしか書いていないのも変だとは思うのですが、どのように変更すればいいのかもわからない状態です。
初心者で、そもそも構成が間違っているかもしれませんが、よろしくお願いいたします。

TN8001😄を押しています

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

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

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

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

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

jimbe

2024/07/17 04:00 編集

テーブルの構造を提示されるのでしたら、マークダウンの "表" をご利用されればちゃんと矩形で表示出来て見易いと思います。 [対応しているMarkdownの記法を知りたい] https://teratail.com/help#about-markdown 質問は編集でき、リアルタイムにプレビューが表示されているはずですので、確認しながら弄ってみてください。 また、「該当のソースコード」でコードのマークダウン(```)のファイル名を書かれている個所は言語名(java や html 等)を書く所です。 例えば ```LoginUserServletConf (コード) ``` は LoginUserServletConf.java ```java (コード) ``` のように ``` の後は言語名とし、ファイル名は ``` の囲みの外に書くようにしてください。そうすることで、コード内の言語的キーワードに色が付くようになります。
退会済みユーザー

退会済みユーザー

2024/07/17 04:07

UserDaoの61行目で例外は出力されていませんか? コードを見ると 43行目、`SELECT dep.name FROM user ~~~`でnameだけ取得していて、 57行目、`dep.setName(rs2.getString("id"));`でidも参照しようとしているようです。 65行目で返されるのは55行目でコンストラクタが呼び出されただけのDepBeanになるような気がしました。 見当違いでしたらごめんなさい・・
jimbe

2024/07/17 04:09

>試したこと・調べたこと >上記の詳細・結果 >遷移はするが、NULLで返ってきます。 「試したこと・調べたこと」の「上記の詳細・結果」というのは、試したり調べたことで得た情報をコードに反映した結果どういう結果が出たかを書く個所です。 「遷移はするが、NULLで返ってきます。」は、試したり調べたり以前に現状起こっていることですよね? それなら >発生している問題・分からないこと >部署がNULLで返ってきます。 の「部署がNULLで返ってきます。」を「遷移はするが、部署がNULLで返ってきます。」とするほうが結果をより端的に説明すると思うのですが如何でしょうか。 逆に「補足」とされている「int型とvarchar型だから?と思い、CAST(user.dep AS CHAR)にした」は「試したこと・調べたこと」であり、そうしたらどうなったのかを「上記の詳細・結果」に書かれると良いと思います。
lovam-nm

2024/07/17 04:17

loginCheckでString sql1 = "select * from user where id=? && pass=?"; と記載していますが正しくユーザ情報を取得できていますか? 「&&」ではなく「AND」ではないでしょうか?
jimbe

2024/07/17 10:28 編集

エラーメッセージに「遷移はされる為、エラーメッセージはありません。」とありますが、遷移すればエラーが無いわけではありません。 実際コード内では例外が発生したら e.printStackTrace() をしているだけで処理は継続してしまいます。 問題が発生したらどのような動作をすると想定しているのでしょう。何もしなくてもエラーが表示されるものとお考えなら、それは間違いです。 例外が発生したら遷移先でエラーを表示するつもりなら、そのようにコードを組む必要があり、プログラムでシステムを作るということは正常な動作だけでなく異常が起きた場合の動作も作ることです。
kyakya

2024/07/17 14:47

jimbe様 コメントありがとうございます。 質問を修正したのでご確認よろしくお願いいたします。 遷移すればエラーが無いわけではないとの事。とても勉強になりました。ありがとうございます。 yametai様 コメントありがとうございます。 例外出力はされませんでした。 65行目で返されるのは55行目でコンストラクタが呼び出されただけのDepBeanになるような気がしたとの事ですが、私も初心者ながらそのような気がしております。ですが、修正方法も見いだせない状態でございます。もう一度、この箇所に絞って調べていきたいと思います。ありがとうございます。 lovam-nm様 コメントありがとうございます。 ユーザー情報は取得できておりました。&&をANDに変更してもユーザー情報は取得できました。 ご指摘頂きありがとうございました。
jimbe

2024/07/17 17:55

編集ありがとうございます。 java のコードは見易くなったと思います。 "表" ですが、2行目に "|:--|:--(中略)|" といった行を入れる必要があります。例えば user テーブルの所は(その前の "実現したいこと" に "|" が入っちゃってるのでそれから直すとして) ### 実現したいこと mysqlにて、userテーブル | field | type | null | key | Default | Extra | |:--|:--|:--|:--|:--|:--| | id | varchar(5) | NO | | NULL | | | name | varchar(20)| YES | | NULL | | | pass | varchar(20)| YES | | NULL | | | dep | int | YES | | NULL | | とすると、綺麗な表が出来ると思います。 また、コードの最後のは java でなく html ですね。ファイル名が無くなってしまうと何のファイルか分からなくなってしまいますので、コードのマークダウンの直前に普通のテキスト行としてファイル名は書くようにしてください。
guest

回答1

0

ベストアンサー

とりあえず、

UserDAO.java (クラス名消えちゃってますけど) の 43 行目の SELECT 文には dep.id を付け足すべきでしょう。
before:

SELECT dep.name FROM ~

after:

SELECT dep.id, dep.name FROM ~

そして、 56 ~ 58 行目の取得する部分で name と id が逆です。
before:

//値の格納 dep.setName(rs2.getString("id")); dep.setId(rs2.getString("name"));

after:

//値の格納 dep.setId(rs2.getString("id")); dep.setName(rs2.getString("name"));

で、 user → dep は n:1 なのですから、 user だけを取り出すのと user の情報を使って dep を取り出す二つのメソッドにするより、 UserBean にオプション的に dep.name を持たせられるよにして loginCheck メソッドを getWithDep とか名前を変えて loginCheck2 みたいに dep テーブルと join して名前を入れちゃうほうが簡単じゃないですかね。(そうすれば loginCheck2 メソッドも DepBean クラスも不要ですし。ついでに SQLException は throws にして使う側で エラー表示に使用するとか…。)

UserDAO.java (loginCheck メソッドの修正案)

java

1 public UserBean getWithDep(String uid, String upass) throws SQLException { 2 String sql = "SELECT u.name, id, pass, dep, d.name AS dep_name" + 3 " FROM user AS u INNER JOIN dep AS d ON u.dep = d.id" + 4 " WHERE id=? AND pass=?"; 5 try { 6 connect(); 7 PreparedStatement ps = getConnection().prepareStatement(sql); 8 ps.setString(1, uid); 9 ps.setString(2, upass); 10 ResultSet rs = ps.executeQuery(); 11 if(rs.next()) { 12 UserBean user = new UserBean(); 13 user.setName(rs.getString("name")); 14 user.setId(rs.getString("id")); 15 user.setPass(rs.getString("pass")); 16 user.setDep(rs.getInt("dep")); 17 user.setDepName(rs.getString("dep_name")); 18 return user; 19 } 20 } finally { 21 disconnect(); 22 } 23 return null; 24 }

UserBean.java (追加部分)

java

1public class UserBean implements Serializable { 2 : 3 private String depName; 4 5 : 6 public String getDepName() { 7 return depName; 8 } 9 public void setDepName(String name) { 10 this.depName = name; 11 } 12}

使う側

java

1 : 2 UserDao userDao = new UserDao(); 3 try { 4 UserBean user = userDao.getWithDep(uid, upass); 5 if(user != null) { 6 session.setAttribute("uname", user.getName()); 7 session.setAttribute("dname", user.getDepName()); 8 : 9 } catch(SQLException e) { 10 //例えば 11 e.printStackTrace(); //例外の詳細はどこかに残るようにしておいて 12 req.setAttribute("errMsg", "※処理に異常が発生しました。"); //利用者には問題が発生したことを知らせる? 13 forward = "/web/login.jsp"; 14 } 15 :

投稿2024/07/17 18:56

編集2024/07/18 04:17
jimbe

総合スコア13104

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

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

kyakya

2024/07/18 14:47

jimbe様 ご丁寧に教えて頂き本当にありがとうございます。”user → dep は n:1”の意味がわからず、n:1の事が学べ、”SQLException は throws にして使う側で エラー表示に使用”などのテクニックやエラーメッセージの概念など、今回の質問で沢山の学びができ感謝の気持ちでいっぱいです。 教えて頂いたコードを学習後、訂正実行したのですが、エラーがでてしまいました。ですが、後もう一歩な気がますので、自身で修正してみたいと思います。また、解決・未解決にかかわらず、その後の報告は改めてさせて頂きます。 本当にありがとうございます。
kyakya

2024/07/26 01:52

先日はありがとうございました。 ログインをクリックすると"※処理に異常が発生しました。"と表示され自力で解決できず、もしおわかりでしたらご教授いただけないでしょうか?以下詳細になります。 (UserDao.java) ```java public class UserDao extends DBAccess{ public UserBean getWithDep(String uid, String upass) throws SQLException { String sql = "SELECT u.name, id, pass, dep, d.name AS dep_name" + " FROM user AS u INNER JOIN dep AS d ON u.dep = d.id" + " WHERE id=? AND pass=?"; try { connect(); PreparedStatement ps = getConnection().prepareStatement(sql); ps.setString(1, uid); ps.setString(2, upass); ResultSet rs = ps.executeQuery(); if(rs.next()) { UserBean user = new UserBean(); user.setName(rs.getString("name")); user.setId(rs.getString("id")); user.setPass(rs.getString("pass")); user.setDep(rs.getInt("dep")); user.setDepName(rs.getString("dep_name")); return user; } } finally { disconnect(); } return null; } } ``` (UserBean.java) ```java public class UserBean implements Serializable{ : private String depName; public UserBean () { } : public String getDepName() { return depName; } public void setDepName(String name) { this.depName = name; } } ``` (使う側) ```java //ログインがおされた if(req.getParameter("submit").equals("ログイン")){ String uid=req.getParameter("uid"); String upass=req.getParameter("upass"); //DAOをインスタンス化 UserDao userDao = new UserDao(); try { //DAOを使用してID・パスワードをチェックする UserBean user = userDao.getWithDep(uid, upass); //もし該当者がいれば if(user != null) { session.setAttribute("uname", user.getName()); session.setAttribute("dname", user.getDepName()); forward="/web/menu.jsp"; }else{ req.setAttribute("errMsg","※ログインID・パスワードが違います"); forward="/web/login.jsp"; } } catch(SQLException e) { e.printStackTrace(); //例外の詳細はどこかに残るようにしておいて req.setAttribute("errMsg", "※処理に異常が発生しました。"); //利用者には問題が発生したことを知らせる。 forward = "/web/login.jsp"; : ``` と変更いたしました。 自分なりに調べたところ、データベース接続の確認、SQLクエリの確認、大文字と小文字の区別の確認との事でした。(確認しましたが、全て問題無いと思いました。) 又”dep テーブルに depName カラムが存在することも確認”とchatGPTで分かったので、depテーブルのnameをdepNameに変更して実行しましたが、同じくログインをクリックすると、"※処理に異常が発生しました。" 教科書を読み直したりしたのですが、その他、どのように修正をすればいいのか分からず苦戦しております。 自力で解決出来ず申し訳ございませんでした。 どうぞ宜しくお願い致します。
jimbe

2024/07/26 02:19

問題が発生した時に真っ先に行うべきは『何が起きているのかの確認』です。闇雲に検索するとか何かに聞くとか解決策を探すことではありません。 コードのコメントに書いています通り、『※処理に異常が発生しました。』はシステムに関与できない利用者に向けての状況の説明であり、システムに関与できるプログラマが見るべき詳細情報は 『例外の詳細はどこかに残るようにしておいて』とコメントを付けた e.printStackTrace(); による出力です。 printStackTrace は『標準出力』に出されますので、実行しているシステムにおいて標準出力が何処に保存されるのかを調べて状況の詳細を得てください。 もし標準出力が保存されないようなシステムでしたら、逆に何処に出力すれば保存されるのかを調べて問題発生時はそこに出力するようにコードを直した上で再度実行して、詳細を得てください。 全てはそれからです。
kyakya

2024/07/31 01:31

回答ありがとうございます。 問題が解決しました!! "『例外の詳細はどこかに残るようにしておいて』とコメントを付けたe.printStackTrace();による出力" "標準出力が保存されないようなシステムでしたら、逆に何処に出力すれば保存されるのかを調べて問題発生時はそこに出力するようにコードを直した上で再度実行" また勉強させていただきました。 私なりにコードを追加し、問題解決いたしました。 始めて質問をさせていただき、考え方まで学ぶ事ができ、jimbe様にご回答頂き嬉しく思います。 ありがとうございました。 ベストアンサーに選ばせていただきました。
jimbe

2024/07/31 19:25 編集

terastail でプログラミングに慣れていない人の質問を見ると大抵の場合原因よりも先に解決方法を探しています。(逆に言うと原因を探していない/調べようとしていない風な質問は大抵プログラミングに慣れていない人です。) プログラムは100%"作られたモノ"であり、因果関係によって現象が発生します。従って原因を直さなければ結果は変わりません。 また、(私は行っていないので想像ですが)学校等でプログラミングを教える場合、"作り方"は教えても"問題が発生した場合にどうするか"は教えていないようです。(そもそも"問題が発生する"事自体を想定しているのか怪しいくらいですね。) 昔(c 言語だけでシステム全部を作っていた頃?)は「プログラムの 7~80% は問題に対応するためのコード」と言われたくらい、正常な動作の為の部分よりも労力が払われた処理です。 ちゃんとシステムが動作していれば動かないような部分だったりもしますので作成する段階ではヤル気が出難いのは確かですが^^; 「想定外」のことで長時間システムが止まって世間を騒がせるようなニュースが実はこのような処理が足りなかったこと(=想定して処理を入れていなければならなかった)を表していると考えれば、重要性は分かると思います。(入れていても尚複雑過ぎて時間が掛かってしまう事もあるでしょうが、なら入れてなかったら尚更…ってことです。) お疲れさまでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.39%

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

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

質問する

関連した質問