---
title: 入門JDBC 〜Java RDBアクセスの仕組み〜
tags:  #java  
author: [tada](https://www.docswell.com/user/MasatoshiTada)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/2EVM3ZWYEQ.jpg?width=480
description: JDBCに関して基礎から解説した資料です。 https://javado.connpass.com/event/251865/
published: August 06, 22
canonical: https://www.docswell.com/s/MasatoshiTada/K7MM75-jdbc-intro
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/2EVM3ZWYEQ.jpg)

入門JDBC
〜Java RDBアクセスの仕組み〜
(株)クレディセゾン 多田真敏
2022年8月6日
Java Doでしょう #201


# Page. 2

![Page Image](https://bcdn.docswell.com/page/57GG34DW7L.jpg)

このセッションについて
▸ JavaでRDBアクセスするための仕組みを、
基礎から丁寧に解説します
▸ 対象者
▸ [必須] Javaの基本的な文法を知っている方
▸ [必須] 基本的なSQLを知っている方
▸ JDBCを初めて使う方
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4EQX5G1Q7P.jpg)

使用しているバージョン
▸ JDK 17
▸ PostgreSQL 14.2
▸ PostgreSQL JDBC Driver 42.4.0
多少バージョンが違っていても、
内容は変わらないと思います
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/KJ4695RY71.jpg)

自己紹介
▸ 多田真敏 (@suke̲masa)
▸ 元・研修トレーナーの
Javaプログラマー
▸ IntelliJ IDEAが好き
▸ 日本Springユーザ会(JSUG)
スタッフ
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/LE1VKWQN7G.jpg)

目次
① JDBCとは
② JDBCでDBに接続する
③ JDBCでSELECTする
④ JDBCでINSERT・UPDATE・DELETEする
⑤ 高度なトピックス
⑥ ORマッパーとは
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/GEWLD6LM72.jpg)

目次
① JDBCとは
② JDBCでDBに接続する
③ JDBCでSELECTする
④ JDBCでINSERT・UPDATE・DELETEする
⑤ 高度なトピックス
⑥ ORマッパーとは
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/47ZMGYMME3.jpg)

RDB製品は世の中にたくさんある
▸ Oracle、Db2、SQL Server、MySQL、
PostgreSQL、・・・
▸ それぞれのRDBで、
アクセスするための通信プロトコルは異なる
▸ どんなRDBでも、同じJavaコードで
アクセスできたら嬉しい！
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/YJ6NYDN5JV.jpg)

JDBCとは
▸ DBアクセスのための標準API
▸ インタフェースの集合＝クラスはほとんど無い
▸ インタフェースを実装したクラス群は、
各RDBベンダーによってJAR形式で提供される
＝ JDBCドライバー
▸ 開発者はインタフェースのみ使ってコードを書く
→ RDBが変わっても、コードは変更しなくてよい！
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/GJ55G35GJ4.jpg)

Javadocを見ると
▸ JDBCの実体
java.sqlパッケージ
クラスは少し
インタフェースはいっぱい
https://docs.oracle.com/javase/jp/17/docs/api/java.sql/java/sql/package-summary.html
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/9E2NYZND7R.jpg)

主要なインタフェース
▸ Connection
▸ RDBとの接続を表す
▸ PreparedStatement
▸ RDBに向けてSQLを実行する
▸ ResultSet
▸ SELECTによる検索結果を保持する
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/D7YPGRPM7M.jpg)

PostgreSQL JDBC Driver
▸ PostgreSQLの
JDBCドライバー
＝ PostgreSQL用の
実装クラスの集合
Connectionインタフェースの
実装クラス
PreparedStatement
インタフェースの実装クラス
ResultSetインタフェースの
実装クラス
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/VEN5GD53J8.jpg)

PostgreSQL JDBC Driverを使う
▸ Mavenの場合は、
pom.xmlにdependencyを追加
&lt;dependency&gt;
&lt;groupId&gt;org.postgresql&lt;/groupId&gt;
&lt;artifactId&gt;postgresql&lt;/artifactId&gt;
&lt;version&gt;42.4.0&lt;/version&gt;
&lt;scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
▸ Mavenとは何ぞやについては、
@yusukeさんの動画をご確認ください
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/Y79YWGYPE3.jpg)

