一、基本接口或类
——>DriverManager:用于管理JDBC驱动的服务类。主要功能是获取Connection对象。
——>Connection:代表数据库连接对象,每个Connection代表一个物理连接会话。
——>Statement:用于执行SQL语句的工具接口。常用方法:
1、ResultSet executeQuery(String sql)throws SQLException:专用于查询。
2、int executeUpdate(String sql)throws SQLException:执行DDL、DML语句,前者返回0,后者返回受影响行数。
3、boolean execute(String sql)throws SQLException:可执行任何SQL 语句。如果执行后第一个结果为ResultSet(即执行了查询语句),则返回true;如果执行了DDL、DML语句,则返回false。返回结果为true,则随后可通过该Statement对象的getResultSet()方法获取结果集对象(ResultSet类型),返回结果为false,则可通过Statement对象的getUpdateCount()方法获得受影响的行数。
——>PrepareStatement:为Statement的子接口,可预编译SQL 语句,常用语执行多条结构相同,仅值不同的SQL 语句,见下例。同样具有Statement对象常用的三个方法,但用法不同,因为已经预编译了SQL 月,所以无需再在方法中写sql语句,只需setString方法设置参数值即可,如代码中。
使用PreparedStatement比使用Statement多了三个好处:
1、PreparedStatement预编译SQL语句,性能更好,执行更快。
2、PreparedStatement无须“拼接”SQL 语句,编程更简单。
3、PreparedStatement可以防止SQL 注入(如将输入的true当成直接量,导致判断直接通过,从而降低了安全性),安全性更好。
二、实践
说明:此实践主要用于熟悉JDBC 编程步骤,理解三种执行SQL语句的一些区别。
目录结构:
java文件:
execute.java:
说明:execute方法可执行所有SQL 语句。学习了一个新的方法:ResultSet对象的getMetaData()方法,该方法返回结果集的列相关的信息,如列数目、列类型等。
package executeSqlWays;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
/**
* @author Administrator
* execute is a way that can execute any SQL.
*/
public class execute {
public void executeSqlWithExecute(String sql) throws Exception{
try{
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbctest","root","1234");
Statement statem=conn.createStatement();
boolean hasResultSet=statem.execute(sql);
//如果执行的为查询语句,打印结果
if(hasResultSet){
try{
ResultSet rs=statem.getResultSet();
//getMetaData返回数据库的columns的信息:number、types、properties。
ResultSetMetaData rsMD=rs.getMetaData();
int number=rsMD.getColumnCount();
for(int numb=1;numb<=number;numb++){
System.out.print(rsMD.getColumnName(numb)+'\t');
}
System.out.println(" ");
while(rs.next()){
for(int numb=1;numb<=number;numb++){
System.out.print(rs.getString(numb)+'\t');
}
}
}catch(Exception e){
System.out.println("execute 返回结果集失败:");
e.printStackTrace();
}
}
//如果执行的为DDL、DML语句,返回受影响的的记录条数
else{
System.out.println("该execute方法执行sql影响的记录数为"+statem.getUpdateCount()+"条");
}
}catch(Exception e){
System.out.print("execute 方法失败:");
e.printStackTrace();
}
}
}
executeUpdate.java:
说明:executeUpdate方法主要用于执行DDL、DML语句。
/**package executeSqlWays includes some different ways to execute SQL.
*/
package executeSqlWays;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* class executeUpdate is a way to execute SQL in java8.
*/
public class executeUpdate {
/*executeUpdate主要用来执行DDL、DML语句*/
public void executeSqlWithExecuteUpdate(String sql) throws Exception{
try{
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbctest","root","1234");
Statement statem=conn.createStatement();
//execute SQL
statem.executeUpdate(sql);
}catch(Exception e){
System.out.print("加载驱动失败:");
e.printStackTrace();
}
}
}
说明:1)表operation3为在命令行建立的。此处只使用了DML 语句,能否使用DDL 等其它语句没多做探究。
2)、PreparedStatement对象的本质是先编译基本SQL 语句结构,对不确定的参数值用?号代替,之后插入值时使用该对象的setString(int index,String value)等方法设定具体值,再调用不带参数的execute、executeUpdate、executeQuery等方法执行。实践发现,其中index指不确定值?的索引,从1开始,若预编译的SQL 指令为:
insert into tableName (column1,column2,column3)values(?,null,?);
则此方法插入一条记录时应为:
pstatem.setString(1,value1);//设置第一个?的值
pstatem.setString(2,value2);//设置第二个?的值
executeUpdate(); //必须,真正的执行。
注意:占位符?参数只能代替普通值,不能代替表名、列名等数据库对象,更不能代替insert等关键字!
package executeSqlWays;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
/**
* @author Administrator
* PreparedStatement是statement的子接口,可以预编译SQL语句,预编译后的SQL语句被存储在PreparedStatement
* 对象中,然后可以使用该对象高效地执行该语句。常用于执行结构相似的多条SQL语句。
*/
public class prepareStatement {
public void executeSqlWithPrepareStatement() throws Exception{
try{
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbctest","root","1234");
//关键区别:获取statement对象的方法不同。?号表示此值是一个变化的值,通过方法设定。
PreparedStatement pstatem=conn.prepareStatement(
"insert into operation3 values(null,?);");
//执行 SQL
pstatem.setString(1,"第一行" );
pstatem.executeUpdate();
pstatem.setString(1,"第二行");
pstatem.executeUpdate();
}catch(Exception e){
System.out.print("加载驱动失败:");
e.printStackTrace();
}
}
}
说明:主函数分别使用execute、executeUpdate方法创建表operation1、operation2且插入一条记录。PreparedStatement方法对命令行创建的表operation3进行插入记录操作。
package mysqlOperation;
import executeSqlWays.executeUpdate;
import executeSqlWays.execute;
import executeSqlWays.prepareStatement;
public class MySQLOperation {
/*分别使用executeUpdate、execute、preparedStatement方法执行SQL语句*/
public static void main(String[] args) {
/*executeUpdate方法*/
executeUpdate operation1=new executeUpdate();
try {
operation1.executeSqlWithExecuteUpdate("create table operation1("
+ "id int auto_increment primary key,"
+ "name varchar(40) not null);");
operation1.executeSqlWithExecuteUpdate("insert into operation1(name)"
+ "values('executeUpdate创建表并插入该行数据');");
} catch (Exception e) {
System.out.print("opertation1错误:");
e.printStackTrace();
}
/*execute方法*/
execute operation2=new execute();
try{
operation2.executeSqlWithExecute("create table operation2("
+ "id int auto_increment primary key,"
+ "name varchar(40) not null);");
operation2.executeSqlWithExecute("insert into operation2(name)"
+ "values('execute方法创建表并插入该行数据');");
operation2.executeSqlWithExecute("select * from operation2;");
} catch(Exception e){
System.out.print("operation2错误:");
e.printStackTrace();
}
/*prepareStatement方法。通过命令行创建表operation3后,使用该方法插入数据。*/
prepareStatement operation3=new prepareStatement();
try{
operation3.executeSqlWithPrepareStatement();
} catch(Exception e){
System.out.println("PreparedStatement方法失败:");
e.printStackTrace();
}
}
}
execute方法在eclipse中输出结果: