ホーム画面からユーザー一覧画面に遷移し、ユーザーの詳細を表示するアプリケーションを作成して、Spring JDBCの使い方について学びます⭐️
今回はNamedParameterJdbcTemplateでの基本的なCRUD操作を学びます^^
構成は前回/これまでの記事を参考にしてください
⭐️前回の記事
【Java・SpringBoot】RowCallbackHandlerでコールバック / CSV出力機能(SpringBootアプリケーション実践編18)
#NamedParameterJdbcTemplate
-
JdbcTemplateでは、
PreparedStatment
を使う際に、メソッドの引数の順番に注意を払う必要があったが、NamedParameterJdbcTemplateでは不要。
#リポジトリークラスを追加
- リポジトリークラスでは、UserDaoインターフェースをimplements
###NamedJdbcTemplateの使い方
- NamedJdbcTemplateでは、PreparedStatementのSQL文に?ではなく
:<キー名>
を使う
*String sql = "INSERT INTO m_user(user_id," + " password," + " role)" + " VALUES(:userId," + " :password," + " :role)";
###SQL文に入れるパラメーターを設定
- SqlParameterSourceクラスをnewして、addValue()メソッドにキーと値をセット
- addValue()の第一引数にキー名、第二引数に値をセット
SqlParameterSource params = new MapSqlParameterSource().addValue("userId", user.getUserId())
- NamedJdbcTemplateにSqlParameterSourceを渡せばOK
return jdbc.update(sql, params);
NamedParameterJdbcTemplate.java
//略(全文は下記参考)
@Repository("UserDaoNamedJdbcImpl")
public class UserDaoNamedJdbcImpl implements UserDao {
@Autowired
private NamedParameterJdbcTemplate jdbc;
//Userテーブルの件数を取得.
@Override
public int count() {
//SQL分
String sql = "SELECT COUNT(*) FROM m_user";
//パラメーター生成
SqlParameterSource params = new MapSqlParameterSource();
//全件取得してカウント
return jdbc.queryForObject(sql, params, Integer.class);
}
//Userテーブルにデータを1件insert.
@Override
public int insertOne(User user) {
//SQL文
String sql = "INSERT INTO m_user(user_id,"
+ " password,"
+ " user_name,"
+ " birthday,"
+ " age,"
+ " marriage,"
+ " role)"
+ " VALUES(:userId,"
+ " :password,"
+ " :userName,"
+ " :birthday,"
+ " :age,"
+ " :marriage,"
+ " :role)";
//パラメーター
SqlParameterSource params = new MapSqlParameterSource()
.addValue("userId", user.getUserId())
.addValue("password", user.getPassword())
.addValue("userName", user.getUserName())
.addValue("birthday", user.getBirthday())
.addValue("age", user.getAge())
.addValue("marriage", user.isMarriage())
.addValue("role", user.getRole());
//SQL実行
return jdbc.update(sql, params);
}
//Userテーブルの全データを取得.
@Override
public List<User> selectMany() {
//SQL文
String sql = "SELECT * FROM m_user";
//パラメーター
SqlParameterSource params = new MapSqlParameterSource();
//SQL実行
List<Map<String, Object>> getList = jdbc.queryForList(sql, params);
//結果返却用のList
List<User> userList = new ArrayList<>();
//取得データ分loop
for(Map<String, Object> map: getList) {
//Userインスタンスの生成
User user = new User();
//Userインスタンスに取得したデータをセットする
user.setUserId((String)map.get("user_id")); //ユーザーID
user.setPassword((String)map.get("password")); //パスワード
user.setUserName((String)map.get("user_name")); //ユーザー名
user.setBirthday((Date)map.get("birthday")); //誕生日
user.setAge((Integer)map.get("age")); //年齢
user.setMarriage((Boolean)map.get("marriage")); //結婚ステータス
user.setRole((String)map.get("role")); //ロール
//Listに追加
userList.add(user);
}
return userList;
}
//Userテーブルを1件更新.
@Override
public int updateOne(User user) {
//SQL文
String sql = "UPDATE M_USER"
+ " SET"
+ " password = :password,"
+ " user_name = :userName,"
+ " birthday = :birthday,"
+ " age = :age,"
+ " marriage = :marriage"
+ " WHERE user_id = :userId";
//パラメーター
SqlParameterSource params = new MapSqlParameterSource()
.addValue("userId", user.getUserId())
.addValue("password", user.getPassword())
.addValue("userName", user.getUserName())
.addValue("birthday", user.getBirthday())
.addValue("age", user.getAge())
.addValue("marriage", user.isMarriage());
//SQL実行
return jdbc.update(sql, params);
}
//略(全文は下記参考)
}
#サービスクラス修正
- UserDaoNamedJdbcImplを使用する
UserService.java
//略(全文は下記参考)
@ServiceUserService
public class UserService {
@Autowired
@Qualifier("UserDaoNamedJdbcImpl")
UserDao dao;
//略
}
#SpringBootを起動してホーム画面確認!
- http://localhost:8080/home
- ユーザー一覧に移ると、コンソールの表示がUserDaoNamedJdbcImplに変わっています
- NamedParameterJdbcTemplateを使ったクラスが使われていることがわかりました^^
- (注)NamedParameterJdbcTemplateではRowMapperは使えるが、BeanPropertyRowMapperは使えません
//コンソール
メソッド開始: List com.example.demo.login.domain.repository.jdbc.UserDaoNamedJdbcImpl.selectMany()
メソッド終了: List com.example.demo.login.domain.repository.jdbc.UserDaoNamedJdbcImpl.selectMany()
#(参考)コード全文
NamedParameterJdbcTemplate.java
package com.example.demo.login.domain.repository.jdbc;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import com.example.demo.login.domain.model.User;
import com.example.demo.login.domain.repository.UserDao;
@Repository("UserDaoNamedJdbcImpl")
public class UserDaoNamedJdbcImpl implements UserDao {
@Autowired
private NamedParameterJdbcTemplate jdbc;
//Userテーブルの件数を取得.
@Override
public int count() {
//SQL分
String sql = "SELECT COUNT(*) FROM m_user";
//パラメーター生成
SqlParameterSource params = new MapSqlParameterSource();
//全件取得してカウント
return jdbc.queryForObject(sql, params, Integer.class);
}
//Userテーブルにデータを1件insert.
@Override
public int insertOne(User user) {
//SQL文
String sql = "INSERT INTO m_user(user_id,"
+ " password,"
+ " user_name,"
+ " birthday,"
+ " age,"
+ " marriage,"
+ " role)"
+ " VALUES(:userId,"
+ " :password,"
+ " :userName,"
+ " :birthday,"
+ " :age,"
+ " :marriage,"
+ " :role)";
//パラメーター
SqlParameterSource params = new MapSqlParameterSource()
.addValue("userId", user.getUserId())
.addValue("password", user.getPassword())
.addValue("userName", user.getUserName())
.addValue("birthday", user.getBirthday())
.addValue("age", user.getAge())
.addValue("marriage", user.isMarriage())
.addValue("role", user.getRole());
//SQL実行
return jdbc.update(sql, params);
}
//Userテーブルのデータを1件取得
@Override
public User selectOne(String userId) {
//SQL文
String sql = "SELECT * FROM m_user WHERE user_id = :userId";
//パラメーター
SqlParameterSource params = new MapSqlParameterSource()
.addValue("userId", userId);
//SQL実行
Map<String, Object> map = jdbc.queryForMap(sql, params);
//結果返却用のインスタンスを生成
User user = new User();
//取得データをインスタンスにセットしていく
user.setUserId((String)map.get("user_id")); //ユーザーID
user.setPassword((String)map.get("password")); //パスワード
user.setUserName((String)map.get("user_name")); //ユーザー名
user.setBirthday((Date)map.get("birthday")); //誕生日
user.setAge((Integer)map.get("age")); //年齢
user.setMarriage((Boolean)map.get("marriage")); //結婚ステータス
user.setRole((String)map.get("role")); //ロール
return user;
}
//Userテーブルの全データを取得.
@Override
public List<User> selectMany() {
//SQL文
String sql = "SELECT * FROM m_user";
//パラメーター
SqlParameterSource params = new MapSqlParameterSource();
//SQL実行
List<Map<String, Object>> getList = jdbc.queryForList(sql, params);
//結果返却用のList
List<User> userList = new ArrayList<>();
//取得データ分loop
for(Map<String, Object> map: getList) {
//Userインスタンスの生成
User user = new User();
//Userインスタンスに取得したデータをセットする
user.setUserId((String)map.get("user_id")); //ユーザーID
user.setPassword((String)map.get("password")); //パスワード
user.setUserName((String)map.get("user_name")); //ユーザー名
user.setBirthday((Date)map.get("birthday")); //誕生日
user.setAge((Integer)map.get("age")); //年齢
user.setMarriage((Boolean)map.get("marriage")); //結婚ステータス
user.setRole((String)map.get("role")); //ロール
//Listに追加
userList.add(user);
}
return userList;
}
//Userテーブルを1件更新.
@Override
public int updateOne(User user) {
//SQL文
String sql = "UPDATE M_USER"
+ " SET"
+ " password = :password,"
+ " user_name = :userName,"
+ " birthday = :birthday,"
+ " age = :age,"
+ " marriage = :marriage"
+ " WHERE user_id = :userId";
//パラメーター
SqlParameterSource params = new MapSqlParameterSource()
.addValue("userId", user.getUserId())
.addValue("password", user.getPassword())
.addValue("userName", user.getUserName())
.addValue("birthday", user.getBirthday())
.addValue("age", user.getAge())
.addValue("marriage", user.isMarriage());
//SQL実行
return jdbc.update(sql, params);
}
//Userテーブルを1件削除.
@Override
public int deleteOne(String userId) {
//SQL文
String sql = "DELETE FROM m_user WHERE user_id = :userId";
//パラメーター
SqlParameterSource params = new MapSqlParameterSource()
.addValue("userId", userId);
//SQL実行
int rowNumber = jdbc.update(sql, params);
return rowNumber;
}
//SQL取得結果をサーバーにCSVで保存する
@Override
public void userCsvOut() {
//M_USERテーブルのデータを全件取得するSQL
String sql = "SELECT * FROM m_user";
//ResultSetExtractorの生成
UserRowCallbackHandler handler = new UserRowCallbackHandler();
//クエリー実行&CSV出力
jdbc.query(sql, handler);
}
}
UserService.java
package com.example.demo.login.domain.service;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import com.example.demo.login.domain.model.User;
import com.example.demo.login.domain.repository.UserDao;
@Service
public class UserService {
@Autowired
@Qualifier("UserDaoNamedJdbcImpl")
UserDao dao;
/**
* insert用メソッド.
*/
public boolean insert(User user) {
// insert実行
int rowNumber = dao.insertOne(user);
// 判定用変数
boolean result = false;
if (rowNumber > 0) {
// insert成功
result = true;
}
return result;
}
/**
* カウント用メソッド.
*/
public int count() {
return dao.count();
}
/**
* 全件取得用メソッド.
*/
public List<User> selectMany() {
// 全件取得
return dao.selectMany();
}
/**
* 1件取得用メソッド.
*/
public User selectOne(String userId) {
// selectOne実行
return dao.selectOne(userId);
}
/**
* 1件更新用メソッド.
*/
public boolean updateOne(User user) {
// 判定用変数
boolean result = false;
// 1件更新
int rowNumber = dao.updateOne(user);
if (rowNumber > 0) {
// update成功
result = true;
}
return result;
}
/**
* 1件削除用メソッド.
*/
public boolean deleteOne(String userId) {
// 1件削除
int rowNumber = dao.deleteOne(userId);
// 判定用変数
boolean result = false;
if (rowNumber > 0) {
// delete成功
result = true;
}
return result;
}
// ユーザー一覧をCSV出力する.
public void userCsvOut() throws DataAccessException {
// CSV出力
dao.userCsvOut();
}
/**
* サーバーに保存されているファイルを取得して、byte配列に変換する.
*/
public byte[] getFile(String fileName) throws IOException {
// ファイルシステム(デフォルト)の取得
FileSystem fs = FileSystems.getDefault();
// ファイル取得
Path p = fs.getPath(fileName);
// ファイルをbyte配列に変換
byte[] bytes = Files.readAllBytes(p);
return bytes;
}
}