目次
① JDBCとは
② JDBCでDBに接続する
③ JDBCでSELECTする
④ JDBCでINSERT・UPDATE・DELETEする
⑤ 高度なトピックス
⑥ ORマッパーとは
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/G786NV6XJD.jpg)

JDBCでDBに接続する
▸ 検索などの操作を行うには、
ますDBに接続することが必要
▸ DBに接続するにはDriverManagerの
getConnection()を利用する
▸ DB操作が終わったら、
必ずConnectionのclose()で接続を終了する
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/L7L9P59NER.jpg)

getConnection()の引数
① url
▸ DBのIPアドレス(orホスト名)・ポート番号・データベース名を指定
▸ PostgreSQLの場合は
jdbc:postgresql://IPアドレス:ポート番号/データベース名
② ユーザー名
▸ DBのユーザー名
RDB製品によって書き方が
微妙に異なるので注意
③ パスワード
▸ DBのパスワード
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/4EMZ43ZQ7W.jpg)

良くないコード例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectSample {
public static void main(String[] args) throws SQLException {
String url = &quot;jdbc:postgresql://localhost:5432/postgres&quot;;
String username = &quot;postgres&quot;;
String password = &quot;postgres&quot;;
Connection connection =
DriverManager.getConnection(url, username, password);
System.out.println(&quot;DBに接続しました！&quot;);
connection.close();
System.out.println(&quot;DB接続を終了しました！&quot;);
}
}
getConnection()で
例外が発生すると
close()されない！
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/PER6WQ6KJ9.jpg)

fi
まあまあ良いコード例
Connection connection = null;
try {
connection = DriverManager.getConnection(url, username, password);
System.out.println(&quot;DBに接続しました！&quot;);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
nally節で確実にclose()
if (connection != null) {
try {
connection.close();
System.out.println(&quot;DB接続を終了しました！&quot;);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
※スペースの都合上、一部省略しています
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/P7XMP5M5JX.jpg)

良いコード例
try (Connection connection =
DriverManager.getConnection(url, username, password)) {
System.out.println(&quot;DBに接続しました！&quot;);
} catch (SQLException e) {
throw new RuntimeException(e);
}
try-with-resourcesで
自動的にclose()
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/37KGD6GRED.jpg)

目次
① JDBCとは
② JDBCでDBに接続する
③ JDBCでSELECTする
④ JDBCでINSERT・UPDATE・DELETEする
⑤ 高度なトピックス
⑥ ORマッパーとは
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/LJ3NR6NGJ5.jpg)

SELECTの流れ
① 文字列でSELECT文を書く
② ConnectionのprepareStatement()で
PreparedStatementを取得する
③ PreparedStatementのexecuteQuery()で
SELECT文を実行する
→ 戻り値のResultSetが検索結果を保持する
④ ResultSetのnext()で1行ずつ移動する
‣ 次の行がある場合はtrue、無ければfalseを返す
⑤ ResultSetのgetXxx()で1列ずつ値を取りだす
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/8JDWYVWNEG.jpg)

SELECTの流れ
① 文字列でSELECT文を書く
String sql = &quot;&quot;&quot;
SELECT id, name, department, salary, joined_date
FROM employee
WHERE department =
AND salary &gt;=
ORDER BY id
&quot;&quot;&quot;;
?
?
パラメーターに
したい部分は?にする
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/VEP96V9N78.jpg)

SELECTの実行
② ConnectionのprepareStatement()で
PreparedStatementを取得する
PreparedStatementも
自動クローズされるようにする
引数にSQLを指定
try (Connection connection = DriverManager.getConnection(
url, username, password);
PreparedStatement statement =
connection.prepareStatement(sql)) {
statement.setString(1, &quot;乃木坂46&quot;);
statement.setInt(2, 250000);
1番目の?に&quot;乃木坂46&quot;を代入
2番目の?に250000を代入
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/27VM3ZMY7Q.jpg)

