カラム名を動的に取り込み、CSVファイルをSQLiteに格納する方法を以下に示します。ここでは、CSVの最初の行をカラム名として使用します。
必要なライブラリ
- SQLite JDBCライブラリ
- OpenCSVライブラリ(CSVファイルの読み書きに使用)
ステップ1: 必要なライブラリを追加
Maven依存関係
org.xerial sqlite-jdbc 3.34.0<!-- OpenCSV Library -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.5.2</version>
</dependency>
ステップ2: カラム名を動的に取り込み、CSVファイルをSQLiteに格納する
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.CSVWriter;
import com.opencsv.exceptions.CsvValidationException;
public class CsvToSQLite {
private static final String DB_URL = "jdbc:sqlite:example.db";
public static void main(String[] args) {
try (Connection conn = DriverManager.getConnection(DB_URL)) {
if (conn != null) {
// CSVファイルを読み込み、TableAに挿入
importCsvToTable(conn, "path/to/csv_A/", "TableA");
// CSVファイルを読み込み、TableBに挿入
importCsvToTable(conn, "path/to/csv_B/", "TableB");
// 差分を抽出し、CSVに出力
exportDiffToCsv(conn, "TableA", "TableB", "diffA.csv");
exportDiffToCsv(conn, "TableB", "TableA", "diffB.csv");
}
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
private static void importCsvToTable(Connection conn, String csvDirPath, String tableName) {
File folder = new File(csvDirPath);
File[] listOfFiles = folder.listFiles((dir, name) -> name.endsWith(".csv"));
if (listOfFiles == null) {
System.out.println("No CSV files found in the directory: " + csvDirPath);
return;
}
for (File file : listOfFiles) {
try (CSVReader csvReader = new CSVReaderBuilder(new FileReader(file))
.withSkipLines(0) // コメント行を処理するためにスキップしない
.build()) {
// 最初の行をカラム名として取得
String[] headers = csvReader.readNext();
if (headers == null) {
continue;
}
// コメント行をスキップ
while (headers[0].startsWith("#")) {
headers = csvReader.readNext();
if (headers == null) {
break;
}
}
// テーブル作成
createTable(conn, tableName, headers);
// データ挿入
String[] row;
while ((row = csvReader.readNext()) != null) {
if (row[0].startsWith("#")) {
continue;
}
insertRow(conn, tableName, headers, row);
}
} catch (IOException | CsvValidationException | SQLException e) {
System.out.println(e.getMessage());
}
}
}
private static void createTable(Connection conn, String tableName, String[] headers) throws SQLException {
try (Statement stmt = conn.createStatement()) {
String columns = String.join(" TEXT, ", headers) + " TEXT";
String createTableSQL = String.format("CREATE TABLE IF NOT EXISTS %s (%s)", tableName, columns);
stmt.execute(createTableSQL);
}
}
private static void insertRow(Connection conn, String tableName, String[] headers, String[] row) throws SQLException {
String columns = String.join(", ", headers);
String placeholders = String.join(", ", Arrays.asList(row).stream().map(col -> "?").toArray(String[]::new));
String insertSQL = String.format("INSERT INTO %s (%s) VALUES (%s)", tableName, columns, placeholders);
try (java.sql.PreparedStatement pstmt = conn.prepareStatement(insertSQL)) {
for (int i = 0; i < row.length; i++) {
pstmt.setString(i + 1, row[i]);
}
pstmt.executeUpdate();
}
}
private static void exportDiffToCsv(Connection conn, String tableA, String tableB, String outputCsvPath) {
String sql = String.format("SELECT * FROM %s EXCEPT SELECT * FROM %s", tableA, tableB);
try (CSVWriter writer = new CSVWriter(new FileWriter(outputCsvPath));
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
writer.writeAll(rs, true);
} catch (SQLException | IOException e) {
System.out.println(e.getMessage());
}
}
}
説明
-
カラム名の動的取得:
最初の行をカラム名として読み込み、headers
配列に格納します。コメント行が最初にある場合は無視します。 -
テーブルの作成:
createTable
メソッドを使い、動的に取得したカラム名でテーブルを作成します。 -
データの挿入:
insertRow
メソッドを使い、動的に取得したカラム名に基づいてデータを挿入します。 -
CSVファイルの読み込み:
指定されたディレクトリ内のすべてのCSVファイルを読み込み、対応するテーブルにデータを挿入します。 -
差分の抽出とCSVへのエクスポート:
exportDiffToCsv
メソッドを使用して、TableA
とTableB
の差分を抽出し、結果を指定されたCSVファイルに書き込みます。
このスクリプトを使用することで、CSVファイルのカラム名を動的に取り込み、適切なテーブルを作成し、データを挿入することができます。カラム名やテーブル構造は実際のデータに応じて調整してください。