【Spring MVC】Spring JDBCを使ったDBアクセス(NamedParameterJdbcTemplateの使い方)

概要

データアクセスフレームワークであるSpring JDBCを使用する方法についてまとめた。
当記事では、NamedParameterJdbcTemplateの使い方について紹介する。

 

前提

以下の記事の続きとなる。

JdbcTemplateを使用するための準備

概要 データアクセスフレームワークであるSpring JDBCを使用して、H2DBにアクセスする方法についてまとめた。 当記事ではSpring JDBCの特徴と、H2DBにアクセスするための準備方法について紹介する。  […]

【Spring MVC】Spring JDBCを使ったDBアクセス(準備)
DAOの作成方法

概要 データアクセスフレームワークであるSpring JDBCを使用する方法についてまとめた。 当記事ではDAOの作成と、DBアクセスの動確を行う方法について紹介する。 ※尚、DAOパターンとは何かについての説明は割愛する &n[…]

【Spring MVC】Spring JDBCを使ったDBアクセス(DAOの作成と動確方法)

 

特徴

基本的にJdbcTemplateとメソッドの使い方は同じ
違いはSQL文内で使用するパラメータの指定方法が異なること。

JdbcTemplateはSQL文内のパラメータ用プレースホルダに「?」を指定するが、NamedParameterJdbcTemplateは「:変数名」を指定する
また、JdbcTemplateではバインドさせる変数はnew Object配列に格納していたが、NamedParameterJdbcTemplateは様々なパターンでバインドさせるパラメータを指定できる。

 

使用例

様々なパラメータオブジェクトを使用して、NamedParameterJdbcTemplateを実装する方法について紹介する。

Map

Mapを使用してパラメータを設定する。
以下はIDを指定して1件のレコードを取得する例。

インターフェース

StudentDao.java


/** 生徒情報を取得 */
Student findStudentById(int id);

 

実装

JdbcStudentDao.java


public Student findStudentById(int id) {
	// SQL文
	var sql = "SELECT id, grade, name, class_name, memo FROM student WHERE id = :id";
	// パラメータ作成
	Map<String, Object> propertyMap = new HashMap<>();
	propertyMap.put("id", id);
	// SQL実行
	return namedParameterJdbcTemplate.queryForObject(sql, propertyMap, studentRowMapper);
}

 

// SQL文
var sql = “SELECT id, grade, name, class_name, memo FROM student WHERE id = :id“;

SQL文のプレースホルダに「:id」を指定している。
Mapのキーに「id」を設定することで、バインドできる

 

// SQL実行
return namedParameterJdbcTemplate.queryForObject(sql, propertyMap, studentRowMapper);

作成したMapをメソッドに渡すことで、内部でパラメータがSQL文にバインドされる。
尚、studentRowMapperについては以下で解説している。

 

RowMapperの使い方

概要 データアクセスフレームワークであるSpring JDBCを使用する方法についてまとめた。 当記事では、JdbcTemplateのSELECT処理であるqueryForObjectメソッドの使い方について紹介する。  […]

【Spring MVC】Spring JDBCを使ったDBアクセス(queryForObjectの使い方)

 

使用結果

FooMain.java


var res = studentDao.findStudentById(3);
System.out.println(res);

// ------------------------
// コンソール
// ------------------------
// Student(id=3, grade=3, name=鈴木一郎, className=3-C, memo=芸術に秀でる, tests=null)

 

MapSqlParameterSource

MapSqlParameterSourceを使用してパラメータを設定する。
上記は異なるデータ型のパラメータを安全に扱うことができる。(例えば、文字列、数値、日付など)

以下は1件の生徒情報をINSERTする例。

インターフェース

StudentDao.java


/** 生徒情報の作成 */
int createStudent(Student student);

 

実装

JdbcStudentDao.java


@Override
public int createStudent(Student student) {
	// SQL文
	var sql = "INSERT INTO student (grade, name, class_name, memo) VALUES (:grade, :name, :className, :memo)";
	// パラメータ作成
	var property = new MapSqlParameterSource()
			.addValue("grade", student.getGrade())
			.addValue("name", student.getName())
			.addValue("className", student.getClassName())
			.addValue("memo", student.getMemo());
	// SQL実行
	return namedParameterJdbcTemplate.update(sql, property);
}

 

var property = new MapSqlParameterSource()
.addValue(“grade”, student.getGrade())
.addValue(“name”, student.getName())
.addValue(“className”, student.getClassName())
.addValue(“memo”, student.getMemo());

MapSqlParameterSourceもMapと同じように、SQL文にバインドさせたいキーを指定して作成する。

Mapと異なるのは、メソッドチェーンを利用してパラメータを作成できる点
※インスタンスを作成して、property.addValue(xxx, yyy)と個別に設定することも可能

 

