JDBC基础篇(MYSQL)——使用CallabeStatement调用存储过程

微笑注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接:

package day04_callable;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import util.JdbcUtil;

/**
 * CallabeStatement:存储过程的statement
 * 		
1. 首先创建一个存储过程:查询所有的用户
  	DELIMITER $
  	CREATE PROCEDURE select_allStudent()
  	BEGIN 
		 	SELECT * FROM student;
 	END $

 	CALL select_allStudent();

2. 输入一个id,查询id对应的用户
 	DELIMITER $
	CREATE PROCEDURE select_studentById(IN sid INT)
	BEGIN 
		SELECT * FROM student WHERE id = sid; -- 注意
	END $

	CALL select_studentById(10);
	
3. 创建一个有输出参数的存储过程
	DELIMITER $
	CREATE PROCEDURE get_studentName(IN sid INT,OUT sname VARCHAR(20))
	BEGIN 
		SELECT NAME INTO sname FROM student WHERE id = sid;
	END $
	
	CALL get_studentName(10, @sname);
	SELECT @sname;
-- 注意输出参数不在ResultSet结果集中,应该在输出参数中

	继承关系:
	 Statement
	 -->PrapredStatement
	 ---->CallableStatement
	 
	 @author mzy
 */
public class Demo01 {
	public static void main(String[] args) {
		// testIn();
		
		testOut();
	}

	private static void testOut() {
		Connection conn = null;
		CallableStatement cstmt = null;
		ResultSet rs = null;
		String sql = "call get_studentName(?, ?)"; //不管是输入还是输出,都可以用 ? 来代替这个参数
		conn = JdbcUtil.getConnection();
		
		try {
			cstmt = conn.prepareCall(sql);
			/**
			 * 设置输入参数
			 */
			cstmt.setInt(1, 10); // 来自preparedStatement:只有preparedStatement才有预编译的功能
			/**
			 * 设置输出参数:
			 * 第一个参数同样是位置下标
			 * 第二个参数是存储过程中,那个输出参数的类型
			 * 
			 * 此方法就是注册输出参数的类型:
			 * 		因为是注册输出参数的是mysql中的操作,注册的输出参数也必须是mysql中的数据类型
			 * 
			 * 通过 java.sql.Types.XXX:就可以获得其中的sql的类型
			 */
			cstmt.registerOutParameter(2, java.sql.Types.VARCHAR); // 因为我们的out参数是varchar
			
			
			// 发送参数:结果并不在resultSet中
			// 这里并不需要rs结果集:因为我们是带返回参数的存储过程,并没有查询结果集
			/*rs = */cstmt.executeQuery(); // 注意:存储过程只能执行Query方法,也只有query方法!!!
			
			// 结果在输出参数中,我们应该在输出参数中查看结果
			// 这里的参数位置和我们的输出参数的位置是保持一致的
			// 通过getXXX方法;但是这里的getXXX方法,和resultSet中的getXXX方法不同
			// 这里的getXXX方法是callableStatement提供的,专门针对存储过程的out参数的
			// 而resultSet中的getXXX方法是获取列的值的
			
			String sname = cstmt.getString(2);
			System.out.println(sname);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JdbcUtil.close(rs, cstmt, conn);
		}
	}

	private static void testIn() {
		Connection conn = null;
		CallableStatement cstmt = null;
		ResultSet rs = null;
		String sql = "call select_studentById(?)";
		conn = JdbcUtil.getConnection();
		
		try {
			cstmt = conn.prepareCall(sql);
			cstmt.setInt(1, 10);
			
			rs = cstmt.executeQuery(); // 注意:存储过程只能执行Query方法,也只有query方法!!!
			
			while(rs.next()) {
				int id = (int)rs.getObject("id"); // rs.getInt("id");
				String name = (String)rs.getObject("name"); // rs.getString("name"); 
				int age = (int)rs.getObject("age"); // rs.getInt("age");
				System.out.println(id+", "+name+", "+age);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JdbcUtil.close(rs, cstmt, conn);
		}
	}
}


posted @ 2018-05-10 16:33  五彩世界  阅读(322)  评论(0编辑  收藏  举报