一、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();
}
}
这样就能避免敏感字符了,其他更新方式同理,甚至查询也是使用同样占位方式,再补充内容就行了。