private Connection getConnection() {To call a database routine we have to create a CallableStatement object from the open Connection, while doing this we also need to define our routine statement:
if(conn == null) {
init();
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:"+database+"://"+host+":"+port+"/"+db, uname, pass);
} catch(ClassNotFoundException ce) {
ce.printStackTrace();
} catch(SQLException se) {
se.printStackTrace();
}
}
return conn;
}
//we will call our function addx, with 3 parameters; 1 out; 2 inTo automate the calling of a routine, I've created a simple utility class:
String stmt = "{? = CALL addx(?, ?)}";
CallableStatement cs = getConnection().prepareCall(stmt);
//register the output parameter, index 1
cs.registerOutParameter(1, java.sql.Types.INTEGER);
//define the 2 in parameters
cs.setInt(2, 2); //index 2
cs.setInt(3, 4); //index 3
cs.execute();//call the routine
int sum = cs.getInt(1); //get the result
package com.ipiel.jdbc.mysql;//Parameter Object
import java.awt.image.ConvolveOp;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Vector;
public class JDBCUtility {
private Connection conn;
private String uname;
private String pass;
private String db;
private String host;
private String port;
private String database;
/**
* Returns an instance of a JDBC Connection object.
* If an instance is null it is initialize.
* @return
*/
private Connection getConnection() {
if(conn == null) {
init();
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:"+database+"://"+host+":"+port+"/"+db, uname, pass);
} catch(ClassNotFoundException ce) {
ce.printStackTrace();
} catch(SQLException se) {
se.printStackTrace();
}
}
return conn;
}
/**
* Initialize the database connection configuration.
*/
private void init() {
database = "mysql";
db = "employee";
port = "3306";
host = "127.0.0.1";
uname = "user";
pass = "password";
}
/**
* Calls a simple function routine
* @param fxnName name of function
* @param v Vector list of Parameter objects
* @param returnType
* @return
*/
public Object callSimpleFunction(String funcName, Vectorv, String returnType) {
Object obj = "";
try {
StringBuilder sb = new StringBuilder();
sb.append("{? = call ");
sb.append(funcName + "(");
for(int i = 0; i < v.size(); i++) {
sb.append("?,");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")}");
//initialize the statement
CallableStatement cs = getConnection().prepareCall(sb.toString());
//first parameter return type (instance of ? character)
cs = setFunctionReturnType(cs, returnType);
Enumeratione = v.elements();
//index 2 is the start of parameter input
//format of fxn call {? = call fxnName(?,?)}
int index = 2;
while(e.hasMoreElements()) {
Parameter param = e.nextElement();
cs = setParameter(cs, param.getType(), param.getValue(), index++);
}
cs.execute();
//index 1 is always the return binder
//fix this
obj = getFunctionReturn(cs, returnType);
} catch(SQLException e) {
e.printStackTrace();
}
return obj;
}
/**
* Calls a simple procedure that returns resultset.
* @param procName
* @param v
* @return
*/
public ResultSet callSimpleProcedure(String procName, Vectorv) {
ResultSet rs = null;
try {
StringBuilder sb = new StringBuilder();
sb.append("{call ");
sb.append(procName + "(");
for(int i = 0; i < v.size(); i++) {
sb.append("?,");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")}");
System.out.println(sb.toString());
//initialize the statement
CallableStatement cs = getConnection().prepareCall(sb.toString());
Enumeratione = v.elements();
//no more return bind
int index = 1;
while(e.hasMoreElements()) {
Parameter param = e.nextElement();
cs = setParameter(cs, param.getType(), param.getValue(), index++);
}
cs.execute();
rs = cs.getResultSet();
} catch(SQLException e) {
e.printStackTrace();
}
return rs;
}
/**
* Sets the return type of a function. Acceptable types are integer,
* Take note that the return index binded is always 1.
* @param cs
* @param returnType
* @return
*/
private CallableStatement setFunctionReturnType(CallableStatement cs,
String returnType) {
int sqlType = -1;
try {
if(returnType.equals("integer")) {
sqlType = java.sql.Types.INTEGER;
} else if(returnType.equals("varchar")) {
sqlType = java.sql.Types.VARCHAR;
} else if(returnType.equals("boolean")) {
sqlType = java.sql.Types.BOOLEAN;
} else if(returnType.equals("datetime")) {
sqlType = java.sql.Types.DATE;
}
if(sqlType != -1)
cs.registerOutParameter(1, sqlType);
} catch(SQLException e) {
e.printStackTrace();
}
return cs;
}
/**
* Gets the return value from a function based on returnType variable.
* @param cs
* @param returnType
* @return
* @throws SQLException
*/
private Object getFunctionReturn( CallableStatement cs, String returnType)
throws SQLException {
Object obj = "";
if(returnType.equals("integer")) {
obj = cs.getInt(1);
} else if(returnType.equals("varchar")) {
obj = cs.getString(1);
} else if(returnType.equals("boolean")) {
obj = cs.getBoolean(1);
} else if(returnType.equals("datetime")) {
obj = cs.getDate(1);
} else if(returnType.equals("resultset")) {
obj = cs.getResultSet();
}
return obj;
}
/**
* Sets the functions parameter.
* @param cs
* @param paramType
* @param value
* @param index
* @return
* @throws SQLException
*/
private CallableStatement setParameter( CallableStatement cs, String paramType,
Object value, int index) throws SQLException {
if(paramType.equals("integer")) {
cs.setInt(index, Integer.valueOf(value.toString()));
} else if(paramType.equals("varchar")) {
cs.setString(index, value.toString());
} else if(paramType.equals("varchar")) {
cs.setBoolean(index, Boolean.valueOf(value.toString()));
} else if(paramType.equals("datetime")) {
cs.setDate(index, Date.valueOf(value.toString()));
}
return cs;
}
/**
* Dispose the current open Connection instance.
*/
public void dispose() {
try {
if(conn.isClosed())
conn.close();
} catch(SQLException e) {
e.printStackTrace();
}
}
}
package com.ipiel.jdbc.mysql;//Sample calls
public class Parameter {
/**
* Acceptable types integer, string(max 50 chars), boolean, date
*/
private String type;
private Object value;
public Parameter() {
type = "integer";
value = "";
}
public Parameter(String type, Object value) {
this.type = type;
this.value = value;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
package com.ipiel.jdbc.mysql;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Vector;
public class Test {
public static void main(String args[]) {
try {
new Test().test();
} catch(Exception e) {
e.printStackTrace();
}
}
private void test() throws SQLException {
//initialize
JDBCUtility jconn = new JDBCUtility();
Vectorv = new Vector ();
//add 2 numbers
Parameter x = new Parameter("integer", 2);
v.add(x);
x = new Parameter("integer", 4);
v.add(x);
Object r = jconn.callSimpleFunction("addx", v, "integer");
System.out.println("add(2, 4): " + r);
//get resultset from procedure call
v.removeAllElements();
x = new Parameter("integer", 1);
v.add(x);
r = jconn.callSimpleProcedure("get_employee_resultset", v);
printResultSet((ResultSet)r);
}
private static void printResultSet(ResultSet rs) throws SQLException {
if(rs == null) {
System.out.println("No resultset");
} else {
ResultSetMetaData md = rs.getMetaData();
System.out.println("Record Count: " + md.getColumnCount());
while(rs.next()) {
System.out.println(rs.getInt(1) + " " + rs.getString(2));
}
}
}
}
DROP TABLE IF EXISTS `employee`;//function addx
CREATE TABLE IF NOT EXISTS `employee` (
`employee_id` int(10) unsigned NOT NULL auto_increment,
`employee_name` varchar(45) NOT NULL,
`employee_male` int(10) unsigned NOT NULL default '1',
`employee_createdat` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY USING BTREE (`employee_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `employee` (
`employee_id`, `employee_name`, `employee_male`, `employee_createdat`
) VALUES
(1, 'employee1', 1, '2009-11-11 00:00:00'),
(2, 'employee2', 0, '2009-12-31 00:00:00');
DELIMITER $$//function get_employee_resultset
DROP FUNCTION IF EXISTS `employee`.`addx` $$
CREATE FUNCTION `employee`.`addx` (a INT, b INT) RETURNS INT
BEGIN
DECLARE c INT;
SET c = a + b;
RETURN c;
END $$
DELIMITER ;
DELIMITER $$
DROP PROCEDURE IF EXISTS `employee`.`get_employee_resultset` $$
CREATE PROCEDURE `get_employee_resultset`(id INT)
BEGIN
SELECT employee_id, employee_name FROM employee WHERE employee_id=id;
END $$
DELIMITER;