总的来说,plsql就是为了提高效率的把能在java中写的逻辑放到数据库执行,而执行过程和执行函数就是把plsql包装了一下,包装成一个个方法可以让java来调用,java是不能直接调用plsql的,但可以调用存储过程,存储函数,而包头,和包体就是把一个存储过程和存储函数归类成一个个包,让java调用方便一点.
先从安装oracle的地方找到oracle的驱动包,然后导入工程中
JDBCUtils工具类
package demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtils {
private static String driver = "oracle.jdbc.OracleDriver";
private static String url = "jdbc:oracle:thin:@192.168.0.103:1521/orcl";
private static String user = "scott";
private static String password = "tiger";
static{
//注册驱动
//DriverManager.registerDriver(driver) 这种方式注册的话会注册两次且依赖jar包
try {
Class.forName(driver); //使用反射这种方式没上面的问题
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
//如果使用连接池的话自己加就可以了
public static Connection getConnection(){
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/*
* 技术方向:
* 1、性能优化
* 2、故障诊断:死锁(JDK: ThreadDump)
* Oracle: 自动处理
*/
//释放资源
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
/*
* java的GC不受代码的控制,System.gc();它的意思是尽快的叫垃圾回收器来清理,而不是立马执行,只是请求来回收而已.
* 运行Java:
* java -Xms100M -Xmx200M HelloWorld.class 设置对内存大小才能影响java的GC,也不是什么时候都调用
* 就好,而是在内存不够的时候合理的调用GC才能进行优化.
*/
rs = null; ///-----> 原因:Java GC: 就成的GC回收的对象,可以尽快的释放.
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
st = null;
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
测试代码,里面用的案例都是前两节存储过程,和包头里的案例,可以先看看那两篇文章
package demo;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import org.junit.Test;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;
public class TestOracle {
/*
* create or replace procedure queryEmpInformation(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
*/
@Test
public void testProcedure(){
//{call <procedure-name>[(<arg1>,<arg2>, ...)]} 这个东西是是java提供调用的方式api文档都有
//格式就是这种格式{call 存储过程的名字+参数}
String sql = "{call queryEmpInformation(?,?,?,?)}";
Connection conn = null;
//这个对象也是专门解决存储过程的对象
CallableStatement call = null;
try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql);
//对于in参数,赋值
call.setInt(1,7839);
//对于out参数,申明类型就可以了
call.registerOutParameter(2, OracleTypes.VARCHAR);
call.registerOutParameter(3, OracleTypes.NUMBER);
call.registerOutParameter(4, OracleTypes.VARCHAR);
//执行
call.execute();
//输出
String name = call.getString(2);
double sal = call.getDouble(3);
String job = call.getString(4);
System.out.println(name+"\t"+sal+"\t"+job);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);
}
}
/*
* create or replace function queryEmpIncome(eno in number)
return number
*/
@Test
public void testFunction(){
//{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
//第一个占位符表示return的返回值
String sql = "{?=call queryEmpIncome(?)}";
Connection conn = null;
CallableStatement call = null;
try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql);
call.registerOutParameter(1, OracleTypes.NUMBER);
call.setInt(2, 7839);
//执行
call.execute();
//取出年收入
double income = call.getDouble(1);
System.out.println(income);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);
}
}
//java调用包头包体
@Test
public void testCursor(){
String sql = "{call mypackage.QUERYEMPLIST(?,?)}";
Connection conn = null;
CallableStatement call = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql);
//对于in参数,赋值
call.setInt(1,20);
//对于out参数,申明
call.registerOutParameter(2, OracleTypes.CURSOR);
//执行
call.execute();
//取出结果
rs = ((OracleCallableStatement)call).getCursor(2);
while(rs.next()){
//取出一个员工 参数填列名就可以了.
String name = rs.getString("ename");
double sal = rs.getDouble("sal");
System.out.println(name+"\t"+sal);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//光标实际上是关闭了,因为是ResultSet调用的光标,它都关闭了光标也就关闭了
JDBCUtils.release(conn, call, rs);
}
}
}