SELECTの実行
③ PreparedStatementのexecuteQuery()で
SELECT文を実行する
→ 戻り値のResultSetが検索結果を保持する
try (ResultSet resultSet = statement.executeQuery()) {
ResultSetも
自動クローズされるようにする
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/5JGG34GWJL.jpg)

SELECTの実行
④ ResultSetのnext()で1行ずつ移動する
‣ 次の行がある場合はtrue、無ければfalseを返す
try (ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
...
}
1行移動
next() -&gt; true
next() -&gt; true
id
name
･･･
1
Alice
・・・
2
Bob
・・・
next() -&gt; false
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/47QX5GXQJP.jpg)

SELECTの実行
⑤ ResultSetのgetXxx()で1列ずつ値を取りだす
列名を指定して、
1列ずつ値を取得
try (ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
int id = resultSet.getInt(&quot;id&quot;);
String name = resultSet.getString(&quot;name&quot;);
String department = resultSet.getString(&quot;department&quot;);
int salary = resultSet.getInt(&quot;salary&quot;);
LocalDate joinedDate =
resultSet.getObject(&quot;joined_date&quot;, LocalDate.class);
System.out.println(&quot;%d, %s, %s, %d, %s&quot;.formatted(
id, name, department, salary, joinedDate));
}
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/KE46956YJ1.jpg)

目次
① JDBCとは
② JDBCでDBに接続する
③ JDBCでSELECTする
④ JDBCでINSERT・UPDATE・DELETEする
⑤ 高度なトピックス
⑥ ORマッパーとは
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/L71VKWVNJG.jpg)

INSERT・UPDATE・DELETEの流れ
① ConnectionのprepareStatement()で
PreparedStatementを取得する
② PreparedStatementのexecuteUpdate()
でINSERT・UPDATE・DELETEを実行する
→ 戻り値は追加・更新・削除された行数
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/G7WLD63MJ2.jpg)

INSERTの実行
String sql = &quot;&quot;&quot;
INSERT INTO employee(name, department, salary, joined_date)
VALUES(?, ?, ?, ?)
&quot;&quot;&quot;;
Employee newEmployee = new Employee(null, &quot;髙橋未来虹&quot;, &quot;日向坂46&quot;,
200000, LocalDate.of(2020, 2, 16));
try (Connection connection = DriverManager.getConnection(
url, username, password);
PreparedStatement statement =
connection.prepareStatement(sql)) {
statement.setString(1, newEmployee.name());
statement.setString(2, newEmployee.department());
statement.setInt(3, newEmployee.salary());
statement.setObject(4, newEmployee.joinedDate());
int rows = statement.executeUpdate();
System.out.println(rows + &quot;行追加しました。&quot;);
} catch (SQLException e) { throw new RuntimeException(e); }
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/4JZMGYVM73.jpg)

UPDATEの実行
String sql = &quot;&quot;&quot;
UPDATE employee
SET name = ?, department = ?, salary = ?, joined_date = ?
WHERE id = ?
&quot;&quot;&quot;;
Employee newEmployee = new Employee(7, &quot;賀喜遥香&quot;, &quot;乃木坂46&quot;,
270000, LocalDate.of(2018, 8, 19));
try (Connection connection = DriverManager.getConnection(
url, username, password);
PreparedStatement statement =
connection.prepareStatement(sql)) {
statement.setString(1, newEmployee.name());
statement.setString(2, newEmployee.department());
statement.setInt(3, newEmployee.salary());
statement.setObject(4, newEmployee.joinedDate());
statement.setInt(5, newEmployee.id());
int rows = statement.executeUpdate();
System.out.println(rows + &quot;行更新しました。&quot;);
} catch (SQLException e) { throw new RuntimeException(e); }
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/YE6NYD55EV.jpg)

DELETEの実行
String sql = &quot;&quot;&quot;
DELETE FROM employee
WHERE id = ?
&quot;&quot;&quot;;
int id = 7;
try (Connection connection = DriverManager.getConnection(
url, username, password);
PreparedStatement statement =
connection.prepareStatement(sql)) {
statement.setInt(1, id);
int rows = statement.executeUpdate();
System.out.println(rows + &quot;行削除しました。&quot;);
} catch (SQLException e) { throw new RuntimeException(e); }
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/GE55G3YGE4.jpg)

