JDBC之PreparedStatement的用法

PreparedStatement 是一个特殊的Statement对象,如果我们只是来查询或者更新数据的话,最好用PreparedStatement代替Statement,因为它有以下优点:

1、简化Statement中的操作
2、提高执行语句的性能
3、可读性和可维护性更好
4、安全性更好。
5、使用PreparedStatement能够预防SQL注入攻击,所谓SQL注入,指的是通过把SQL命令插入到Web表单提交或者输入域名或者页面请求的查询字符串,最终达到欺骗服务器,达到执行恶意SQL命令的目的。注入只对SQL语句的编译过程有破坏作用,而执行阶段只是把输入串作为数据处理,不再需要对SQL语句进行解析,因此也就避免了类似select * from user where name='aa' and password='bb' or 1=1的sql注入问题的发生。

入门使用

创建PreparedStatement

创建一个PreparedStatement PreparedStatement对象的创建也同样离不开 DriverManger.getConnect()对象,因为它也是建立在连接到数据库之上的操作。

      /** 1. init PreparedStatement*/
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/db_test?useSSL=false";
        String username = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, username, password);
        String sql = "update user set username=? where id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

设置入参

往PreparedStatement里写入参数

看上面那个sql 字符串,中间有几个?,它在这里有点占位符的意思,然后我们可以通过PreparedStatement的setString(),等方法来给占位符进行赋值,使得sql语句变得灵活。

        /** 2. prepare param*/
        preparedStatement.setString(1, "feifz");
        preparedStatement.setInt(2, 2);

参数中的第一个参数分别是1和2,它代表的是第几个问号的位置。如果sql语句中只有一个问号,那就不用声明这个参数。

执行更新
 /** 3. execute update*/
  int result = preparedStatement.executeUpdate();
  System.out.printf("更新记录数:"+result+"\n");

结果:
更新记录数:1
执行查询

如果是执行查询数据库的话,也像Statement对象执行excuteQuery()一样返回一个ResultSet结果集。

/** 4. execute select*/
String sql2 = "select * from user";
        ResultSet resultSet = preparedStatement.executeQuery(sql2);
        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String username = resultSet.getString("username");
            String dept = resultSet.getString("dept");
            System.out.println("id:"+id +"username->"+ username + ",dept-> " + dept );
        }

执行结果:
id:1username->Fant.J,dept-> 测试部
id:2username->feifz,dept-> 研发部
id:3username->xixi,dept-> 产品部
id:4username->hah,dept-> 集成部
id:5username->zeze,dept-> 研发部
完整代码
package com.github.feifuzeng.middleware.mybatis.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class PrepareStatementSimpleDemo {

    public static void main(String[] args) throws Exception {

        /** 1. init PreparedStatement*/
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/db_test?useSSL=false";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        String sql = "update user set username=? where id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        /** 2. prepare param*/
        preparedStatement.setString(1, "feifz");
        preparedStatement.setInt(2, 2);

        /** 3. execute update*/
        int result = preparedStatement.executeUpdate();
        System.out.printf("更新记录数:"+result+"\n");

        /** 4. execute select*/

        String sql2 = "select * from user";
        ResultSet resultSet = preparedStatement.executeQuery(sql2);
        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String username = resultSet.getString("username");
            String dept = resultSet.getString("dept");
            System.out.println("id:"+id +"username->"+ username + ",dept-> " + dept );
        }


    }
}

第二个模板:

一、用法:

PreparedStatement是Statement的子接口,Statement在使用的过程中,直接拼写SQL是很容易出错的且难用的,PreparedStatement带有模版的思想,减少了出错的机率。

1、写sql模版,并和PreparedStatement绑定

String sqlsqlTemplate= “insert emp VALUE (?,?,?)”;
PreparedStatement pstmt = con.prepareStatement(sqlsqlTemplate);

2、依次设置模版中??所带表的值

pstmt.setInt(1,9); //第一个参数,表示设置第几个值
pstmt.setString (2,“yangli”);
pstmt.setInt(3,30);

3、执行
          String driver = "com.mysql.jdbc.Driver";
          String url = "jdbc:mysql://localhost:3306/test";
          String user  = "root";
          String password = "root";
        try {
            Class.forName(driver);
            con = DriverManager.getConnection(url,user,password);
            if(!con.isClosed())
                    String sqlTemplate = "insert emp VALUE (?,?,?)";
                    PreparedStatement pstmt = con.prepareStatement(sqlTemplate);
                    pstmt.setInt(1,9); //插入第n个数
                    pstmt.setString (2,"yangli");
                    pstmt.setInt(3,30);
                    int  rs = pstmt.executeUpdate();
                  pstmt.clase();
                  con.close();
        } catch (ClassNotFoundException e) {
            System.out.println("数据库数据异常"+e.toString());
            e.printStackTrace();
        } catch (SQLException e) {
            System.out.println("数据库数据异常"+e.toString());
            e.printStackTrace();
        }finally {
            System.out.println("数据库数据成功获取");
        }
二、和Statement的区别
    1、PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高;

    2、PreparedStatement和sql模板绑定,最后执行的时候,不再有sql语句
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值