首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JDBC 入门核心指南:四大对象、PreparedStatement 防注入与标准操作模板

     編輯:Java 綜合教學

JDBC 四大核心对象

  1. DriverManager:驱动管理,加载驱动、获取连接。
  2. Connection:数据库连接会话,事务管理、创建 Statement。
  3. Statement / PreparedStatement:SQL 执行载体。
  4. ResultSet:结果集游标,遍历查询结果。

1. 驱动加载:推荐方式

// 不推荐:DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 问题:驱动注册两次、强依赖具体驱动类

// 推荐:反射加载,解耦驱动实现
Class.forName("com.mysql.jdbc.Driver"); // JDBC 4.0+ 甚至可省略(SPI 自动加载)

2. 获取连接

// 方式一:URL + 用户名/密码
String url = "jdbc:mysql://localhost:3306/day06?useSSL=false&serverTimezone=UTC";
Connection conn = DriverManager.getConnection(url, "root", "root");

// 方式二:Properties 对象(适配多数据源配置文件)
Properties props = new Properties();
props.setProperty("user", "root");
props.setProperty("password", "root");
Connection conn = DriverManager.getConnection(url, props);

// 常见数据库 URL 格式
// MySQL: jdbc:mysql://host:port/dbname
// Oracle: jdbc:oracle:thin:@host:port:sid

3. Statement vs PreparedStatement

结论:生产环境 99% 场景使用 PreparedStatement。

PreparedStatement 使用模板

// 查询
String sql = "SELECT * FROM users WHERE username=? AND pwd=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "tom");
ps.setString(2, "123");
ResultSet rs = ps.executeQuery();

// 更新/删除/插入
String sql = "DELETE FROM users WHERE id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 5);
int rows = ps.executeUpdate(); // 返回影响行数

4. ResultSet 结果集遍历

while (rs.next()) { // 游标下移,返回是否有数据
    User u = new User();
    u.setId(rs.getInt("id"));        // 推荐用列名,可读性强
    u.setName(rs.getString("name"));
    u.setBirthday(rs.getDate("birthday"));
    list.add(u);
}

5. 资源关闭:标准 finally 模式(JDK 7+ try-with-resources 更优)

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
    conn = DriverManager.getConnection(url, user, pwd);
    ps = conn.prepareStatement(sql);
    // ... 设置参数、执行 ...
    rs = ps.executeQuery();
    // ... 处理结果 ...
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    // 逆序关闭,单独 try-catch 保证都能关闭
    if (rs != null) try { rs.close(); } catch (SQLException e) { e.printStackTrace(); }
    if (ps != null) try { ps.close(); } catch (SQLException e) { e.printStackTrace(); }
    if (conn != null) try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}

完整 CRUD 示例

public class JdbcDemo {
    static final String URL = "jdbc:mysql:///day06?useSSL=false";
    static final String USER = "root";
    static final String PWD = "abc";

    public static void main(String[] args) {
        String sql = "SELECT * FROM users WHERE name=? AND pwd=?";
        try (Connection conn = DriverManager.getConnection(URL, USER, PWD);
             PreparedStatement ps = conn.prepareStatement(sql)) {
            
            ps.setString(1, "tom");
            ps.setString(2, "123");
            
            try (ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                    System.out.println(rs.getInt("id") + " " + rs.getString("name"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

总结

  • 驱动加载用 Class.forName 或依赖 SPI。
  • **永远使用 PreparedStatement** 防注入、提性能。
  • 资源关闭用 try-with-resources(JDK 7+)保证不泄漏。
  • 事务控制:conn.setAutoCommit(false) → 执行多条 SQL → conn.commit()/rollback()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性StatementPreparedStatement
SQL 注入风险高(拼接字符串)**免疫**(预编译+参数绑定)
性能每次编译预编译一次,多次执行高效
参数设置不支持setXxx(index, val) 类型安全
批处理支持支持 addBatch()/executeBatch()