在 Java 中封装数据库操作是一个常见的需求,可以通过以下方法实现高效且可维护的代码结构。以下是一个 基于 JDBC 的封装示例,并附上最佳实践建议:
1. 封装数据库操作的核心思想隐藏实现细节:将 Connection、Statement、ResultSet 等对象的创建和释放封装在内部。统一异常处理:统一处理 SQLException,避免重复代码。使用接口与实现分离:定义 DAO(Data Access Object)接口,分离业务逻辑与数据库操作。2. 基础封装示例步骤 1:创建数据库连接工具类代码语言:javascript复制import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
private static final String URL = "jdbc:mysql://localhost:3306/your_database";
private static final String USER = "root";
private static final String PASSWORD = "password";
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}步骤 2:定义 DAO 接口代码语言:javascript复制public interface UserDao {
void addUser(User user);
User getUserById(int id);
void updateUser(User user);
void deleteUser(int id);
}步骤 3:实现 DAO 类(使用 PreparedStatement 防止 SQL 注)代码语言:javascript复制import java.sql.*;
public class UserDaoImpl implements UserDao {
@Override
public void addUser(User user) {
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getEmail());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public User getUserById(int id) {
String sql = "SELECT * FROM users WHERE id = ?";
User user = null;
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
}
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
// 其他方法类似,省略...
}3. 高级封装(使用模板模式)通过 JdbcTemplate 简化重复代码(类似 Spring JDBC 的思路):
代码语言:javascript复制import java.sql.*;
public class JdbcTemplate {
public static int update(String sql, Object... params) {
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
return pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
public static
try (Connection conn = DBUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
ResultSet rs = pstmt.executeQuery();
return handler.handle(rs);
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
}
// 定义结果集处理器接口
public interface ResultSetHandler
T handle(ResultSet rs) throws SQLException;
}
// 使用示例
User user = JdbcTemplate.query(
"SELECT * FROM users WHERE id = ?",
rs -> {
if (rs.next()) {
User u = new User();
u.setId(rs.getInt("id"));
u.setName(rs.getString("name"));
return u;
}
return null;
},
1
);4. 使用 ORM 框架(推荐)Hibernate:基于 JPA 规范的全自动 ORM。MyBatis:半自动化的 SQL 映射框架,灵活性更高。MyBatis 示例定义 Mapper 接口:代码语言:javascript复制public interface UserMapper {
@Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
void insertUser(User user);
@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById(int id);
}通过 SqlSession 调用:代码语言:javascript复制try (SqlSession session = sqlSessionFactory.openSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.getUserById(1);
}5. 最佳实践使用连接池(如 HikariCP、Druid)替代原生 DriverManager。事务管理:通过 Connection 的 setAutoCommit(false) 和 commit()/rollback() 实现。避免硬编码 SQL:将 SQL 语句提取到 XML 或 Properties 文件中。使用 Lombok 或 Record 简化实体类代码。通过上述方法,可以显著提高代码的可维护性和安全性。如果需要更详细的实现或特定框架的示例,请告诉我!