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

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

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

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

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

4421閲覧

jdbcTemplateのqueryForObjectの第二引数の指定がわからない

ryuxx

総合スコア18

Java

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

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

1グッド

1クリップ

投稿2020/09/02 14:25

前提・実現したいこと

queryForObjectの第二引数のRowMapper<T>の指定方法がわからない。
Spring BootでログインのDBのデータの件数を取得する処理でエラーが発生。

実現したいことは、現在出ているエラーを解消することです。
いろいろなサイトを参考に作成しているが、今まで携ってきた案件が下記のようなソースコードだったためうろ覚え状態でコーディングしています。
qurtyForObjectの引数が3つあった気がしますが、よくわかっていません、、、

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

The method queryForObject(String, RowMapper<T>) in the type JdbcTemplate is not applicable for the arguments (String, MapSqlParameterSource)Java(67108979)

該当のソースコード

Java

1@Repository 2public class SampleRepositoryImpl implements SampleRepository { 3 4 @Autowired 5 JdbcTemplate db; 6 7 @Override 8 public Integer login(String userName) { 9 StringBuilder sb = new StringBuilder(); 10 MapSqlParameterSource param = new MapSqlParameterSource(); 11 sb.append(" SELECT "); 12 sb.append(" user_name "); 13 sb.append(" FROM "); 14 sb.append(" users "); 15 sb.append(" WHERE "); 16 sb.append(" user_name = :userName "); 17 param.addValue("userName", userName); 18 return db.queryForObject(sb.toString(), param); 19 } 20}

試したこと

1.return db.queryForObject(sb.toString(), param);
2.return db.queryForObject(sb.toString(), param, Integer.class);
3.return db.queryForObject(sb.toString(), Integer.class);

3の場合のエラー

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [ SELECT user_name FROM users WHERE user_name = :userName ]; nested exception is org.postgresql.util.PSQLException: ERROR: ":"またはその近辺で構文エラー org.postgresql.util.PSQLException: ERROR: ":"またはその近辺で構文エラー

補足情報(FW/ツールのバージョンなど)

JAVA 8
Spring Boot 2.3.3

A-pZ👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

JdbcTemplateのqueryForObjectを使う場合のパラメータ指定ですが、利用するJdbcTemplateで、いわゆるPreparedStatement(?で指定する方法)のSQLを使うか、変数を指定するプレースホルダにする NamedParameterJdbcTemplate を使う方法(id = :id で指定する方法)があります。

例えば、以下で定義されるテーブルで

sql

1CREATE TABLE account (id INT, name VARCHAR(256))

このテーブルに対して、id を指定して検索するSQLを、NamedParameterJdbcTemplate ならば

sql

1SELECT id, name FROM account WHERE id = :id

素のJdbcTemplateは、

sql

1SELECT id, name FROM account WHERE id=?

であるときに、このレコードを受けるクラスが以下で表現した場合、

java

1public class Account { 2 private Integer id; 3 private String name; 4// get|setメソッドならびにデフォルトコンストラクタが必須 5}

これを実行する処理は、お使いのJdbcTemplateによりパラメータの格納方法が異なります。
NamedQuery~の方がパラメータの格納がしやすく(※)、視認性もとても高いので、ご希望されているNamedQuery~が良いですね!

※SqlParameterSource param = new MapSqlParameterSource().addValue("id", id); や Beanを丸ごと定義できる BeanPropertySqlParameterSource(..) が使えます。

NamedParameterJdbcTemplate :

java

1import org.springframework.jdbc.core.BeanPropertyRowMapper; 2import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; 3import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 4import org.springframework.jdbc.core.namedparam.SqlParameterSource; 5import org.springframework.stereotype.Repository; 6 7import lombok.RequiredArgsConstructor; 8 9@Repository 10@RequiredArgsConstructor 11public class NamedQueryAccountRepository { 12 private final NamedParameterJdbcTemplate template; 13 14 public Account findById(Integer id) { 15 SqlParameterSource param = new MapSqlParameterSource().addValue("id", id); 16 return template.queryForObject("SELECT id, name FROM account WHERE id = :id", param, new BeanPropertyRowMapper<Account>(Account.class)); 17 }

素のJdbcTemplate :

java

1import org.springframework.jdbc.core.BeanPropertyRowMapper; 2import org.springframework.jdbc.core.JdbcTemplate; 3import org.springframework.stereotype.Repository; 4 5import lombok.RequiredArgsConstructor; 6 7@Repository 8@RequiredArgsConstructor 9public class AccountRepository { 10 private final JdbcTemplate jdbcTemplate; 11 public Account findById(int id) { 12 return jdbcTemplate.queryForObject("SELECT id, name FROM account WHERE id=?" 13 , new Object[]{id} 14 , new BeanPropertyRowMapper<Account>(Account.class)); 15 } 16}

投稿2020/09/05 03:28

編集2020/09/06 04:15
A-pZ

総合スコア12011

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

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

ryuxx

2020/09/05 12:00

回答ありがとうございました。 いろんなサイトを参考にしていますが、「id=:id」の実装方法があまり乗っていなく苦戦しているため上記での実装方法を教えていただけますでしょうか。
A-pZ

2020/09/06 04:15

@ryuxx さん NamedQueryの方を回答に追記しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問