通过DriverManager
的Connection
,我们获得了与数据库连接之后,我们就要与数据库进行交互了,用Java语言与数据库进行交互就需要用到JDBC的Statement
,CallableStatement
,PreparedStatement
首先这些都是接口!不能由他们直接创建对象。这三个有很多的共同点。
PreparedStatement 继承了Statement接口,相当于扩展了一些功能。
创建对象
这三个在使用之前都需要Connection
创建他们的对象。
虽然都是由Connection对象来调用方法来创建,但是他们的方法还是不一样的。
以下 conn
代表着数据库的连接
创建Statement对象:
conn.createStatement()
值得注意的是,这个方法不接受任何参数。
创建PreparedStatement
conn.preparedStatement(SQL)
这个SQL是预编译的语句,用?
,来占位。例如:
String SQL = "Update Employees SET age = ? WHERE id = ?";
这个?
以后是通过setXXX()
方法来进行输入的。如果忘记绑定,就会输出SQLException。
例如:setString(1,"0880");
其中第一个参数是要填充的位置,从1开始,第二个是填充的值。
创建CallableStatement对象
Callable对象用于执行对数据库存储过程的调用
关于存储过程的相关信息,在另一篇文章中,虽然没有完全理解,但是还是有一定的认识的。
以下代码片段显示了如何创建一个CallableStatement
对象。
CallableStatement cstmt = null;
try {
String strSQL - "{call getEmpName (?,?)}";
cstmt = conn.prepareCall(strSQL);
...
}
catch (SQLException e) {
...
}
finally {
...
}
这其中,strSQL
代表的是存储过程,带有两个参数占位符。CallableStatement
对象和PreparedStatement
对象一样,在执行语句之前,必须将值绑定到所有参数,否则将跑出一个SQLException
异常。
看一下oracle存储过程:
CREATE OR REPLACE PROCEDURE getEmpName
(EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
SELECT first INTO EMP_FIRST
FROM Employees
WHERE ID = EMP_ID;
END;
可以发现这里面有三个参数类型,IN
和OUT
和INOUT
首先PreparedStatement对象只是用IN
参数
Callable可以使用上面三个参数类型。
更加详细的:
IN:创建SQL语句时其参数值是未知的,使用setXXX()方法将值绑定到IN参数。
OUT:由SQL语句返回的参数值,可以使用getXXX()方法从OUT参数中检索值。
INOUT:提供输入和输出的参数。使用setXXX()
方法绑定变量并使用getXXX()方法检索值。
见了上面的三个类型。
【实例】使用CallableStatement的示例。
确保在EMP
数据库中创建了getEmpName()存储过程,可以使用Mysql查询来创建。
DELIMITER $$
DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName`
(IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
SELECT first INTO EMP_FIRST
FROM Employees
WHERE ID = EMP_ID;
END $$
DELIMITER ;
查询emp数据库的所有存储过程,如下语句:
mysql> select `name` from mysql.proc where db = 'emp' and `type` = 'PROCEDURE';
+------------+
| name |
+------------+
| getEmpName |
+------------+
1 row in set (0.00 sec)
然后再编写JDBC代码:
//1. 导包
import java.sql.*;
public class JDBCCallableStatement{
//数据库驱动和URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/EMP";
//数据库用户名和密码
static final String USER = "root";
static final String PASD = "123456";
public static void main(String[] args){
//创建两个对象 Connnection、和 CallableStatement
Connection conn = null;
CallableStatement stmt = null;
//注册驱动(注意跑出错误)
try{
Class.forName(JDBC_DRIVER);
System.out.println("连接数据库中。。。");
//打开连接
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//创建statement对象
String sql = "{call getEmpName(?,?)}";
stmt = conn.prepareCall(sql);
//先绑定IN参数,然后绑定OUT参数
int empID = 102;
stmt.setInt(1,empID);//将ID设置成102
//因为第二个参数是OUT,所以用register它。 stmt.registerOutParameter(2,java.sql,Types.VARCHAR);
//使用excute方法去存储过程
System.out.println("Executing stored procedure");
stmt.execute();//因为在存储过程中有相应的sql语句,所以相当于给存储过程传入参数后就不需要在为stmt传入参数了。
//执行完毕后,亚欧使用getXXX方法,接收employee name
String empName = stmt.getString(2);
System.out.println("Emp Name with ID:" + empID+ "is " + empName);
//关闭连接。
stmt.close();
conn.close();
}catch (SQLException se){
//se.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}finally{
//最后关闭资源
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}//什么都做不了
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("GoodBye!");
}
}
经过这个就很明了了。
执行SQL语句
建完以上的Statement对象、CallableStatement对象、PreparedStatement对象。我们就需要通过他们执行Sql语句,和数据库进行交互了!!!
这三个大体是相同的。
Statement对象
三个方法:boolean execute (String SQL)
: 如果可以检索到ResultSet对象,则返回一个布尔值true; 否则返回false。使用此方法执行SQLDDL语句或需要使用真正的动态SQL,可使用于执行创建数据库,创建表的SQL语句等等。
int executeUpdate (String SQL)
: 返回受SQL语句执行影响的行数。使用此方法执行预期会影响多行的SQL语句,例如:INSERT,UPDATE或DELETE语句。
ResultSet executeQuery(String SQL)
:返回一个ResultSet对象。 当您希望获得结果集时,请使用此方法,就像使用SELECT语句一样。
PreparedStatement对象
由于PreparedStatement对象,在创建对象的过程中就已经传入了sql语句,并通过SetXXX()方法传入了参数。所以Statemetn
的三个方法对PreparedStatement
都适用,并且都没有参数。execute()
executeQuery()
executeUpdate()
CallableStatement对象
暂时还不清楚,不过笔者认为,应该是使用excute()
就可以了。
关闭连接
使用close()
函数,即可。