目次
① JDBCとは
② JDBCでDBに接続する
③ JDBCでSELECTする
④ JDBCでINSERT・UPDATE・DELETEする
⑤ 高度なトピックス
⑥ ORマッパーとは
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/972NYZGDJR.jpg)

トランザクション
▸ トランザクション機能を有効化するには、
ConnectionのsetAutoCommit()に
falseを指定する
▸ これにより自動コミット(1行ごとのコミット)
が無効化される
▸ Connectionのcommit()でコミット、
rollback()でロールバック
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/DJYPGRVMJM.jpg)

トランザクション
String sql1 = &quot;&quot;&quot;
INSERT INTO employee(name, department, salary, joined_date)
VALUES(&#039;髙橋未来虹&#039;, &#039;日向坂46&#039;, 200000, &#039;2020-02-16&#039;)
&quot;&quot;&quot;;
String sql2 = &quot;&quot;&quot;
INSERT INTO employee(name, department, salary, joined_date)
VALUES(&#039;賀喜遥香&#039;, &#039;乃木坂46&#039;, 270000, &#039;2018-08-19&#039;)
&quot;&quot;&quot;;
boolean throwException = false;
Connection connection = null;
PreparedStatement statement1 = null;
PreparedStatement statement2 = null;
try {
connection = DriverManager.getConnection(
url, username, password);
connection.setAutoCommit(false);
※try-with-resourcesでは書きづらかったため、わざと使っていません
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/V7N5GDM3E8.jpg)

トランザクション
statement1 = connection.prepareStatement(sql1);
int rows1 = statement1.executeUpdate();
if (throwException) {
throw new Exception(&quot;わざと例外&quot;);
}
statement2 = connection.prepareStatement(sql2);
int rows2 = statement2.executeUpdate();
connection.commit();
System.out.println(&quot;コミットしました。&quot;);
} catch (Exception e) {
if (connection != null) {
try {
connection.rollback();
System.out.println(&quot;ロールバックしました。&quot;);
} catch (SQLException e2) {
throw new RuntimeException(e2);
}
}
throw new RuntimeException(e);
}
34


# Page. 35

![Page Image](https://bcdn.docswell.com/page/YJ9YWGNP73.jpg)

DDL文の実行
▸ PreparedStatementのexecute()で実行
String sql = &quot;&quot;&quot;
CREATE TABLE test(
id INTEGER PRIMARY KEY,
content VARCHAR(32)
)
&quot;&quot;&quot;;
try (Connection connection = DriverManager.getConnection(
url, username, password);
PreparedStatement statement =
connection.prepareStatement(sql)) {
statement.execute();
System.out.println(&quot;テーブルを作成しました。&quot;);
} catch (SQLException e) {
throw new RuntimeException(e);
}
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/GJ86NVKXED.jpg)

DatabaseMetaData
▸ 接続中のデータベースに関する情報を取得できる
▸ getDatabaseProductName() : DB製品名
▸ getTables() : テーブル一覧(型はResultSet)
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/LJL9P5ZN7R.jpg)

