You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import com.dao.AccountDao;
import com.javaBean.Account;
/**
* 实现了AccountDao接口该类封装了对账户数据进行CRUD创建、读取、更新、删除操作的数据库逻辑。
*/
public class Accountimpl implements AccountDao {
/**
* 从数据库连接工具类获取连接。
*
* @return 数据库连接对象
* @throws SQLException 连接失败时抛出
*/
// 使用JDBC工具类获取数据库连接
private Connection getConnection() throws SQLException {
return JDBCUtil.getConnection();
}
/**
* 验证用户ID和密码是否匹配。
*
* @param userid 用户ID
* @param password 用户密码
* @return 匹配的Account对象如果没有匹配的记录则返回null
* @throws SQLException 数据库操作过程中发生的异常
*/
@Override
public Account validateUser(String userid, String password) throws SQLException {
// 方法功能验证用户ID和密码是否匹配如果匹配则返回对应的Account对象否则返回null。
// 参数userid - 用户IDpassword - 用户密码。
// 返回与userid和password匹配的Account对象如果没有匹配项则返回null。
// 异常可能会抛出SQLException表示数据库访问过程中发生错误。
Account account = null;// 初始化Account对象为null准备存储查询结果。
Connection conn = null;// 数据库连接对象。
PreparedStatement prestm = null; // 预编译的SQL语句对象用于执行查询。
ResultSet rs = null;// 结果集对象,用于存放查询结果。
try {
// 1. 获取数据库连接。
conn = getConnection();
// 2. 构造SQL查询语句用于根据用户ID和密码验证用户。
// 使用预编译语句PreparedStatement以防止SQL注入攻击
String sql = "SELECT * FROM elsfk.wlw20 WHERE userid=? AND password=?";
// 3. 创建PreparedStatement实例并预编译SQL语句。
prestm = conn.prepareStatement(sql);
// 4. 为预编译语句的参数赋值。
prestm.setString(1, userid); // 设置第一个问号的值为userid
prestm.setString(2, password); // 设置第二个问号的值为password
// 5. 执行查询语句。
rs = prestm.executeQuery();
// 6. 判断查询结果是否有数据。
if (rs.next()) {
// 7. 如果查询到匹配的记录创建Account对象并填充数据。
account = new Account();
account.setuserid(rs.getString("userid")); // 假设Account类有set_userid方法
account.setpassword(rs.getString("password")); // 同上假设存在set_password方法
// 根据实际表结构,可继续设置其他属性
}
} catch (SQLException e) {
// 8. 捕获并打印SQLException用于调试和问题追踪。
// 再次抛出异常,允许上层调用者处理此异常。
e.printStackTrace();
throw e; // 重新抛出异常,以便调用者可以处理
} finally {
// 9. 确保在方法结束前所有数据库资源ResultSet、PreparedStatement、Connection被关闭。
closeResources(rs, prestm, conn);
}
// 10. 返回查询结果。如果有匹配项则返回Account对象否则返回null。
return account;
}
// 其他方法的实现与validateUser相似增加了详细的注释说明每一步操作的目的和处理逻辑
/**
* 通用资源关闭方法确保ResultSet、PreparedStatement、Connection等资源被正确关闭。
*
* @param rs 结果集对象
* @param stmt PreparedStatement对象
* @param conn 数据库连接对象
*/
/**
* 根据用户ID查找账户信息。
*
* @param userid 用户ID
* @return 查找到的Account对象如果未找到则返回null
*/
@Override
public Account findByUserid(String userid) {
// 方法功能根据用户ID从数据库中查找对应的账户信息。
// 参数userid - 需要查询的用户ID。
// 返回与userid匹配的Account对象如果没有找到匹配的记录则返回null。
Account account = null;// 初始化Account对象为null用于存储查询结果。
Connection conn = null;// 数据库连接对象。
PreparedStatement prestm = null;// 预编译的SQL语句对象用于执行查询
ResultSet rs = null;// 结果集对象,用于存放查询结果。
try {
// 获取数据库连接。
conn = getConnection();
// 准备SQL查询语句目的是根据用户ID查找账户信息。
String sql = "SELECT * FROM elsfk.wlw20 WHERE userid=?";
// 创建PreparedStatement实例预编译SQL语句以防止SQL注入攻击。
prestm = conn.prepareStatement(sql);
// 设置SQL语句中的第一个参数占位符为传入的userid。
prestm.setString(1, userid);
// 执行查询语句。
rs = prestm.executeQuery();
// 如果查询结果集中有下一条记录即找到了匹配的用户ID
if (rs.next()) {
account = new Account();// 从结果集中获取用户ID并设置到Account对象中。
account.setuserid(rs.getString("userid"));// 从结果集中获取密码并设置到Account对象中
account.setpassword(rs.getString("password"));// 注释提示此处可根据实际需要继续设置Account对象的其他属性。
// 设置其他属性...
}
} catch (SQLException e) {
// 捕获并打印SQL异常用于调试和问题追踪。
e.printStackTrace();
// 注意:在生产环境中,除了打印堆栈跟踪,还应考虑更合理的异常处理机制,如记录日志、抛出自定义异常等。
} finally {
// 确保数据库资源ResultSet、PreparedStatement、Connection在方法结束前被关闭。
// 即便在try块中发生了异常finally块中的代码也会被执行。
closeResources(rs, prestm, conn);
}
// 返回查询结果。如果有匹配的记录则返回填充了数据的Account对象否则返回null。
return account;
}
/**
* 添加一个新的账户到数据库。
*
* @param account 要添加的Account对象
*/
@Override
public void addAccount(Account account) {
// 方法功能:向数据库中添加一个新的账户信息。
// 参数account - 要添加的Account对象应包含至少userid和password属性。
Connection conn = null;// 数据库连接对象。
PreparedStatement prestm = null;// 预编译的SQL语句对象用于执行插入操作。
try {// 1. 通过getConnection()方法获取数据库连接。
conn = getConnection();
// 2. 准备SQL插入语句用于向表elsfk.wlw20中插入新记录插入字段为userid和password。
String sql = "INSERT INTO elsfk.wlw20 (userid, password) VALUES (?, ?)";
// 3. 创建PreparedStatement实例预编译SQL语句以防止SQL注入攻击。
prestm = conn.prepareStatement(sql);
// 4. 为预编译语句的占位符设置实际值。
//设置第一个问号为Account对象中的userid。
prestm.setString(1, account.getuserid());
//设置第二个问号为Account对象中的password
prestm.setString(2, account.getpassword());
// 5. 执行插入操作将预编译SQL语句中的数据插入到数据库中。
prestm.executeUpdate(); // 执行插入操作
} catch (SQLException e) {
// 6. 捕获并打印SQLException用于调试和问题追踪。
// 实际应用中,可能需要更细致的错误处理,如记录日志、事务回滚等。
e.printStackTrace();
} finally {
// 7. 在finally块中确保数据库资源被关闭即使在try-catch中发生异常也是如此。
// 注意这里传入的ResultSet为null因为addAccount操作不涉及查询操作。
closeResources(null, prestm, conn);
}
}
/**
* 查询并返回数据库中的所有账户信息。
*
* @return 包含所有账户的ArrayList集合
*/
@Override
public ArrayList<Account> findAll() {
// 方法功能从数据库中检索所有账户信息并以ArrayList形式返回所有Account对象列表。
ArrayList<Account> accounts = new ArrayList<>();// 初始化一个ArrayList用于存储查询到的所有Account对象。
Connection conn = null; // 数据库连接对象。
PreparedStatement prestm = null; // 预编译的SQL语句对象用于执行查询操作。
ResultSet rs = null;// 结果集对象,用于存放查询结果。
try {
// 1. 通过getConnection()方法获取数据库连接。
conn = getConnection();
// 2. 构建SQL查询语句用于从表elsfk.wlw20中选取所有记录。
String sql = "SELECT * FROM elsfk.wlw20";
// 3. 创建PreparedStatement实例预编译SQL查询语句提高执行效率并防止SQL注入。
prestm = conn.prepareStatement(sql);
// 4. 执行查询操作,获取结果集。
rs = prestm.executeQuery();
// 5. 遍历结果集对于每一行数据创建Account对象并填充数据然后将其添加到accounts列表中。
while (rs.next()) {
Account acc = new Account();
// 获取当前行的userid字段值并设置给Account对象。
acc.setuserid(rs.getString("userid"));
// 获取当前行的password字段值并设置给Account对象。
acc.setpassword(rs.getString("password"));
// 注释提示此处可根据实际表结构继续设置Account对象的其他属性
accounts.add(acc); // 将填充好的Account对象添加到列表中。
}
} catch (SQLException e) {
// 6. 捕获并打印SQLException用于调试和问题追踪。
e.printStackTrace();
} finally {
closeResources(rs, prestm, conn);
// 7. 确保在方法结束前数据库资源ResultSet、PreparedStatement、Connection被正确关闭。
}
// 8. 返回包含所有账户信息的ArrayList。
return accounts;
}
/**
* 更新指定账户的密码信息。
*
* @param account 包含待更新账户信息的对象
* @return 受影响的行数成功更新则返回1否则为0
*/
@Override
public int updateAccount(Account account) {
// 方法功能根据Account对象更新数据库中对应用户的密码信息。
// 返回值受影响的行数一般情况下如果更新成功则返回1表示有一行数据被修改
// 如果没有匹配的记录则返回0。
int rowsAffected = 0;// 初始化受影响的行数为0用于记录更新操作的结果。
Connection conn = null; // 数据库连接对象。
PreparedStatement prestm = null;// 预编译的SQL语句对象用于执行更新操作。
try {
// 1. 获取数据库连接。
conn = getConnection();
// 2. 构造SQL更新语句用于根据userid更新账户的password。
String sql = "UPDATE elsfk.wlw20 SET password=? WHERE userid=?";
// 3. 创建PreparedStatement实例预编译SQL更新语句提高执行效率并防止SQL注入。
prestm = conn.prepareStatement(sql);
// 4. 设置预编译语句的参数。
// 第一个问号处设置为Account对象的password。
prestm.setString(1, account.getpassword());
// 第二个问号处设置为Account对象的userid作为更新条件。
prestm.setString(2, account.getuserid());
// 5. 执行更新操作并通过executeUpdate()方法获取受影响的行数。
rowsAffected = prestm.executeUpdate(); // 执行更新操作并获取影响的行数
} catch (SQLException e) {
// 6. 捕获并打印SQLException用于调试和问题追踪。
e.printStackTrace();
} finally {
// 7. 确保数据库资源PreparedStatement、Connection被正确关闭即便在异常情况下。
closeResources(null, prestm, conn);
}
// 8. 返回受影响的行数,供调用者判断更新操作是否成功。
return rowsAffected;
}
/**
* 根据用户ID删除账户。
*
* @param userid 要删除账户的用户ID
* @return 受影响的行数成功删除则返回1否则为0
*/
@Override
public int deleteAccount(String userid) {
// 方法功能根据用户ID从数据库中删除对应的账户记录。
// 参数userid - 需要删除的账户的用户ID。
// 返回值受影响的行数如果删除成功通常返回1若无匹配记录则返回0。
int rowsAffected = 0;// 初始化受影响的行数变量,用于记录删除操作的影响范围。
Connection conn = null;// 数据库连接对象。
PreparedStatement prestm = null;// 预编译的SQL语句对象用于执行删除操作。
try {
// 1. 通过getConnection()方法获取数据库连接。
conn = getConnection();
// 2. 构造SQL删除语句用于根据userid删除表elsfk.wlw20中的记录。
String sql = "DELETE FROM elsfk.wlw20 WHERE userid=?";
// 3. 创建PreparedStatement实例预编译SQL删除语句以提高执行效率并防止SQL注入。
prestm = conn.prepareStatement(sql);
// 4. 设置预编译语句中的参数即将userid值绑定到SQL中的第一个问号处。
prestm.setString(1, userid);
// 5. 执行删除操作并通过executeUpdate()方法获取受影响的行数,即删除了多少行数据。
rowsAffected = prestm.executeUpdate(); // 执行删除操作并获取影响的行数
} catch (SQLException e) {
// 6. 捕获并打印SQLException用于调试和问题追踪
e.printStackTrace();
} finally {
// 7. 确保在方法结束前数据库资源PreparedStatement、Connection被正确关闭。
closeResources(null, prestm, conn);
}
// 8. 返回受影响的行数,调用者可以通过这个值判断删除操作是否成功。
return rowsAffected;
}
/**
* 关闭数据库操作所使用的资源包括ResultSet、PreparedStatement和Connection。
*
* @param rs 结果集对象
* @param prestm 预编译的SQL语句对象
* @param conn 数据库连接对象
*/
private void closeResources(ResultSet rs, PreparedStatement prestm, Connection conn) {
// 方法功能关闭数据库操作中使用的资源包括ResultSet、PreparedStatement和Connection。
// 目的:确保每次数据库操作后,占用的资源能够被及时释放,避免资源泄露。
try {
// 1. 如果ResultSet不为null尝试关闭它。ResultSet用于存储查询结果占用内存资源。
if (rs != null) rs.close();
// 2. 如果PreparedStatement不为null尝试关闭它。PreparedStatement用于执行预编译的SQL语句。
if (prestm != null) prestm.close();
// 3. 如果Connection不为null尝试关闭数据库连接。Connection是数据库操作的基础是非常宝贵的资源。
if (conn != null) conn.close();
} catch (SQLException e) {
// 4. 在关闭资源过程中如果遇到SQLException如资源已被关闭或其他问题打印堆栈跟踪。
e.printStackTrace();
}
}
}