首先创建工具包:
public class JDBCUtils {
private static String driver="oracle.jdbc.OracleDriver";
private static String url="jdbc:oracle:thin:@localhost:1521:orcl";
private static String user="scott";
private static String password="zhang";
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConn(){
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static void release(Connection conn,Statement stat,ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null; //let the gc release it
}
}
if(stat != null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
stat = null; //let the gc release it
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null; //let the gc release it
}
}
}
}
rs=null,stat=null,conn=null(问题:是否可以通过代码干预垃圾回收?)
说明:不可以,即使使用gc方法,因为JVM会为每个资源分配内存,当我们在cmd中执行时
可以采用此方式执行:java -Xms100M -Xmx200M TestHello;(最小内存-Xms100M 最大内存-Xmx200M)
这样就为该TestHello程序手动分配内存了,当此程序快要超出最大内存200M时,这时JVM才会回收垃圾,
否则内存还很充足时,是不会回收的,所以无法干预。
然后测试:
package oracle.jdbc.utils;
import java.sql.CallableStatement;
import java.sql.Connection;
import org.junit.Test;
public class TestJDBC {
@Test
public void testJdbc(){
System.out.println(JDBCUtils.getConn());
}
/**这是储存过程的头部定义 过程名为checkemp
* create or replace PROCEDURE checkemp(empid in number,
pname out VARCHAR2,
psal out VARCHAR2,
pcomm out VARCHAR2)
*/
@Test
public void testProcedure(){
//{call <procedure-name>[(<arg1>,<arg2>, ...)]}----》API中存储过程的定义的sql方式
String sql = "{call checkemp(?,?,?,?)}";
Connection conn = null;
CallableStatement call = null;
try {
conn = JDBCUtils.getConn();
call = conn.prepareCall(sql);
//对于输入参数:赋值
call.setInt(1, 7839);
//对于out输出参数:声明
call.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);
call.registerOutParameter(3, oracle.jdbc.OracleTypes.NUMBER);
call.registerOutParameter(4, oracle.jdbc.OracleTypes.NUMBER);
//执行储存过程
call.execute();
//输出结果
String name = call.getString(2);
double sal = call.getDouble(3);
double comm = call.getDouble(4);
System.out.println(name+"-----"+sal+"-----"+comm);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);
}
}
/**这是储存函数的头部定义 函数名为findSal
* create or replace function findSal(empid in number)
return NUMBER
*/
@Test
public void testFunction(){
//{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}----》API中存储函数的定义的sql方式
String sql = "{?= call findSal(?)}";
Connection conn = null;
CallableStatement call = null;
try{
conn = JDBCUtils.getConn();
call = conn.prepareCall(sql);
//返回值的声明
call.registerOutParameter(1, oracle.jdbc.OracleTypes.NUMBER);
//输入参数的设置
call.setInt(2, 7839);
//执行
call.execute();
//输出结果
double sal = call.getDouble(1);
System.out.println(sal);
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);
}
}
}
记住原则:
如果只有一个返回值,用存储函数;否则,就用存储过程。