001package com.streamconverter.examples; 002 003import com.streamconverter.StreamConverter; 004import com.streamconverter.command.IStreamCommand; 005import com.streamconverter.command.impl.csv.CsvNavigateCommand; 006import com.streamconverter.command.impl.json.JsonNavigateCommand; 007import com.streamconverter.command.rule.DatabaseFetchRule; 008import com.streamconverter.path.CSVPath; 009import com.streamconverter.path.TreePath; 010import java.io.ByteArrayInputStream; 011import java.io.ByteArrayOutputStream; 012import java.sql.Connection; 013import java.sql.DriverManager; 014import java.sql.PreparedStatement; 015import java.sql.SQLException; 016 017/** 018 * DatabaseFetchRuleの実用的な使用例デモンストレーション 019 * 020 * <p>このデモでは以下の実用的なシナリオを示します: 1. 顧客IDを顧客名に変換 2. 商品コードを商品名と価格に変換 3. 部署コードを部署名に変換 4. 021 * エラーハンドリング(存在しないIDの処理) 022 */ 023public class DatabaseRuleDemo { 024 025 private static final String DB_URL = "jdbc:h2:mem:demo;DB_CLOSE_DELAY=-1"; 026 027 public static void main(String[] args) { 028 try { 029 // デモ用データベースの初期化 030 setupDemoDatabase(); 031 032 System.out.println("=== DatabaseFetchRule実用例デモ ===\n"); 033 034 // シナリオ1: JSON内の顧客IDを顧客名に変換 035 demonstrateCustomerIdConversion(); 036 037 // シナリオ2: CSV内の商品コードを商品名に変換 038 demonstrateProductCodeConversion(); 039 040 // シナリオ3: 複数のIDを含むJSONの一括変換 041 demonstrateBatchProcessing(); 042 043 // シナリオ4: StreamConverterと組み合わせた複雑な処理 044 demonstrateComplexPipeline(); 045 046 // シナリオ5: エラーハンドリングの例 047 demonstrateErrorHandling(); 048 049 } catch (Exception e) { 050 System.err.println("デモ実行中にエラーが発生しました: " + e.getMessage()); 051 e.printStackTrace(); 052 } 053 } 054 055 /** デモ用のデータベースセットアップ */ 056 private static void setupDemoDatabase() throws SQLException { 057 try (Connection conn = DriverManager.getConnection(DB_URL)) { 058 // テーブル作成 059 conn.prepareStatement( 060 """ 061 CREATE TABLE customers ( 062 id INTEGER PRIMARY KEY, 063 name VARCHAR(100), 064 email VARCHAR(100), 065 phone VARCHAR(20) 066 ) 067 """) 068 .execute(); 069 070 conn.prepareStatement( 071 """ 072 CREATE TABLE products ( 073 code VARCHAR(20) PRIMARY KEY, 074 name VARCHAR(100), 075 price DECIMAL(10,2), 076 category VARCHAR(50) 077 ) 078 """) 079 .execute(); 080 081 conn.prepareStatement( 082 """ 083 CREATE TABLE departments ( 084 code VARCHAR(10) PRIMARY KEY, 085 name VARCHAR(50), 086 manager VARCHAR(50) 087 ) 088 """) 089 .execute(); 090 091 // テストデータ挿入 092 insertDemoData(conn); 093 094 System.out.println("✅ デモ用データベースを初期化しました"); 095 } 096 } 097 098 private static void insertDemoData(Connection conn) throws SQLException { 099 // 顧客データ 100 PreparedStatement customerStmt = 101 conn.prepareStatement("INSERT INTO customers (id, name, email, phone) VALUES (?, ?, ?, ?)"); 102 103 customerStmt.setInt(1, 1001); 104 customerStmt.setString(2, "田中太郎"); 105 customerStmt.setString(3, "tanaka@example.com"); 106 customerStmt.setString(4, "090-1234-5678"); 107 customerStmt.execute(); 108 109 customerStmt.setInt(1, 1002); 110 customerStmt.setString(2, "佐藤花子"); 111 customerStmt.setString(3, "sato@example.com"); 112 customerStmt.setString(4, "090-9876-5432"); 113 customerStmt.execute(); 114 115 customerStmt.setInt(1, 1003); 116 customerStmt.setString(2, "鈴木一郎"); 117 customerStmt.setString(3, "suzuki@example.com"); 118 customerStmt.setString(4, "090-5555-7777"); 119 customerStmt.execute(); 120 121 // 商品データ 122 PreparedStatement productStmt = 123 conn.prepareStatement( 124 "INSERT INTO products (code, name, price, category) VALUES (?, ?, ?, ?)"); 125 126 productStmt.setString(1, "LAPTOP001"); 127 productStmt.setString(2, "高性能ビジネスノートPC"); 128 productStmt.setBigDecimal(3, new java.math.BigDecimal("98000.00")); 129 productStmt.setString(4, "PC"); 130 productStmt.execute(); 131 132 productStmt.setString(1, "MOUSE001"); 133 productStmt.setString(2, "無線光学マウス"); 134 productStmt.setBigDecimal(3, new java.math.BigDecimal("2980.00")); 135 productStmt.setString(4, "周辺機器"); 136 productStmt.execute(); 137 138 productStmt.setString(1, "MONITOR001"); 139 productStmt.setString(2, "24インチ液晶ディスプレイ"); 140 productStmt.setBigDecimal(3, new java.math.BigDecimal("24800.00")); 141 productStmt.setString(4, "モニター"); 142 productStmt.execute(); 143 144 // 部署データ 145 PreparedStatement deptStmt = 146 conn.prepareStatement("INSERT INTO departments (code, name, manager) VALUES (?, ?, ?)"); 147 148 deptStmt.setString(1, "DEV"); 149 deptStmt.setString(2, "開発部"); 150 deptStmt.setString(3, "山田部長"); 151 deptStmt.execute(); 152 153 deptStmt.setString(1, "SALES"); 154 deptStmt.setString(2, "営業部"); 155 deptStmt.setString(3, "田村部長"); 156 deptStmt.execute(); 157 158 deptStmt.setString(1, "HR"); 159 deptStmt.setString(2, "人事部"); 160 deptStmt.setString(3, "川上部長"); 161 deptStmt.execute(); 162 } 163 164 /** シナリオ1: JSON内の顧客IDを顧客名に変換 */ 165 private static void demonstrateCustomerIdConversion() throws Exception { 166 System.out.println("--- シナリオ1: 顧客IDを顧客名に変換 ---"); 167 168 // DatabaseFetchRuleの作成 169 DatabaseFetchRule customerRule = 170 new DatabaseFetchRule(DB_URL, "SELECT name FROM customers WHERE id = ?"); 171 172 // JsonNavigateCommandの作成 173 JsonNavigateCommand command = 174 new JsonNavigateCommand(TreePath.fromJson("$.customerId"), customerRule); 175 176 // 変換前のJSON 177 String inputJson = 178 """ 179 { 180 "orderId": "ORD-2024-001", 181 "customerId": "1001", 182 "orderDate": "2024-01-15", 183 "items": [ 184 {"productCode": "LAPTOP001", "quantity": 1} 185 ], 186 "totalAmount": 98000 187 } 188 """; 189 190 System.out.println("📄 変換前のJSON:"); 191 System.out.println(inputJson); 192 193 // 変換実行 194 ByteArrayInputStream input = new ByteArrayInputStream(inputJson.getBytes()); 195 ByteArrayOutputStream output = new ByteArrayOutputStream(); 196 197 command.execute(input, output); 198 199 System.out.println("✨ 変換後のJSON:"); 200 System.out.println(output.toString()); 201 System.out.println(); 202 } 203 204 /** シナリオ2: CSV内の商品コードを商品名に変換 */ 205 private static void demonstrateProductCodeConversion() throws Exception { 206 System.out.println("--- シナリオ2: 商品コードを商品名に変換 ---"); 207 208 // DatabaseFetchRuleの作成 209 DatabaseFetchRule productRule = 210 new DatabaseFetchRule(DB_URL, "SELECT name FROM products WHERE code = ?"); 211 212 // CsvNavigateCommandの作成 213 CsvNavigateCommand command = new CsvNavigateCommand(new CSVPath("product_code"), productRule); 214 215 // 変換前のCSV 216 String inputCsv = 217 """ 218 order_id,customer_id,product_code,quantity,unit_price 219 ORD-001,1001,LAPTOP001,1,98000 220 ORD-002,1002,MOUSE001,2,2980 221 ORD-003,1003,MONITOR001,1,24800 222 """; 223 224 System.out.println("📊 変換前のCSV:"); 225 System.out.println(inputCsv); 226 227 // 変換実行 228 ByteArrayInputStream input = new ByteArrayInputStream(inputCsv.getBytes()); 229 ByteArrayOutputStream output = new ByteArrayOutputStream(); 230 231 command.execute(input, output); 232 233 System.out.println("✨ 変換後のCSV:"); 234 System.out.println(output.toString()); 235 System.out.println(); 236 } 237 238 /** シナリオ3: 複数のIDを含むJSONの一括変換 */ 239 private static void demonstrateBatchProcessing() throws Exception { 240 System.out.println("--- シナリオ3: 複数顧客IDの一括変換 ---"); 241 242 // DatabaseFetchRuleの作成 243 DatabaseFetchRule customerRule = 244 new DatabaseFetchRule(DB_URL, "SELECT name FROM customers WHERE id = ?"); 245 246 // JsonNavigateCommandの作成 247 JsonNavigateCommand command = 248 new JsonNavigateCommand(TreePath.fromJson("$.customerId"), customerRule); 249 250 // 複数の注文を含むJSON 251 String inputJson = 252 """ 253 [ 254 { 255 "orderId": "ORD-001", 256 "customerId": "1001", 257 "amount": 98000 258 }, 259 { 260 "orderId": "ORD-002", 261 "customerId": "1002", 262 "amount": 5960 263 }, 264 { 265 "orderId": "ORD-003", 266 "customerId": "1003", 267 "amount": 24800 268 } 269 ] 270 """; 271 272 System.out.println("📄 変換前のJSON配列:"); 273 System.out.println(inputJson); 274 275 // 変換実行 276 ByteArrayInputStream input = new ByteArrayInputStream(inputJson.getBytes()); 277 ByteArrayOutputStream output = new ByteArrayOutputStream(); 278 279 command.execute(input, output); 280 281 System.out.println("✨ 変換後のJSON配列:"); 282 System.out.println(output.toString()); 283 System.out.println(); 284 } 285 286 /** シナリオ4: StreamConverterと組み合わせた複雑な処理 */ 287 private static void demonstrateComplexPipeline() throws Exception { 288 System.out.println("--- シナリオ4: 複雑なパイプライン処理 ---"); 289 290 // 顧客ID変換ルール 291 DatabaseFetchRule customerRule = 292 new DatabaseFetchRule(DB_URL, "SELECT name FROM customers WHERE id = ?"); 293 294 // 部署コード変換ルール 295 DatabaseFetchRule deptRule = 296 new DatabaseFetchRule(DB_URL, "SELECT name FROM departments WHERE code = ?"); 297 298 // 複数段階の変換を組み合わせる 299 JsonNavigateCommand customerCommand = 300 new JsonNavigateCommand(TreePath.fromJson("$.customerId"), customerRule); 301 JsonNavigateCommand deptCommand = 302 new JsonNavigateCommand(TreePath.fromJson("$.deptCode"), deptRule); 303 304 // StreamConverterで複数のコマンドを組み合わせ 305 StreamConverter converter = 306 new StreamConverter(new IStreamCommand[] {customerCommand, deptCommand}); 307 308 // 変換前のJSON 309 String inputJson = 310 """ 311 { 312 "employeeId": "EMP-001", 313 "customerId": "1001", 314 "deptCode": "DEV", 315 "projectName": "新システム開発", 316 "status": "進行中" 317 } 318 """; 319 320 System.out.println("📄 変換前のJSON:"); 321 System.out.println(inputJson); 322 323 // パイプライン実行 324 ByteArrayInputStream input = new ByteArrayInputStream(inputJson.getBytes()); 325 ByteArrayOutputStream output = new ByteArrayOutputStream(); 326 327 converter.run(input, output); 328 329 System.out.println("✨ パイプライン変換後のJSON:"); 330 System.out.println(output.toString()); 331 System.out.println(); 332 } 333 334 /** シナリオ5: エラーハンドリングの例 */ 335 private static void demonstrateErrorHandling() throws Exception { 336 System.out.println("--- シナリオ5: エラーハンドリング ---"); 337 338 // DatabaseFetchRuleの作成 339 DatabaseFetchRule customerRule = 340 new DatabaseFetchRule(DB_URL, "SELECT name FROM customers WHERE id = ?"); 341 342 // JsonNavigateCommandの作成 343 JsonNavigateCommand command = 344 new JsonNavigateCommand(TreePath.fromJson("$.customerId"), customerRule); 345 346 // 存在しない顧客IDを含むJSON 347 String inputJson = 348 """ 349 { 350 "orderId": "ORD-9999", 351 "customerId": "9999", 352 "amount": 50000, 353 "note": "存在しない顧客IDのテスト" 354 } 355 """; 356 357 System.out.println("📄 存在しない顧客IDを含むJSON:"); 358 System.out.println(inputJson); 359 360 // 変換実行 361 ByteArrayInputStream input = new ByteArrayInputStream(inputJson.getBytes()); 362 ByteArrayOutputStream output = new ByteArrayOutputStream(); 363 364 command.execute(input, output); 365 366 System.out.println("✨ 変換結果(存在しないIDは空文字列になる):"); 367 System.out.println(output.toString()); 368 369 System.out.println("💡 DatabaseFetchRuleは存在しないIDに対して空文字列を返し、"); 370 System.out.println(" システム全体の安定性を保ちます。"); 371 System.out.println(); 372 } 373}