前回の記事でJDBCを使ってJavaからのSQLiteデータベースにアクセスすることに成功しました。
予めデータベースを用意しておいてJavaプログラムでSELECT文を記述してデータベースからデータを取得するだけだったので、もう一歩踏み込んでSELECT文に加えてINSERT文・UPDATE文・DELETE文等を組み込んだものに挑戦してみました。
環境
今回の開発環境については以下のとおりです。
- Ubuntu 18.04.5LTS
- OpenJDK 11.0.8
- SQLite3 3.22.0
参考にしたサンプルコード
今回は複数のSQL文を使いたかったので、JDBCリポジトリのREADMEにあったサンプルコードをもとにメソッド化していこうと思います。
import java.sql.*;
public class Sample
{
public static void main(String[] args) throws ClassNotFoundException
{
// load the sqlite-JDBC driver using the current class loader
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:sample.db");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("drop table if exists person");
statement.executeUpdate("create table person (id integer, name string)");
statement.executeUpdate("insert into person values(1, 'leo')");
statement.executeUpdate("insert into person values(2, 'yui')");
ResultSet rs = statement.executeQuery("select * from person");
while(rs.next())
{
// read the result set
System.out.println("name = " + rs.getString("name"));
System.out.println("id = " + rs.getInt("id"));
}
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
try
{
if(connection != null)
connection.close();
}
catch(SQLException e)
{
// connection close failed.
System.err.println(e);
}
}
}
}
SQL文ごとにメソッド化する
上記のサンプルコードは、データベスにアクセス → テーブルを消去 → テーブル作成 → データの入力 → データの読み込みの全てをmainメソッドの中で処理しています。
実際のプログラムでは各動作を別々に行うので、それらをメソッド化して必要時にmainメソッドに呼び出して使うのがより現実的だと思います。
自分なりにメソッド化したコードが以下になります。
尚、データベース内の名前は解りやすくするため、適宜変えてあります。
import java.sql.*;
/**
* TestDataBaseAccess
*/
public class TestDataBaseAccess {
static Connection connection;
static String URL = "jdbc:sqlite:sample.db";
public static void main(String[] args) throws ClassNotFoundException {
// load the sqlite-JDBC driver using the current class loader
Class.forName("org.sqlite.JDBC");
connection = null;
dropTable();
createTable();
insertData();
loadData();
updateData();
loadData();
deleteData();
loadData();
}
/**
* SELECT文
*/
public static void loadData() {
try {
// create a database connection
connection = DriverManager.getConnection(URL);
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
ResultSet rs = statement.executeQuery("SELECT * FROM person");
while(rs.next()){
// read the result set
System.out.println("id = " + rs.getInt("id") + " | name = " + rs.getString("name"));
}
} catch(SQLException e) {
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
} finally {
try {
if(connection != null)
connection.close();
} catch(SQLException e) {
// connection close failed.
System.err.println(e);
}
}
}
/**
* INSERT文
*/
public static void insertData() {
try {
// create a database connection
connection = DriverManager.getConnection(URL);
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("INSERT INTO person VALUES(1, 'Satou')");
statement.executeUpdate("INSERT INTO person VALUES(2, 'Tanaka')");
statement.executeUpdate("INSERT INTO person VALUES(3, 'Suzuki')");
} catch(SQLException e) {
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
} finally {
try {
if(connection != null)
connection.close();
} catch(SQLException e) {
// connection close failed.
System.err.println(e);
}
}
}
/**
* UPDATE文
*/
public static void updateData() {
try {
// create a database connection
connection = DriverManager.getConnection(URL);
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("UPDATE person SET name = 'Takahashi' WHERE id = 1");
} catch(SQLException e) {
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
} finally {
try {
if(connection != null)
connection.close();
} catch(SQLException e) {
// connection close failed.
System.err.println(e);
}
}
}
/**
* DELETE文
*/
public static void deleteData() {
try {
// create a database connection
connection = DriverManager.getConnection(URL);
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("DELETE FROM person WHERE id = 3");
} catch(SQLException e) {
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
} finally {
try {
if(connection != null)
connection.close();
} catch(SQLException e) {
// connection close failed.
System.err.println(e);
}
}
}
/**
* テーブル作成
*/
public static void createTable() {
try {
// create a database connection
connection = DriverManager.getConnection(URL);
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("CREATE TABLE person (id INTEGER, name STRING)");
} catch(SQLException e) {
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
} finally {
try {
if(connection != null)
connection.close();
} catch(SQLException e) {
// connection close failed.
System.err.println(e);
}
}
}
/**
* テーブル削除
*/
public static void dropTable() {
try {
// create a database connection
connection = DriverManager.getConnection(URL);
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("DROP TABLE IF EXISTS person");
} catch(SQLException e) {
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
} finally {
try {
if(connection != null)
connection.close();
} catch(SQLException e) {
// connection close failed.
System.err.println(e);
}
}
}
}
メソッド化した上で、処理の流れをmainメソッドに呼び出してみました。
id = 1 | name = Satou
id = 2 | name = Tanaka
id = 3 | name = Suzuki
id = 1 | name = Takahashi
id = 2 | name = Tanaka
id = 3 | name = Suzuki
id = 1 | name = Takahashi
id = 2 | name = Tanaka
まとめ
各SQL文をメソッド化し、必要に応じてmainメソッドに呼び出すことになんとか成功しました。
SQLを扱う場合、各メソッドごとにtry-catchをしないとエラーになるようでした。
しかし現状では、データの入力内容・変更内容をメソッド内で定義しているため、再利用性が低く未だ未完成です。
今回のコードをベースに再利用性のあるコードにしていこうと思います。