博客
关于我
26-【连接池和JdbcTemplate-笔记】
阅读量:521 次
发布时间:2019-03-08

本文共 7127 字,大约阅读时间需要 23 分钟。

连接池和JdbcTemplate

PreparedSatement预编译对象

目标

理解PreparedSatement的作用,掌握其使用步骤,避免SQL注入问题。

讲解

SQL注入问题

在之前的 JDBC 实现登录案例中,我们发现输入特定密码后可以登录成功。问题分析如下:

// 代码中的SQL语句"SELECT * FROM user WHERE name='" + name + "' AND password='" + password + "';";// 用户输入后变为"SELECT * FROM user WHERE name='hehe' AND password='a' or '1'='1';";

用户输入的内容直接被拼接到 SQL 语句中,导致 SQL 注入问题。

PreparedSatement的执行原理

数据库不会直接执行字符串形式的 SQL 语句,而是需要预编译后的 SQL 语句执行。PreparedSatement 类的作用是:

  • 预编译 SQL 语句。
  • 通过设置参数多次执行预编译后的 SQL 语句。
  • PreparedSatement 的好处

  • 提高效率:预编译后的 SQL 语句可以多次重复使用,减少数据库的编译开销。
  • 安全性:防止 SQL 注入问题,保护数据库免受恶意代码攻击。
  • 可读性:代码中使用 ? 占位,提升 SQL 语句的可读性。
  • 小结

    PreparedSatement 的使用步骤:

  • 编写 SQL 语句,使用 ? 占位参数。
  • 获取 PreparedStatement 对象。
  • 设置实际参数。
  • 执行 SQL 语句。
  • 关闭资源。
  • PreparedSatement 用于执行增删改查操作,执行增删改时使用 executeUpdate(),执行查询时使用 executeQuery()


    PreparedSatement 实现登录案例

    目标

    理解如何使用 PreparedSatement 改写登录案例,防止 SQL 注入问题。

    讲解

    使用步骤

  • 编写 SQL 语句,使用 ? 占位。
  • 获取 PreparedStatement 对象。
  • 设置用户输入的参数值。
  • 执行 SQL 查询。
  • 检查结果并关闭资源。
  • 案例代码

    public class Demo02 {    public static void main(String[] args) throws Exception {        Scanner sc = new Scanner(System.in);        System.out.println("请输入账号: ");        String name = sc.nextLine();        System.out.println("请输入密码: ");        String password = sc.nextLine();        Connection conn = JDBCUtils.getConnection();        String sql = "SELECT * FROM user WHERE name=? AND password=?";        PreparedStatement pstmt = conn.prepareStatement(sql);        pstmt.setString(1, name);        pstmt.setString(2, password);        ResultSet rs = pstmt.executeQuery();        if (rs.next()) {            System.out.println("登录成功:" + rs.getString("name"));        } else {            System.out.println("登录失败!");        }        JDBCUtils.close(conn, pstmt, rs);    }}

    小结

    PreparedSatement 的使用步骤:

  • 编写 SQL 语句,使用 ? 占位。
  • 获取 PreparedStatement 对象。
  • 设置参数。
  • 执行 SQL。
  • 处理结果。
  • 关闭资源。

  • PreparedSatement 实现增删改查

    目标

    掌握 PreparedSatement 对于增删改查操作的实现方法。

    讲解

    增加数据

    向 Employee 表中添加记录。

    public class Demo01 {    public static void main(String[] args) throws SQLException {        Connection conn = JDBCUtils.getConnection();        String sql = "INSERT INTO employee (name, age, address) VALUES (?, ?, ?)";        PreparedStatement preSate = conn.prepareStatement(sql);        // 插入数据        preSate.setString(1, "张三");        preSate.setInt(2, 30);        preSate.setString(3, "北京");        int i1 = preSate.executeUpdate();        System.out.println("插入数据:" + i1);        // 关闭资源        JDBCUtils.close(conn, preSate);    }}

    修改数据

    更新 Employee 表中的记录。

    public class Demo01 {    public static void main(String[] args) throws SQLException {        Connection conn = JDBCUtils.getConnection();        String sql = "UPDATE employee SET address = ? WHERE id = ?";        PreparedStatement preSate = conn.prepareStatement(sql);        // 更新数据        preSate.setString(1, "上海");        preSate.setInt(2, 1);        int i1 = preSate.executeUpdate();        System.out.println("更新数据:" + i1);        // 关闭资源        JDBCUtils.close(conn, preSate);    }}

    删除数据

    从 Employee 表中删除指定记录。

    public class Demo01 {    public static void main(String[] args) throws SQLException {        Connection conn = JDBCUtils.getConnection();        String sql = "DELETE FROM employee WHERE id = ?";        PreparedStatement preSate = conn.prepareStatement(sql);        // 删除数据        preSate.setInt(1, 2);        int i1 = preSate.executeUpdate();        System.out.println("删除数据:" + i1);        // 关闭资源        JDBCUtils.close(conn, preSate);    }}

    查询数据

    查询 Employee 表中所有记录。

    public class Demo01 {    public static void main(String[] args) throws SQLException {        Connection conn = JDBCUtils.getConnection();        String sql = "SELECT * FROM employee";        PreparedStatement preSate = conn.prepareStatement(sql);        // 执行查询        ResultSet rs = preSate.executeQuery();        while (rs.next()) {            System.out.println("id: " + rs.getInt("id") +                             ", name: " + rs.getString("name") +                            ", age: " + rs.getInt("age") +                            ", address: " + rs.getString("address"));        }        // 关闭资源        JDBCUtils.close(conn, preSate, rs);    }}

    小结

    PreparedSatement 的使用步骤:

  • 编写 SQL 语句,使用 ? 占位。
  • 获取 PreparedStatement 对象。
  • 设置参数。
  • 执行 SQL。
  • 处理结果。
  • 关闭资源。

  • Druid 连接池

    目标

    掌握 Druid 连接池的使用方法,了解其优势。

    讲解

    Druid 简介

    Druid 是阿里巴巴开源的数据库连接池,具有高性能、高可用性和丰富的监控功能。

    Druid 常用配置参数

    参数名 说明
    jdbcUrl 数据库连接 URL
    username 数据库用户名
    password 数据库密码
    driverClass 驱动类名
    initialSize 连接池初始连接数量
    maxActive 连接池最大连接数
    maxWait 获取连接的最大等待时间
    checkoutTimeout 获取连接的超时时间

    Druid 连接池配置

    通过 properties 文件配置 Druid 参数。

    driverClassName=com.mysql.jdbc.DriverjdbcUrl=jdbc:mysql://localhost:3306/day05username=rootpassword=rootinitialSize=5maxActive=10maxWait=3000

    使用步骤

  • 导入 Druid jar 包。
  • 创建 properties 文件,配置数据库参数。
  • 创建 Druid 连接池对象。
  • 获取连接。
  • 使用连接执行 SQL。
  • 关闭资源。
  • 案例代码

    public class Demo04 {    public static void main(String[] args) throws Exception {        InputStream is = Demo04.class.getResourceAsStream("/druid.properties");        Properties pp = new Properties();        pp.load(is);        DataSource ds = DruidDataSourceFactory.createDataSource(pp);        Connection conn = ds.getConnection();        String sql = "INSERT INTO student VALUES (NULL, ?, ?, ?)";        PreparedStatement pstmt = conn.prepareStatement(sql);        // 插入数据        pstmt.setString(1, "张三");        pstmt.setInt(2, 35);        pstmt.setDouble(3, 99.5);        int i = pstmt.executeUpdate();        System.out.println("影响的行数:" + i);        // 关闭资源        pstmt.close();        conn.close();    }}

    小结

    Druid 连接池的优势:

  • 提高数据库资源利用率。
  • 提供连接池监控功能。
  • 支持多种数据库厂商。
  • 高性能和稳定性。

  • JdbcTemplate 简化 JDBC 操作

    目标

    掌握 JdbcTemplate 的使用方法,了解其与 JDBC 的区别。

    讲解

    JdbcTemplate 简化 JDBC

    JdbcTemplate 对 JDBC 进行了封装,简化了资源管理,避免了手动处理 Statement 和 Connection。

    JdbcTemplate 配置连接池

    通过 DataSource 对 JdbcTemplate 进行配置,JdbcTemplate 会自动管理数据库连接。

    JdbcTemplate 方法分类

  • execute:执行 DDL、DML 语句。
  • update:执行 INSERT、UPDATE、DELETE 语句。
  • queryForObject:查询单个数据。
  • queryForMap:查询多个字段返回 Map 对象。
  • queryForList:查询多条记录返回 List 集合。
  • query:自定义结果映射。
  • 案例代码

    创建表

    public class Demo04 {    public static void main(String[] args) throws Exception {        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());        String sql = "CREATE TABLE product (pid INT PRIMARY KEY AUTO_INCREMENT, pname VARCHAR(20), price DOUBLE)";        jdbcTemplate.execute(sql);    }}

    插入数据

    public class Demo05 {    public static void main(String[] args) throws Exception {        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());        String sql = "INSERT INTO product VALUES (NULL, ?, ?)";        jdbcTemplate.update(sql, "iPhone3GS", 3333);        // 其他插入操作...    }}

    查询数据

    public class Demo05 {    public static void main(String[] args) throws Exception {        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());        String sql = "SELECT * FROM product";        List
    > list = jdbcTemplate.queryForList(sql); list.forEach(map -> { System.out.println(map); }); }}

    小结

    JdbcTemplate 的优势:

  • 简化了 JDBC 操作。
  • 自动管理数据库资源。
  • 提供丰富的查询方法。
  • 支持参数化 SQL 语句,防止 SQL 注入。

  • 总结

    通过学习 PreparedSatement 的使用方法,掌握了如何避免 SQL 注入问题;通过了解连接池的原理,认识到连接池在数据库资源管理中的重要作用;最后,通过 JdbcTemplate 的简化 API,体验了现代化的 JDBC 开发方式。

    转载地址:http://syuiz.baihongyu.com/

    你可能感兴趣的文章