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

概要

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

 

前提

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

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の作成と動確方法)

 

特徴

データベースに対する更新操作(INSERT、UPDATE、DELETE)を実行する。
実行したクエリによって、影響を受けた行数を整数値で返却する

 

使い方

JdbcTemplate.updateメソッドは以下のように使用する。

JdbcTemplate.update(
SQL文字列,
バインドするラメータ
)

 

使用例

実際にJdbcTemplate.updateメソッドの使用例について紹介する。

INSERT処理

生徒情報を新規作成する。

インターフェース

StudentDao.java


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

 

実装

JdbcStudentDao.java


@Override
public int createStudent(Student student) {
	var sql = "INSERT INTO student (grade, name, class_name, memo) VALUES (?, ?, ?, ?)";
	return jdbcTemplate.update(sql, student.getGrade(), student.getName(), student.getClassName(),
			student.getMemo());
}

 

使用結果

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

 

UPDATE処理

生徒IDに紐づく生徒名を変更する。

インターフェース

StudentDao.java


/** 生徒名の更新 */
int updateStudentName(Student student);

 

実装

JdbcStudentDao.java


@Override
public int updateStudentName(Student student) {
	var sql = "UPDATE student SET name = ? WHERE id = ?";
	return jdbcTemplate.update(sql, student.getName(), student.getId());
}

 

使用結果

FooMain.java


// 生徒情報の更新
var student = new Student();
student.setName("テスト太郎");
student.setId(1);

int res = studentDao.updateStudentName(student);
System.out.println("更新結果:" + res);
// ------------------------
// コンソール
// ------------------------
// 更新結果:1

 

DELETE処理

生徒IDに紐づくテスト情報を削除する。

インターフェース

StudentDao.java


/** 生徒に紐づくテスト情報の削除 */
int deleteTest(int id);

 

実装

JdbcStudentDao.java


@Override
public int deleteTest(int id) {
	var sql = "DELETE FROM test_point WHERE student_id = ?";
	return jdbcTemplate.update(sql, id);
}

 

使用結果

FooMain.java


// 生徒に紐づくテスト情報の削除
int res = studentDao.deleteTest(3);
System.out.println("削除結果:" + res);

// ------------------------
// コンソール
// ------------------------
// 削除結果:2

 

補足

生徒情報を作成して自動生成された生徒IDをもとに、テスト情報を作成するときはKeyHolderオブジェクトを使用する。

生徒情報作成(生徒IDを返却)

生徒情報を作成した後、自動生成された生徒IDを取得するメソッドを用意する。

インターフェース

StudentDao.java


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

 

実装

JdbcStudentDao.java


@Override	
public int insertStudentAndGetId(Student student) {	
	var sql = "INSERT INTO student (grade, name, class_name, memo) VALUES (?, ?, ?, ?)";
	KeyHolder keyHolder = new GeneratedKeyHolder();
	jdbcTemplate.update(connection -> {
		PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
		ps.setInt(1, student.getGrade());
		ps.setString(2, student.getName());
		ps.setString(3, student.getClassName());
		ps.setString(4, student.getMemo());
		return ps;
	}, keyHolder);
	
	// 生徒IDを取得
	return keyHolder.getKey().intValue();
}	

 

KeyHolder keyHolder = new GeneratedKeyHolder();

KeyHolderオブジェクトは、挿入操作で生成された主キー(今回は自動生成された生徒ID)を保持するために使用される。

 

PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, student.getGrade());
ps.setString(2, student.getName());
ps.setString(3, student.getClassName());
ps.setString(4, student.getMemo());
return ps;

JdbcTemplateのupdateが隠蔽している、JDBC APIをカスタマイズする。

本来はPreparedStatementを実行して処理結果件数を返却するが、今回は処理結果件数ではなくて自動生成IDを返却するよう修正する。
PreparedStatementにStatement.RETURN_GENERATED_KEYSを指定することで、SQL文(特にINSERT文)の実行後に自動生成された主キーを取得できる
※JDBC APIの機能

 

}, keyHolder);

JdbcTemplate.updateメソッドにKeyHolderオブジェクトを渡すことで、挿入によって自動生成された主キーを保持できる。

 

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

KeyHolderオブジェクトが保持する主キーを返却する。

 

テスト情報作成

テスト情報を新規作成するメソッドを用意する。

インターフェース

StudentDao.java


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

 

実装

JdbcStudentDao.java


@Override
public int insertTest(TestPoint test) {
	var sql = "INSERT INTO test_point (student_id, japanese, mathematics, evaluation, test_date) VALUES (?, ?, ?, ?, ?)";
	return jdbcTemplate.update(sql, test.getStudentId(), test.getJapanese(), test.getMathematics(),
			test.getEvaluation(), test.getTestDate());
}

 

生徒情報とテスト情報の作成

生徒情報を作成した後で自動生成される生徒IDをもとに、テスト情報を作成する。
尚、トランザクションは今回は考慮していない。

使用結果

FooMain.java


// 生徒情報と紐づく1件のテスト情報の作成
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-24, studentId=4)])

 

スポンサーリンク