使用結果

FooMain.java


var student = new Student();
student.setGrade(5);
student.setName("田中太郎");
student.setClassName("5-D");
student.setMemo("良好な成績");
int res = studentDao.createStudent(student);
System.out.println("新規作成結果:" + res);

// ------------------------
// コンソール
// ------------------------
// 新規作成結果:1

 

BeanPropertySqlParameterSource

BeanPropertySqlParameterSourceを使用してパラメータを設定する。
上記はJavaBeanのフィールド名を、自動でSQLのパラメータにバインドできる

以下は生徒情報とテスト情報を作成する例。
※トランザクションは考慮外

インターフェース

StudentDao.java


/** 生徒情報を作成して生徒ID取得 */
int insertStudentAndGetId(Student student);

/** テスト情報の作成 */
int insertTest(TestPoint test);

 

実装

JdbcStudentDao.java


@Override
public int insertStudentAndGetId(Student student) {
	// SQL文
	var sql = "INSERT INTO student (grade, name, class_name, memo) VALUES (:grade, :name, :className, :memo)";
	// パラメータ作成
	var beanProperty = new BeanPropertySqlParameterSource(student);
	// SQL実行
	KeyHolder keyHolder = new GeneratedKeyHolder();
	namedParameterJdbcTemplate.update(sql, beanProperty, keyHolder, new String[] { "id" });

	// 生徒IDを取得
	return keyHolder.getKey().intValue();
}

@Override
public int insertTest(TestPoint test) {
	// SQL文
	var sql = "INSERT INTO test_point (student_id, japanese, mathematics, evaluation, test_date) VALUES (:studentId, :japanese, :mathematics, :evaluation, :testDate)";
	// パラメータ作成
	var beanProperty = new BeanPropertySqlParameterSource(test);
	// SQL実行
	return namedParameterJdbcTemplate.update(sql, beanProperty);
}

 

// パラメータ作成
var beanProperty = new BeanPropertySqlParameterSource(student);

BeanPropertySqlParameterSourceのコンストラクタ引数にJavaBeanを渡せば、フィールド名をキーとしたバインド情報を自動で作成できる

 

// SQL実行
KeyHolder keyHolder = new GeneratedKeyHolder();
namedParameterJdbcTemplate.update(sql, beanProperty, keyHolder, new String[] { “id” });

INSERTにより自動生成された主キーをKeyHolderオブジェクトに保持させる処理。
以下で解説している。

 

KeyHolderの使い方

概要 データアクセスフレームワークであるSpring JDBCを使用する方法についてまとめた。 当記事では、JdbcTemplateの更新処理であるupdateメソッドの使い方について紹介する。   前提 以下の記事[…]

【Spring MVC】Spring JDBCを使ったDBアクセス(upudateの使い方)

 

使用結果

FooMain.java


// 生徒情報作成
var student = new Student();
student.setGrade(6);
student.setName("鈴木次郎");
student.setClassName("6-D");
student.setMemo("良好な成績");
int studentId = studentDao.insertStudentAndGetId(student);

// テスト情報作成
var test = new TestPoint();
test.setStudentId(studentId);
test.setJapanese(90);
test.setMathematics(80);
test.setEvaluation("優秀");
test.setTestDate(new Date());
studentDao.insertTest(test);

// 全生徒情報を表示
List<Student> studentList = studentDao.findAllStudens();
studentList.forEach(s -> System.out.println(s));

// ------------------------
// コンソール
// ------------------------
// Student(id=1, grade=1, name=山田太郎, className=1-A, memo=良好な成績, tests=[TestPoint(id=1, japanese=80, mathematics=70, evaluation=良好, testDate=2023-05-22, studentId=1), TestPoint(id=4, japanese=85, mathematics=90, evaluation=非常に良い, testDate=2023-09-30, studentId=1)])
// Student(id=2, grade=2, name=佐藤花子, className=2-B, memo=スポーツ万能, tests=[TestPoint(id=2, japanese=90, mathematics=65, evaluation=優秀, testDate=2023-05-22, studentId=2), TestPoint(id=5, japanese=60, mathematics=80, evaluation=普通, testDate=2023-09-30, studentId=2)])
// Student(id=3, grade=3, name=鈴木一郎, className=3-C, memo=芸術に秀でる, tests=[TestPoint(id=3, japanese=75, mathematics=85, evaluation=可, testDate=2023-05-22, studentId=3), TestPoint(id=6, japanese=85, mathematics=90, evaluation=非常に良い, testDate=2023-09-30, studentId=3)])
// Student(id=4, grade=6, name=鈴木次郎, className=6-D, memo=良好な成績, tests=[TestPoint(id=7, japanese=90, mathematics=80, evaluation=優秀, testDate=2024-02-28, studentId=4)])

 

 

 

スポンサーリンク