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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Spring MVC

Spring MVCとは、Javaを用いてWebアプリケーションを開発できるフレームワーク。アーキテクチャにMVCを採用しており、画面遷移と入出力パラメータの受け渡しの基本的な機能の他、ユーザーの送信したパラメータに対する入力チェックなどさまざまな機能を持ちます。

MySQL

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

JDBC

JDBC(Java DataBase Connectivity)は、Javaとリーレーショナルデータベースに接続させる基本的なAPIです。Java上でSQLステートメントを発行することで、データベースの種類に影響を受ないDB操作を可能とします。

Java

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

1回答

1080閲覧

Spring MVCで演算をした後にJDBCTemplateのメソッドupdateを使うとうまくいきません

退会済みユーザー

退会済みユーザー

総合スコア0

Spring MVC

Spring MVCとは、Javaを用いてWebアプリケーションを開発できるフレームワーク。アーキテクチャにMVCを採用しており、画面遷移と入出力パラメータの受け渡しの基本的な機能の他、ユーザーの送信したパラメータに対する入力チェックなどさまざまな機能を持ちます。

MySQL

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

JDBC

JDBC(Java DataBase Connectivity)は、Javaとリーレーショナルデータベースに接続させる基本的なAPIです。Java上でSQLステートメントを発行することで、データベースの種類に影響を受ないDB操作を可能とします。

Java

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2022/01/06 11:07

編集2022/01/07 01:46

Spring MVCを使い簡易的なバンクシステムで作っています。
'預かりメソッド'と'引き出しメソッド'を作成したのですが、うまくいきません。
例えば、4万円の残高があり、最初に1万円引き出すと残高は3万円になるのですが、その次に2万円引き出すと残高は2万円になります。なぜでしょうか?

UserController

