JDBC(3):PreparedStatement接口

参考资料http://study.163.com/course/courseLearn.htm?courseId=1455026#/learn/video?lessonId=1821070&courseId=1455026

一、Statement接口问题

虽然在JDBC里面提供有Statement接口,但实际来讲,Statement接口存在严重操作缺陷,是不会在工作中使用的
范例:观察Statement接口问题

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;



public class TestDemo {
    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";
    private static final String USER = "scott";
    private static final String PASSWORD = "tiger";
    public static void main(String[] args) throws Exception {
        String name = "Mr'SMITH";
        String birthday = "1998-10-10";
        int age = 18;
        String note = "是个外国人";
        //第一步:加载数据库驱动程序,此时不需要实例化,因为会由容器自己负责管理
        Class.forName(DBDRIVER);
        //第二步:连接数据库
        Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
        //第三步

        Statement stmt = conn.createStatement();
        String sql = "INSERT INTO member(mid,name,birthday,age,note) VALUES "
                + " (myseq.nextval,'"+name+"', TO_DATE('"+birthday+"','yyyy-mm-dd'),"
                + age + ", '" + note+"')";
        System.out.println(sql);
        int len = stmt.executeUpdate(sql);
        System.out.println("影响的数据行:" + len);
        //在编写SQL语句的过程里,如果太长的时候需要换行,那么应当前后加上空格,避免出错

        conn.close();

    }

}

由于一般情况,基本信息 都是 分开输入的,以上代码将其最后在组成SQL语句字符串。
但上面的程序运行结果是会报错的

INSERT INTO member(mid,name,birthday,age,note) VALUES  (myseq.nextval,'Mr'SMITH', TO_DATE('1998-10-10','yyyy-mm-dd'),18, '是个外国人')
Exception in thread "main" java.sql.SQLSyntaxErrorException: ORA-00917: 缺失逗号

出错的原因就是用户名包含了一个 ‘ 号。
Statement如果要灵活的应用,那么就必须采用拼凑字符串的形式完成,可是如果输入的内容有“ ‘ ” ,那么整个SQL就会出错了,也就是说Statement的执行模式不适合处理一些敏感字符。所以不能使用Statement接口。

PreparedStatement操作

Statement执行的关键性问题是在于它需要一个完整的字符串来定义要使用的SQL语句,所以这就导致在使用中要进行大量的字SQL拼凑,而PreStatement与Statement不同的地方在于,它执行的是一个完整的具备特殊占位标记的SQL语句,并且可以动态地设置所需要的数据。

PreparedStatement属于Statement的子接口,但是如果要取得这个字接口的实例化对象,依然要使用Connection接口提供的方法。

* public PreparedStatement prepareStatement(String sql) throws SQLException*
(注意方法名不含“d”)
里面需传入一个SQL语句,这个SQL是一个具备特殊标记的完整SQL,但此时没有内容。需要一系列的setXXX()方法用于为所使用的标记设置具体内容,而后可以进行:
更新操作:int executeUpdate() throws SQLException
查询操作:ResultSet executeQuery() throws SQLException
以上方法不用接收SQL语句
当使用了PreStatement接口操作时最要注意的是里面的setDate()方法,因为此方法使用的是java.sql.Date 而不再是java.util.Date.
在java.util.Date 类下有三个子类都是在java.sql的包中:
java.sql.Date:描述的是日期;
java.sql.Time:描述的是时间:
java.sql.Timestamp:描述的是时间戳(日期时间)。
如果要将java.util.Date变为java.sql.Date(Time、Timestamp)只能够依靠long完成。
java.util.Date:public long getTime(),可以将Date变为long
java.sql.Date:public Date(long date),将long变为sql.Date。

范例:数据增加

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Date;



public class TestDemo {
    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";
    private static final String USER = "scott";
    private static final String PASSWORD = "tiger";
    public static void main(String[] args) throws Exception {
        String name = "Mr'SMITH";
        Date birthday = new Date();
        int age = 18;
        String note = "是个外国人";
        //第一步:加载数据库驱动程序,此时不需要实例化,因为会由容器自己负责管理
        Class.forName(DBDRIVER);
        //第二步:连接数据库
        Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
        //第三步:进行数据库的操作,执行完整的SQL
        String sql = " INSERT INTO member(mid, name, brithday, age, note) VALUES "
                + " (myseq.nextval,?, ?, ? ,?)"; 
        PreparedStatement stmt = conn.prepareStatement(sql);
        stmt.setString(1, name);
        stmt.setDate(2, new java.sql.Date(birthday.getTime()));
        stmt.setInt(3, age);
        stmt.setString(4, note);

        System.out.println(sql);
        int len = stmt.executeUpdate();
        System.out.println("影响的数据行:" + len);
        //在编写SQL语句的过程里,如果太长的时候需要换行,那么应当前后加上空格,避免出错

        conn.close();

    }

}

这样就能避免敏感字符了,其他更新方式同理,甚至查询也是使用同样占位方式,再补充内容就行了。

猜你喜欢

转载自blog.csdn.net/weixin_39855497/article/details/80039965