Mysql+使用CallableStatement对象调用存储过程和存储函数+java链接数据库

1.存储过程

(1)定义过程时,使用 DELIMITER $$ 命令将语句的结束符号从分号 ; 临时改为两个 $$,使得过程体中使用的分号被直接传递到服务器,而不会被客户端(如mysql)解释。

delimiter $$
create procedure find(in num1 int)
begin
	select * from student where stuno = num1;
end$$
delimiter ;
call find(1);
delimiter $$
create procedure add_three_num(in num1 int,in num2 int,in num3 int,out re int)
begin
	set re = num1+num2+num3;
end$$
delimiter ;

2.存储函数

(1)建立存储函数的时候报错 “This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) ”,打开my.ini,添加上 log_bin_trust_function_creators=1

delimiter $$
create function add_twonum_function(a int,b int,c int) returns int
begin
	return a+b+c;
end$$
delimiter ;
select add_twonum_function(20,30,40);

3.使用CallableStatement调用

package servletDemo;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;

public class JDBCCallableStatement {
	private static final String URL = "jdbc:MySQL://localhost:3306/hotel?&useSSL=false&serverTimezone=UTC";
	private static final String USERNAME = "root";
	private static final String PWD = "root";
	public static void invokeprocedure(){//增删改
		//调用存储过程和存储函数callableStatement
		Connection connection = null;//因为有可能还么有用到connection就报错了 那么这个对象是空的就不能使用close方法
		CallableStatement cstmt = null;//同理
		try{
			//1导入驱动,加载具体的驱动类
			Class.forName("com.mysql.cj.jdbc.Driver");
			//2与DB建立连接
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			//3发送sql语句,执行(增删改)
			//cstmt需要预编译sql
			//num1 + num2 + num3 = result
			cstmt = connection.prepareCall(   "{ call add_three_num(?,?,?,?) }" ) ;
//			cstmt = connection.prepareCall(sql);
			cstmt.setInt(1,10);
			cstmt.setInt(2,25);
			cstmt.setInt(3,10);
			cstmt.registerOutParameter(4, Types.INTEGER); 
			cstmt.execute();
			int result = cstmt.getInt(4);
			System.out.println(result);
		}catch (ClassNotFoundException e) {//Class.forName()的异常
			e.printStackTrace();
		} catch (SQLException e) {//connection.createStatement()异常
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}finally{//用finally的原因是无论有没有异常都需要关闭连接
			try{
				if(cstmt!=null){//执行sql语句
					cstmt.close();
				}
				if(connection!=null){//建立java代码和数据库的连接
					connection.close();
				}
			}catch(SQLException e) {//前面两个close 都会抛SQLException异常
				e.printStackTrace();
			}
		}		
	}
	public static void invokeFunction(){//增删改
		//调用存储过程和存储函数callableStatement
		Connection connection = null;//因为有可能还么有用到connection就报错了 那么这个对象是空的就不能使用close方法
		CallableStatement cstmt = null;//同理
		try{
			//1导入驱动,加载具体的驱动类
			Class.forName("com.mysql.cj.jdbc.Driver");
			//2与DB建立连接
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			//3发送sql语句,执行(增删改)
			//cstmt需要预编译sql
			//num1 + num2 = result
			String sql = "{? =  call add_twonum_function(?,?,?)}";
			cstmt = connection.prepareCall(sql) ;
//			cstmt = connection.prepareCall(sql);
			cstmt.registerOutParameter(1, Types.INTEGER); 
			cstmt.setInt(2,10);
			cstmt.setInt(3,10);
			cstmt.setInt(4,10);
//			cstmt.registerOutParameter(4, Types.INTEGER); 
			cstmt.execute();
			int result = cstmt.getInt(1);
			System.out.println(result);
		}catch (ClassNotFoundException e) {//Class.forName()的异常
			e.printStackTrace();
		} catch (SQLException e) {//connection.createStatement()异常
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}finally{//用finally的原因是无论有没有异常都需要关闭连接
			try{
				if(cstmt!=null){//执行sql语句
					cstmt.close();
				}
				if(connection!=null){//建立java代码和数据库的连接
					connection.close();
				}
			}catch(SQLException e) {//前面两个close 都会抛SQLException异常
				e.printStackTrace();
			}
		}		
	}
	
	public static void main(String [] args){
		invokeprocedure();
		invokeFunction();
		
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章