1package com.banksystem.controller; 2 3import javax.servlet.http.HttpSession; 4 5import org.springframework.beans.factory.annotation.Autowired; 6import org.springframework.stereotype.Controller; 7import org.springframework.ui.Model; 8import org.springframework.web.bind.annotation.RequestMapping; 9import org.springframework.web.bind.annotation.RequestMethod; 10 11import com.banksystem.model.User; 12import com.banksystem.model.UserInput; 13import com.banksystem.service.BSService; 14 15@Controller 16public class UserController { 17 18 @Autowired 19 BSService service; 20 21 @Autowired 22 HttpSession session; 23 24 /* 25 ****************** 26 **Deposit Method** 27 ****************** 28 */ 29 @RequestMapping(value = "/deposit", method = RequestMethod.GET) 30 public String toDeposit(Model model) { 31 UserInput userInput = new UserInput(); 32 model.addAttribute("userInput", userInput); 33 return "deposit"; 34 } 35 @RequestMapping(value = "/deposit_p", method = RequestMethod.POST) 36 public String deposit(Model model, UserInput userInput) { 37 38 User user = new User(); 39 int inputNum; 40 Integer amount; 41 inputNum = userInput.getInputNum(); 42 user = (User) session.getAttribute("User"); 43 amount = user.getAmount(); 44 //初回利用時 45 if(amount == null) { 46 amount = 0; 47 } 48 amount = amount + inputNum; 49 Integer id = user.getId(); 50 int numRow = service.deposit(amount, id); 51 //failed 52 if(numRow > 1) { 53 session.invalidate(); 54 model.addAttribute("message", "エラーが発生しました。もう一度最初からやり直してください。"); 55 return "end"; 56 } 57 model.addAttribute("message", "預け入れが完了しました"); 58 return "topMain"; 59 } 60 61 /* 62 ******************* 63 **Withdraw Method** 64 ******************* 65 */ 66 @RequestMapping(value = "/withdraw", method = RequestMethod.GET) 67 public String toWithdraw(Model model) { 68 UserInput userInput = new UserInput(); 69 model.addAttribute("userInput", userInput); 70 return "withdraw"; 71 } 72 @RequestMapping(value = "withdraw_p", method = RequestMethod.POST) 73 public String withdraw(Model model, UserInput userInput) { 74 75 User user = new User(); 76 int inputNum; 77 Integer amount; 78 inputNum = userInput.getInputNum(); 79 user = (User) session.getAttribute("User"); 80 amount = user.getAmount(); 81 //初回利用時 82 if(amount == null) { 83 amount = 0; 84 } 85 //be negative 86 if(amount <= inputNum) { 87 model.addAttribute("message", "残高が不足しています"); 88 UserInput userInput1 = new UserInput(); 89 model.addAttribute("userInput", userInput1); 90 return "withdraw"; 91 } 92 amount = amount - inputNum; 93 Integer id = user.getId(); 94 int numRow = service.withdraw(amount, id); 95 //failed 96 if(numRow > 1) { 97 session.invalidate(); 98 model.addAttribute("message", "エラーが発生しました。もう一度最初からやり直してください。"); 99 return "end"; 100 } 101 model.addAttribute("message", "お引き出しが完了しました"); 102 return "topMain"; 103 } 104} 105

Dao.java

1package com.banksystem.dao; 2 3import org.springframework.dao.DataAccessException; 4import org.springframework.stereotype.Repository; 5 6import com.banksystem.model.Contact; 7import com.banksystem.model.User; 8 9@Repository 10public interface Dao { 11 //login method 12 public User login(String loginId, String loginPass) throws DataAccessException; 13 14 //register method 15 public int register(User user) throws DataAccessException; 16 17 //contact method 18 public int contact(Contact contact) throws DataAccessException; 19 20 //deposit method 21 public int deposit(int id, int sum) throws DataAccessException; 22 23 //withdraw method 24 public int withdraw(int id, int sum) throws DataAccessException; 25} 26

JdbcDao

1package com.banksystem.dao; 2 3import java.util.Map; 4 5import org.springframework.beans.factory.annotation.Autowired; 6import org.springframework.dao.DataAccessException; 7import org.springframework.jdbc.core.JdbcTemplate; 8import org.springframework.stereotype.Repository; 9 10import com.banksystem.model.Contact; 11import com.banksystem.model.User; 12 13@Repository 14public class JdbcDao implements Dao{ 15 16 @Autowired JdbcTemplate jdbc; 17 18 @Override 19 public User login(String loginId, String loginPass) throws DataAccessException { 20 User user = new User(); 21 try { 22 String sql = "SELECT * FROM users_info WHERE loginId = ? AND loginPass = ?"; 23 Map<String, Object> map = jdbc.queryForMap(sql, loginId, loginPass); 24 user.setId((Integer) map.get("id")); 25 user.setName((String) map.get("name")); 26 user.setPhone((String)map.get("phone")); 27 user.setEmail((String)map.get("email")); 28 user.setLoginId((String)map.get("loginId")); 29 user.setLoginPass((String)map.get("loginPass")); 30 user.setAmount((Integer)map.get("amount")); 31 }catch(Exception e) { 32 e.printStackTrace(); 33 } 34 return user; 35 } 36 37 @Override 38 public int register(User user) throws DataAccessException { 39 int rowNum = -1; 40 try { 41 String sql = "INSERT INTO users_info(name, phone, email, loginId, loginPass) VALUES(?, ?, ?, ?, ?)"; 42 rowNum = jdbc.update(sql, user.getName(), user.getPhone(), user.getEmail(), user.getLoginId(), user.getLoginPass()); 43 }catch(Exception e) { 44 e.printStackTrace(); 45 } 46 return rowNum; 47 } 48 49 @Override 50 public int contact(Contact contact) throws DataAccessException { 51 int rowNum = -1; 52 try { 53 String sql = "INSERT INTO contacts(email, message) VALUES(?, ?)"; 54 rowNum = jdbc.update(sql, contact.getEmail(), contact.getMessage()); 55 }catch(Exception e) { 56 e.printStackTrace(); 57 } 58 return rowNum; 59 } 60 61 @Override 62 public int deposit(int id, int sum) throws DataAccessException{ 63 int rowNum = -1; 64 try { 65 String sql = "UPDATE users_info SET amount=? WHERE id=?"; 66 rowNum = jdbc.update(sql, sum, id); 67 }catch(DataAccessException e) { 68 e.printStackTrace(); 69 } 70 return rowNum; 71 } 72 73 @Override 74 public int withdraw(int id, int sum) throws DataAccessException { 75 int rowNum = -1; 76 try { 77 String sql = "UPDATE users_info SET amount=? WHERE id=?"; 78 rowNum = jdbc.update(sql, sum, id); 79 }catch(DataAccessException e) { 80 e.printStackTrace(); 81 } 82 return rowNum; 83 } 84 85} 86

BSService

1package com.banksystem.service; 2 3import org.springframework.beans.factory.annotation.Autowired; 4import org.springframework.stereotype.Service; 5 6import com.banksystem.dao.Dao; 7import com.banksystem.model.Contact; 8import com.banksystem.model.User; 9 10@Service 11public class BSService { 12 13 @Autowired 14 Dao dao; 15 16 //login 17 public User login(String loginId, String loginPass) { 18 User user = dao.login(loginId, loginPass); 19 return user; 20 } 21 22 //register 23 public int register(User user) { 24 int rowNum = dao.register(user); 25 return rowNum; 26 } 27 28 //contact 29 public int contact(Contact contact) { 30 int rowNum = dao.contact(contact); 31 return rowNum; 32 } 33 34 //deposit 35 public int deposit(int id, int sum) { 36 int rowNum = dao.deposit(sum, id); 37 return rowNum; 38 } 39 40 //withdraw 41 public int withdraw(int id, int sum) { 42 int rowNum = dao.deposit(sum, id); 43 return rowNum; 44 } 45} 46

1回目のデバッグ(残高40000、引き出し10000)
イメージ説明

DataBase
id name phone email loginId loginPass amount
"6" "Test" "09012345678" "test@gmail.com" "test" "test" "30000"


2回目のデバッグ(残高30000、引き出し20000)(本来は10000になる)
イメージ説明

DataBase
id name phone email loginId loginPass amount
"6" "Test" "09012345678" "test@gmail.com" "test" "test" "20000"

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

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

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

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

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

xebme

2022/01/07 00:22

if(amount <= inputNum) { この条件は、引き出せる? 残高不足? どちらですか。
退会済みユーザー

退会済みユーザー

2022/01/07 01:18

残高不足です
xebme

2022/01/07 01:40

質問の文脈が分からなくなりました。 >残高は3万円になるのですが、その次に2万円引き出すと残高は変わらずに2万円になります。なぜでしょうか? 残高は3万円から2万円に変わったと読めるのですが。
退会済みユーザー

退会済みユーザー

2022/01/07 01:45

すみません。表記ミスです。"変わらずに"はいりません。
xebme

2022/01/08 00:56

2回目のデバッグの画像を見ると、user.amount.valueが40000となっています。これが残高として使われている可能性は? 40000 - 20000 = 20000 となります。
退会済みユーザー

退会済みユーザー

2022/01/08 01:00

はい。そうなんです。1回目の結果がコミットされてない様に思えるのですが"自動コミット"をONにしています。何故かJDBCTemplate.updateで数値を変更した場合、数値が正しく反映されません。解決方法がわかりません。
guest

回答1

0

ベストアンサー

検討違いのことを言っていたら申し訳ないのですが

引き出し用の
Controller.withdrawメソッド内部で引き落としの際にも
残高をDBから取得せずHttpSessionから取得しているのが原因ではないでしょうか?

java

1 2// controllerのwithdrawメソッド 3 user = (User) session.getAttribute("User"); 4 amount = user.getAmount(); // ここで一回目のデバック時/2回目のデバッグ時共に40000が取れている ※同じ情報を取ってしまっているのでは・・? DB見に行かないと駄目なような。 5 6 // 省略 7 8    // 上記のセッションから取得したユーザー情報のAmountから 9 // リクエストのAmountの値を減算した値をDBにUpdateで更新かけている 10 amount = amount - inputNum; 11     Integer id = user.getId(); 12 int numRow = service.withdraw(amount, id); 13

私の見解としては DB側のデータの更新自体は出来ていると考えていて、
Service以降は問題ないように見受けられます。 Controllerのバグの認識です。
※ 1回目でDB側の残高が40000 -> 30000に更新されていることから分かる

引き出しの際はセッションからユーザーの残高を受け取るのではなく、
DBにSelectで検索をかけて取得した残高から userInputに設定された残高を引いた値をDBに登録するべきではないのでしょうか?

おそらくセッションから1回目と2回目で同じ情報を取って減算している関係で
1回目: 40000 -10000で DBに30000が登録
2回目: 40000 -20000で DBに20000が登録(30000を上書きしてしまう)

となっているのだと思います。

投稿2022/01/08 16:50

編集2022/01/08 16:52
dev-fjk

総合スコア9

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

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

xebme

2022/01/09 00:50

お気づきのとおり、最も疑うべきはUser.amountですが、質問には手がかりがありません。質問者の立場なら、思い込みを捨てて、User.amountをどのように取得しているのかを調べるのが、初めになすべきことです。
dev-fjk

2022/01/09 11:13

ご返信ありがとうございます。 そうですね。上記の情報含め質問者様の方でもう少し調査いただけますと幸いですmm
退会済みユーザー

退会済みユーザー

2022/01/10 04:46

selectで持ってきた値を使ったところ無事機能しました。 セッションのamountで計算するのがまずかったようです。 みなさまご協力ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問