具体内容:
虽然JDBC有提供Statement接口,但是Statement存在巨大的缺陷.
范例:以数据增加操作为例观察一下Statement的问题
package conll;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestDemo {
private static final String DBDEIVER="oracle.jdbc.driver.OracleDriver";
private static final String DBURL="jdbc:oracle:thin:@localhost:1521:mldn";
private static final String USER="scoot";
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(DBDEIVER) ;
//第二步:连接数据库
Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
//第三步:进行数据库的数据操作
Statement stmt = conn.createStatement();
//在编写SQL的过程里面,如果太长的时候需要增加换行,那么请一定记住要前后加上空格
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);
stmt.close(); //这个操作可选并且无用
conn.close();
}
}
Statement如果想要变为灵活的应用,那么就必须采用拼凑字符串的方式完成,可是如果输入的内容存在有" ' ",那么整个SQL就会出错了,也就是Statement的执行模式不适合处理一些敏感字符。
PreparedStatement操作:重点
Statement执行关键性的问题在于它需要一个完整的字符串来定义要使用SQL语句,所以这就导致在使用中要大量的进行SQL的拼凑,而PreparedStatement与Statement不同的地方在于,它执行的是一个具备特殊占位标记的SQL语句,并且可以动态的设置所需要的数据。
PreparedStatement属于Statement的子接口,但是如果要想取得这个子接口的实例化对象,依然需要使用Connection接口所提供的方法:PreparedStatement prepareStatement(String sql) throws SQLException,里面在之心那个的时候需要传入一个SQL语句,这SQL是一个具备特殊标记的完整SQL,但是此时没有内容,当取得了PreparedStatement接口对象后需要使用一系列的setXxx()方法设置具体内容,而后对于执行操纵有两个方法支持。
更新操作:int executeUpdate() throws SQLException
查询操作:ResultSet executeQuery() throws SQLException
当使用了PreparedStatement接口操作时最需要注意的是里面的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(Tim、Timestamp) 只能够依靠lang完成。
Java.util.Date:public long getTime(),可以将Date变为long;
java.sql.Date:public Date(long date),将long变为sql.Date
范例:改进数据增加。
package conll;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestDemo {
private static final String DBDEIVER="oracle.jdbc.driver.OracleDriver";
private static final String DBURL="jdbc:oracle:thin:@localhost:1521:mldn";
private static final String USER="scoot";
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(DBDEIVER) ;
//第二步:连接数据库
Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
//在编写SQL的过程里面,如果太长的时候需要增加换行,那么请一定记住要前后加上空格
String sql = " INSERT INTO member(mid,name,birthday,age,note) values "
+" (myseq.nextval,?,?,?,?)";
//第三部:进行数据库的数据操作,执行完整的SQL
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);
int len = stmt.executeUpdate();//执行SQL返回更新的数据行
System.out.println("影响的数据行:"+len);
//第四行:关闭数据库
stmt.close();
conn.close();
}
}
跟新与删除操作和增加操作的区别不大。以上代码就是在Date()问题上稍微麻烦一点。
整个数据库里面更新操作几乎都是固定的模式,但是查询操作是最为复杂的。
范例:查询全部数据
package conll;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestDemo {
private static final String DBDEIVER="oracle.jdbc.driver.OracleDriver";
private static final String DBURL="jdbc:oracle:thin:@localhost:1521:mldn";
private static final String USER="scoot";
private static final String PASSWORD="tiger";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动程序,此时不需要实例化,因为由容器自己负责管理
Class.forName(DBDEIVER) ;
//第二步:连接数据库
Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
//在编写SQL的过程里面,如果太长的时候需要增加换行,那么请一定记住要前后加上空格
String sql = "SELECT mid,name,birthday,age,note from member order by mid";
//第三部:进行数据库的数据操作,执行完整的SQL
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
while(rs.next()){
int mid =rs.getInt(1);
String name = rs.getString(2);
Date birthday = rs.getDate(3);
int age = rs.getInt(4);
String note = rs.getString(5);
System.out.println(mid+","+name+","+birthday+","+age+","+note);
}
//第四行:关闭数据库
stmt.close();
conn.close();
}
}
范例:模糊查询
package conll;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestDemo {
private static final String DBDEIVER="oracle.jdbc.driver.OracleDriver";
private static final String DBURL="jdbc:oracle:thin:@localhost:1521:mldn";
private static final String USER="scoot";
private static final String PASSWORD="tiger";
public static void main(String[] args) throws Exception {
String keyWord = "李";
//第一步:加载数据库驱动程序,此时不需要实例化,因为由容器自己负责管理
Class.forName(DBDEIVER) ;
//第二步:连接数据库
Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
//在编写SQL的过程里面,如果太长的时候需要增加换行,那么请一定记住要前后加上空格
String sql = "SELECT mid,name,birthday,age,note from member where name like ?";
//第三部:进行数据库的数据操作,执行完整的SQL
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
stmt.setString(1, "%"+keyWord+"%");
while(rs.next()){
int mid =rs.getInt(1);
String name = rs.getString(2);
Date birthday = rs.getDate(3);
int age = rs.getInt(4);
String note = rs.getString(5);
System.out.println(mid+","+name+","+birthday+","+age+","+note);
}
//第四行:关闭数据库
stmt.close();
conn.close();
}
}
如果将String keyWord=""这样设置模糊查询,最后返回的结果是全部数据,但是它和直接全部查询有区别。模糊查询会一行一行的扫描,后者不会,直观的区别就是前者执行速度慢。
范例:分页显示
package conll;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestDemo {
private static final String DBDEIVER="oracle.jdbc.driver.OracleDriver";
private static final String DBURL="jdbc:oracle:thin:@localhost:1521:mldn";
private static final String USER="scoot";
private static final String PASSWORD="tiger";
public static void main(String[] args) throws Exception {
int currentPage = 1;
int lineSize = 5;
String keyWord = "";
//第一步:加载数据库驱动程序,此时不需要实例化,因为由容器自己负责管理
Class.forName(DBDEIVER) ;
//第二步:连接数据库
Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
//在编写SQL的过程里面,如果太长的时候需要增加换行,那么请一定记住要前后加上空格
String sql = "SELECT * from("
+ " SELECT mid,name,birthday,age,note ROWNUM rn "
+ " from member "
+ " where name like ? AND ROWNUM<=?)temp"
+ "where temp.rn>?";
//第三部:进行数据库的数据操作,执行完整的SQL
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
stmt.setString(1, "%"+keyWord+"%");
stmt.setInt(2, currentPage*lineSize);
stmt.setInt(3, (currentPage-1)*lineSize);
while(rs.next()){
int mid =rs.getInt(1);
String name = rs.getString(2);
Date birthday = rs.getDate(3);
int age = rs.getInt(4);
String note = rs.getString(5);
System.out.println(mid+","+name+","+birthday+","+age+","+note);
}
//第四行:关闭数据库
stmt.close();
conn.close();
}
}
范例:统计数据量,使用COUNT()函数
package conll;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestDemo {
private static final String DBDEIVER="oracle.jdbc.driver.OracleDriver";
private static final String DBURL="jdbc:oracle:thin:@localhost:1521:mldn";
private static final String USER="scoot";
private static final String PASSWORD="tiger";
public static void main(String[] args) throws Exception {
String keyWord = "";
//第一步:加载数据库驱动程序,此时不需要实例化,因为由容器自己负责管理
Class.forName(DBDEIVER) ;
//第二步:连接数据库
Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
//在编写SQL的过程里面,如果太长的时候需要增加换行,那么请一定记住要前后加上空格
String sql = "select COUNT(mid) from member where like ?";
//第三部:进行数据库的数据操作,执行完整的SQL
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
stmt.setString(1, "%"+keyWord+"%");
if(rs.next()){ //因为返回一行数据
int count =rs.getInt(1); //取出第一列
System.out.println(count);
}
//第四行:关闭数据库
stmt.close();
conn.close();
}
}
以上所有为PreparedStatement接口的核心功能,必须掌握。
总结:任何开发之中不会用Statement,只会是PreparedStatement.
本文深入探讨JDBC中PreparedStatement的使用,对比Statement接口,解析其如何处理敏感字符,演示数据增加、更新、删除、查询及分页等核心操作,强调其在数据库操作中的灵活性与安全性。

被折叠的 条评论
为什么被折叠?



