JDBC(三)——PreparedStatement接口和CallableStatement接口

使用PreparedStatement接口实现增删改操作

PreparedStatement是Statement的子接口(一般子接口更加强大),与直接使用Statement接口不同的是,PreparedStatement在操作时,是先在数据表中准备一条SQL语句,但是此时SQL语句的具体内容暂且不设置,而是之后再进行设置。
以后开发一般用PreparedStatement,不用Statement。

1
2
3
4
PreparedStatement pstat = con
.prepareStatement(“UPDATE EMPLOYEES SET SALAY = ? WHERE id = ?”);
pstat.setBigDecimal(1, 153833.00);
pstat.setInt(2, 110592);

添加操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import com.java.jdbc.model.Book; //在不同的包需要import
import com.java.jdbc.util.DbUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;

public class Demo1 {
private static DbUtil dbUtil = new DbUtil();
/**
* 添加操作的方法
* @param book
* @return
* @throws Exception
*/
private static int addBook (Book book) throws Exception {
Connection con = dbUtil.getCon(); //获取数据库连接
String sql ="INSERT INTO t_book (id, bookName, author, price, bookTypeId) "
+ "VALUES (?, ?, ?, ?, ?)";
PreparedStatement pstat = con.prepareStatement(sql);
pstat.setInt(1, book.getId());
pstat.setString(2, book.getBookName());//一次对每个属性设置值
pstat.setString(3, book.getAuthor());
pstat.setFloat(4, book.getPrice());
pstat.setString(5, book.getBookTypeId());
int rst = pstat.executeUpdate();
dbUtil.close(pstat, con);
return rst;
}
public static void main(String[] args) throws Exception {
Book book = new Book(7, "英语", "pstat", 55, "1");
int rst = addBook(book);
if (rst == 1){
System.out.println("添加操作成功");
} else {
System.out.println("添加操作失败");
}
}
}

更新操作

除操作

使用CallableStatement接口调用存储过程

CallableStatement主要用于调用数据库中的存储过程,它是PreparedStatement的子接口。在使用CallableStatement时可以接收存储过程的返回值。
格式:
void registerOutParameter(int parameterIndex, int sqlType) 按顺序位置parameterIndex将OUT参数注册为JDBC类型sqlType。

先创建一个procedure,根据id返回bookName

1
2
3
4
5
6
7
DELIMITER &&
CREATE PROCEDURE pro_getBookNameById2 (IN _id INT(10), OUT _bookName VARCHAR(20))
BEGIN
SELECT bookName INTO _bookName FROM t_book WHERE id = _id;
END
&&
DELIMITER ; //注意与分号之间有空格

调用存储过程

1)直接在Mysql中调用
//会话遍历,同一个会话中可以取到,类似于全局遍历。如果存储过程中不加LIMITE 1在这步会报错:Result consisted of more than one row,这是因为mysql的参数赋值语句必须是只能够选出一行,
CALL pro_getBookNameById(7, @_bookName);
//显示这个遍历
SELECT @_bookName;
2)在eclipse中调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Types;

import com.java.jdbc.util.DbUtil;

public class Demo1 {
private static DbUtil dbUtil = new DbUtil();

/**
* 调用存储过程,通过id查询bookName
* @param id
* @return
* @throws Exception
*/
private static String getBookNameById(int id) throws Exception{
Connection con = dbUtil.getCon();
String sql = "{CALL pro_getBookNameById(?, ?)}";
CallableStatement cstat = con.prepareCall(sql);
cstat.setInt(1, id); //只需要设置第一个参数
cstat.registerOutParameter(2, Types.VARCHAR); //第二个为返回值,返回值为VARCHAR类型
cstat.execute(); //直接执行
String bookName = cstat.getString("_bookName"); //获取返回值
dbUtil.close(cstat, con);
return bookName;
}

public static void main(String[] args) throws Exception {
String bookName = getBookNameById(8);
System.out.println("bookName:" + bookName);
}
}