继承类数据插入问题:JDBC执行无效果及类型参数填充疑问
问题解决方案
一、账户类型参数填充
你的Account类未存储账户类型信息,无法直接获取数据库所需的类型字符串,可通过以下两种方式解决:
方案1:扩展Account类添加类型字段
在Account类中新增accountType属性,创建子类实例时传入对应的类型名称(解析CSV时根据token[2]映射,如"C"对应"Checkings"):
public class Account { private Person accountHolder; private int accountNumber; private double currentBalance; private String accountType; // 新增类型字段 public Account() {} public Account(Person accountHolder, int accountNumber, double currentBalance, String accountType) { this.accountHolder = accountHolder; this.accountNumber = accountNumber; this.currentBalance = currentBalance; this.accountType = accountType; } // 新增getter方法 public String getAccountType() { return accountType; } }
创建子类对象示例(解析CSV时):
// 当CSV中类型为"C"时,创建CheckingAccount并传入"Checkings" CheckingAccount checkingAcc = new CheckingAccount(personObj, 313003, 250002.15, "Checkings");
插入时直接获取类型:
accountPs.setString(4, accountHolder.getAccountType());
方案2:通过instanceof判断子类类型
若不想修改Account类,可在插入方法中判断对象所属子类,映射到对应类型字符串:
String accountType = ""; if (accountHolder instanceof CheckingAccount) { accountType = "Checkings"; } else if (accountHolder instanceof SavingsAccount) { accountType = "Savings"; } else if (accountHolder instanceof GoldSavingsAccount) { accountType = "Gold Savings"; } // 其他账户类型同理补充 accountPs.setString(4, accountType);
二、数据库无新增数据的修复
你的插入代码存在多处可能导致失败的问题,逐一修正:
1. 主键accountId错误赋值
代码中accountId固定为0+1=1,若数据库accountId是自增主键,手动赋值会引发主键冲突,或不符合自增逻辑。应改为让数据库自动生成主键:
// 修改SQL,移除accountId的插入(假设accountId为自增字段) String accountQuery = "insert into Account (accountNumber,currentBalance,type,personId) values (?,?,?,?);"; // 对应调整参数顺序 accountPs.setInt(1, accountHolder.getAccountNumber()); accountPs.setDouble(2, accountHolder.getCurrentBalance()); accountPs.setString(3, accountType); // 替换为实际类型值 accountPs.setInt(4, personId.getPersonId());
若必须手动生成accountId,需先查询当前最大ID再递增:
// 在插入前查询最大accountId try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery("SELECT MAX(accountId) FROM Account"); if (rs.next()) { accountId = rs.getInt(1); } accountId += 1; } // 再设置accountId参数 accountPs.setInt(1, accountId);
2. 资源管理与异常处理缺陷
原代码在try块中直接关闭资源,异常时可能导致资源泄漏,且无法明确插入是否成功。改用try-with-resources自动管理资源,并检查插入影响行数:
public static void DbAddAccount(Person person, Account accountHolder){ String accountQuery = "insert into Account (accountNumber,currentBalance,type,personId) values (?,?,?,?);"; try (Connection conn = DriverManager.getConnection(DatabaseInfo.URL, DatabaseInfo.USERNAME, DatabaseInfo.PASSWORD); PreparedStatement accountPs = conn.prepareStatement(accountQuery)) { // 设置参数... int affectedRows = accountPs.executeUpdate(); if (affectedRows == 0) { System.err.println("插入失败:未更新任何数据行"); } } catch (SQLException e) { System.err.println("数据库操作异常"); e.printStackTrace(); throw new RuntimeException("账户插入失败", e); } }
3. 事务提交问题
部分数据库默认关闭自动提交,需手动控制事务,确保插入成功后提交,异常时回滚:
public static void DbAddAccount(Person person, Account accountHolder){ String accountQuery = "insert into Account (accountNumber,currentBalance,type,personId) values (?,?,?,?);"; try (Connection conn = DriverManager.getConnection(DatabaseInfo.URL, DatabaseInfo.USERNAME, DatabaseInfo.PASSWORD)) { conn.setAutoCommit(false); // 关闭自动提交 try (PreparedStatement accountPs = conn.prepareStatement(accountQuery)) { // 设置参数... accountPs.executeUpdate(); conn.commit(); // 提交事务 System.out.println("账户插入成功"); } catch (SQLException e) { conn.rollback(); // 异常回滚 System.err.println("插入失败,已回滚事务"); e.printStackTrace(); throw new RuntimeException("账户插入失败", e); } } catch (SQLException e) { System.err.println("数据库连接失败"); e.printStackTrace(); throw new RuntimeException("数据库连接异常", e); } }
内容的提问来源于stack exchange,提问作者joshua
相关产品推荐
相关产品推荐

