概要
データアクセスフレームワークであるSpring JDBCを使用する方法についてまとめた。
当記事では、NamedParameterJdbcTemplateの使い方について紹介する。
前提
以下の記事の続きとなる。
概要 データアクセスフレームワークであるSpring JDBCを使用して、H2DBにアクセスする方法についてまとめた。 当記事ではSpring JDBCの特徴と、H2DBにアクセスするための準備方法について紹介する。 […]
概要 データアクセスフレームワークであるSpring JDBCを使用する方法についてまとめた。 当記事ではDAOの作成と、DBアクセスの動確を行う方法について紹介する。 ※尚、DAOパターンとは何かについての説明は割愛する &n[…]
特徴
基本的に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);
}
var sql = “SELECT id, grade, name, class_name, memo FROM student WHERE id = :id“;
SQL文のプレースホルダに「:id」を指定している。
Mapのキーに「id」を設定することで、バインドできる。
return namedParameterJdbcTemplate.queryForObject(sql, propertyMap, studentRowMapper);
作成したMapをメソッドに渡すことで、内部でパラメータがSQL文にバインドされる。
尚、studentRowMapperについては以下で解説している。
概要 データアクセスフレームワークであるSpring JDBCを使用する方法についてまとめた。 当記事では、JdbcTemplateのSELECT処理である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);
}
.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を渡せば、フィールド名をキーとしたバインド情報を自動で作成できる。
KeyHolder keyHolder = new GeneratedKeyHolder();
namedParameterJdbcTemplate.update(sql, beanProperty, keyHolder, new String[] { “id” });
INSERTにより自動生成された主キーをKeyHolderオブジェクトに保持させる処理。
以下で解説している。
概要 データアクセスフレームワークであるSpring JDBCを使用する方法についてまとめた。 当記事では、JdbcTemplateの更新処理であるupdateメソッドの使い方について紹介する。 前提 以下の記事[…]
使用結果
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)])