DatabaseMetaDataの利用
try (Connection connection = DriverManager.getConnection(
url, username, password)) {
DatabaseMetaData databaseMetaData = connection.getMetaData();
ResultSet tables = databaseMetaData.getTables(
null, null, null, new String[]{&quot;TABLE&quot;});
while (tables.next()) {
String tableName = tables.getString(&quot;TABLE_NAME&quot;);
System.out.println(tableName);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
実行結果
employee
37


# Page. 38

![Page Image](https://bcdn.docswell.com/page/47MZ43VQJW.jpg)

ResultSetMetaData
▸ 検索結果に関する情報を取得できる
▸ getTableName() : テーブル名
▸ getColumnCount() : 検索した列数
▸ getColumnName() : 検索した列名
38


# Page. 39

![Page Image](https://bcdn.docswell.com/page/P7R6WQ2KE9.jpg)

ResultSetMetaDataの利用
try (ResultSet resultSet = statement.executeQuery()) {
ResultSetMetaData metaData = resultSet.getMetaData();
String tableName = metaData.getTableName(1);
System.out.println(&quot;テーブル名: &quot; + tableName);
int columnCount = metaData.getColumnCount();
for (int i = 1; i &lt;= columnCount; i++) {
String columnName = metaData.getColumnName(i);
System.out.println(&quot;列名: &quot; + columnName);
}
} // 以下省略
実行結果
テーブル名: employee
列名: id
列名: name
列名: department
列名: salary
列名: joined_date
39


# Page. 40

![Page Image](https://bcdn.docswell.com/page/PJXMP5D5EX.jpg)

IntelliJ IDEAのDatabase Tool
▸ DatabaseMetaDataや
ResultSetMetaDataで
作られているのかも？
▸ IntelliJ IDEAはJava製
40


# Page. 41

![Page Image](https://bcdn.docswell.com/page/3JKGD6XR7D.jpg)

目次
① JDBCとは
② JDBCでDBに接続する
③ JDBCでSELECTする
④ JDBCでINSERT・UPDATE・DELETEする
⑤ 高度なトピックス
⑥ ORマッパーとは
41


# Page. 42

![Page Image](https://bcdn.docswell.com/page/LE3NR65GE5.jpg)

JDBCは面倒（特に検索）
① Connectionを作って
② PreparedStatementを作って
③ 検索を実行してResultSetを受け取って
④ 1行ずつ移動して
⑤ 1列ずつ値を取得して
⑥ インスタンスに変換して
⑦ finallyで忘れずにクローズ
😫
42


# Page. 43

![Page Image](https://bcdn.docswell.com/page/8EDWYVDN7G.jpg)

ORマッパーとは
▸ Object/Relational Mapper
▸ DBアクセスを簡潔に記述できる
▸ 内部ではJDBCとリフレクションを使っている
▸ 参考記事: 入門Javaのリフレクション
ORマッパー
業務
コード
JDBC
RDB
43


# Page. 44

![Page Image](https://bcdn.docswell.com/page/V7P96VXNJ8.jpg)

OSSのORマッパーたち
▸ Spring JDBC
▸ MyBatis
▸ Doma
▸ DBFlute
▸ jOOQ
▸ Hibernate
▸ ・・・など
44


# Page. 45

![Page Image](https://bcdn.docswell.com/page/2JVM3ZLYJQ.jpg)

Spring JDBCの例
String sql = &quot;&quot;&quot;
SELECT id, name, department, salary, joined_date
FROM employee
WHERE department = ?
AND salary &gt;= ?
ORDER BY id
&quot;&quot;&quot;;
DataSource dataSource = new DriverManagerDataSource(
url, username, password);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List&lt;Employee&gt; employeeList = jdbcTemplate.query(sql,
new DataClassRowMapper&lt;&gt;(Employee.class), &quot;乃木坂46&quot;, 250000);
for (Employee employee : employeeList) {
System.out.println(employee);
}
45


# Page. 46

![Page Image](https://bcdn.docswell.com/page/5EGG34XWEL.jpg)

ORマッパーでこれだけ簡潔になる
JDBC:
21行
Spring JDBC:
1行
46


# Page. 47

![Page Image](https://bcdn.docswell.com/page/4JQX5G8QEP.jpg)

ORマッパーの選び方
https://www.docswell.com/s/MasatoshiTada/596WW5-how-to-choose-java-orm
47


# Page. 48

![Page Image](https://bcdn.docswell.com/page/K746952YE1.jpg)

まとめ
▸ JDBCはインタフェースの集合。
その実装クラスの集合がJDBCドライバー
▸ JDBCはDML/DDLの実行、トランザクション、
メタデータの取得などの機能を備えている
▸ ORマッパーはJDBCとリフレクションで作られている
▸ 素のJDBCをそのまま現場で使うことはほぼ無い
(はず)
▸ しかし、仕組みを知っておけば色々と応用が効く
48


