java封装调用存储过程

来源:互联网 发布:阿里云服务器外网ip 编辑:程序博客网 时间:2024/06/06 03:54

之前闲来无事在研究存储过程 觉得jdbc调用存储过程效率太低就想有没有更高效的方式?最好能用面对对象思想一个方法调用, 传入过程名称就好?于是打开了百度搜索一番 还真找到了一篇很赞的文章,英雄所见略同啊,想到一块去了 博主已经封装的很好了 叫JAVA调用存储过程的另类封装的开发日志(一)http://nikoloss.iteye.com/blog/1734487 然后没有了 what? 有一那肯定还有二啊,说明一是不全的 那么我理所当然的去搜索二 纳尼? 没有 次奥 说明这个博主很懒!最起码比我懒,好了开玩笑的,不过这个博主已经写的很好很好了 但还是无法真正投入使用 干脆我就用博主的思路继续重新写一篇完整的好了,这次的目的是继续封装生成一个jar包 以后导入就可以用了 这个包后面我会上传的 建议先看上面那个博客后再来看 因为思想一样很多话就没必要在重复讲解了


首先需要两个有关系的java实体bean

这里就用orcle中的emp和dept表也就是员工和部门表

首先是emp实体对象

package test.bean;import java.util.Date;public class Emp {    int empno;                         String ename;                   String job;                  int mgr;                    Date  hiredate;                    double sal;                    double comm ;                    //int deptno;    Dept dept;    public Dept getDept() {        return dept;    }    public void setDept(Dept dept) {        this.dept = dept;    }    public int getEmpno() {        return empno;    }    public void setEmpno(int empno) {        this.empno = empno;    }    public String getEname() {        return ename;    }    public void setEname(String ename) {        this.ename = ename;    }    public String getJob() {        return job;    }    public void setJob(String job) {        this.job = job;    }    public int getMgr() {        return mgr;    }    public void setMgr(int mgr) {        this.mgr = mgr;    }    public Date getHiredate() {        return hiredate;    }    public void setHiredate(Date hiredate) {        this.hiredate = hiredate;    }    public double getSal() {        return sal;    }    public void setSal(double sal) {        this.sal = sal;    }    public double getComm() {        return comm;    }    public void setComm(double comm) {        this.comm = comm;    }//  public int getDeptno() {//      return deptno;//  }//  public void setDeptno(int deptno) {//      this.deptno = deptno;//  }}

我注释的部分就是那位那位很懒的博主所描述的不全的部分,因为很多什么我们要查的对象是有关联关系的

然后是dept实体对象

package test.bean;public class Dept {   int deptno;    String dname;                      String loc;    public int getDeptno() {        return deptno;    }    public void setDeptno(int deptno) {        this.deptno = deptno;    }    public String getDname() {        return dname;    }    public void setDname(String dname) {        this.dname = dname;    }    public String getLoc() {        return loc;    }    public void setLoc(String loc) {        this.loc = loc;    }}

这个就没什么好讲的了


第二步我们的dao层

接口和博主一样不写出来了

package test.dao.imp;import java.sql.SQLException;import java.util.Date;import java.util.Map;import test.bean.Dept;import test.bean.Emp;import test.common.ProcessingCenter;import test.common.utils.DBHelper;import test.dao.EmpDao;import test.dao.ProxyObjects;public class EmpDaoImpl extends ProxyObjects implements EmpDao  {    /*     *数字代表传入参数  字母代表传出参数     *返回的是一个MAP集合 对应传出参数的个数 从0开始     *1代表普通类型  2代表对象类型 3代表集合类型     */    @Override    //根据id获取emp实体对象 如果返回的游标是一行则返回的是一个对象 如果返回的游标是多行则是一个list集合     public Emp getEmpbyid(int id) throws SQLException {        // TODO Auto-generated method stub        String sql="{call getbyname({1},{c})}";        return (Emp) pr.execute(sql, Emp.class).get(0);    }    @Override    //传入emp对象进行添加当然同样的也可以传入一个list集合这里就不写出来了     public void addEmp(Emp emp) throws SQLException {        // TODO Auto-generated method stub        String sql="{call ADDEMP({2})}";        //如果想传入一个对象进行添加必须在数据库创建对应数据类型        //第一个为对象类型,第二个为集合类型  第三个为关联字段以 如果关联字段不同 以被关联对象的关联字段为准 这里的deptno为dept对象中的关联字段        String[] li={"EMPOBJ","EMPLIST","deptno"};        pr.execute(li, sql, null);    }    @Override    //s代表为输出的是字符类型    public String getnamebyid(int id) throws SQLException {        // TODO Auto-generated method stub        String sql="{call getname({1},{s})}";        return (String) pr.execute(sql, null).get(0);    }    @Override    //i代表输出为integer类型    public Integer getMGRbyid(int id) throws SQLException {        // TODO Auto-generated method stub        String sql="{call getmgr({1},{i})}";        return  (Integer) pr.execute(sql, null).get(0);    }    @Override    //o代表输出为double类型    public double getSALbyid(int id) throws SQLException {        // TODO Auto-generated method stub        String sql="{call getsal({1},{o})}";        return (double) pr.execute(sql, null).get(0);    }    @Override    //d代表输出为data类型    public Date getHIREDATEbyid(int id) throws SQLException {        // TODO Auto-generated method stub        String sql="{call gethiredate({1},{d})}";        return (Date) pr.execute(sql, null).get(0);    }   }

这里之所以用map集合是考虑到存储过程可以输出多个值的原因

而之所以结果集要传入calss是因为考虑到过程可以输出多个结果集的原因


第三步是我们要封装jar的入口啦也就是DAO所继承的ProxyObjects类

package test.dao;import java.sql.Connection;import test.common.ProcessingCenter;import test.common.utils.DBHelper;//代理对象 名字随便取都可以public class ProxyObjects {//处理中心对象  public   ProcessingCenter pr;  //提供一个获取Connection对象的方法  方法名称一定为getCon  public Connection getCon(){      Connection con=DBHelper.getCon();      return con;  }}

提供一个getcon方法这样我们就可以将这个jar包和现在的主流框架一起使用了哈哈有木有很激动


第四部 我们最重要的处理中心

package test.common;import static test.common.utils.BeanUtils.getBeans;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import oracle.sql.ARRAY;import oracle.sql.ArrayDescriptor;import oracle.sql.STRUCT;import oracle.sql.StructDescriptor;public class ProcessingCenter {    enum ParamType {        CURSOR, ARRAY, INTEGER, DOUBLE, VARCHAR, DATE;    }    private Connection conn;    private CallableStatement cs;    private ResultSet rs;    private Object[] paras;// 需要一个存放参数的Object数组    private String[] orders; // 一个存放参数的设置和序列的数组    private Class superclass;    public ProcessingCenter(Object[] paras, Class superclass) {        super();        this.paras = paras;        this.superclass = superclass;        try {            conn = getConnection();        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException                | InvocationTargetException | InstantiationException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    // 获取Connection对象    private Connection getConnection() throws NoSuchMethodException, SecurityException, IllegalAccessException,            IllegalArgumentException, InvocationTargetException, InstantiationException {        Method method = superclass.getMethod("getCon", null);        Connection conn = (Connection) method.invoke(superclass.newInstance(), null);        return conn;    }    /*     *      * 1解析sql 2:设置传入参数(如果需要) 3:注册传出参数(如果需要) 4:执行     * 5:获取传出结果集放到集合中返回(List<bean>|null) (如过有)     */    public Map<Integer, Object> execute(String sql, Class<?>... clazz) throws SQLException {        List<?> list = null;        // 存储枚举类型集合就是注册参数类型存储        Map<Integer, ParamType> map = new LinkedHashMap<Integer, ParamType>();        // 此集合为最终要返回的集合        Map<Integer, Object> maps = new LinkedHashMap<Integer, Object>();        try {            // 获取一个数组记录参数的类型(是输入参数还是输出参数)和序列            orders = getOrdersFromSql(sql);            cs = conn.prepareCall(sql.replaceAll("\\{\\w\\}", "?"));            for (int index = 0; index < orders.length; index++) {                try {                    // 设置传入参数                    // 如果有异常则说明这个参数为输出参数                    // 输入参数是用数字类型表示 而输出参数是用字母表示                    int order = Integer.parseInt(orders[index]);                    cs.setObject(index + 1, paras[index]);                } catch (Exception e) {                    // TODO: handle exception                    // 注册传出参数                    switch (orders[index]) {                    case "c":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.CURSOR);                        map.put(index + 1, ParamType.CURSOR);                        break;                    case "i":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.INTEGER);                        map.put(index + 1, ParamType.INTEGER);                        break;                    case "s":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.VARCHAR);                        map.put(index + 1, ParamType.VARCHAR);                        break;                    case "o":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.DOUBLE);                        map.put(index + 1, ParamType.DOUBLE);                        break;                    case "d":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.DATE);                        map.put(index + 1, ParamType.DATE);                        break;                    default:                        throw new Exception("无法注册传出参数类型");                    }                }            }            cs.execute();            // 4.获取结果集并通过传递进来的bean的class加载并放到list中返回(如果需要)! 如果有输出参数            if (map.size() > 0) {                list = new ArrayList();                int clazz_index = 0;// 对于传进来的bean.class是数组,我们需要用来初始化收集                Iterator<Integer> iterator = map.keySet().iterator();                while (iterator.hasNext()) {                    Integer key = iterator.next();// 获取注册输出参数时的序号(key值)                    ParamType paramType = map.get(key);// 获取注册参数的类型                    switch (paramType) {                    case CURSOR:                        // 获取结果集                        rs = (ResultSet) (cs.getObject(key));                        list = getBeans(rs, clazz[clazz_index]);                        if (list.size() == 0) {                            maps.put(clazz_index, null);                        } else if (list.size() == 1) {                            maps.put(clazz_index, list.get(0));                        } else {                            maps.put(clazz_index, list);                        }                        break;                    case INTEGER:                        maps.put(clazz_index, cs.getInt(key));                        break;                    case DOUBLE:                        maps.put(clazz_index, cs.getDouble(key));                        break;                    case VARCHAR:                        maps.put(clazz_index, cs.getString(key));                        break;                    case DATE:                        maps.put(clazz_index, cs.getDate(key));                        break;                    }                    clazz_index++;                }            }        } catch (SQLException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        } finally {            closeConn(conn, cs, rs);        }        return maps;    }    // 提供一个方法的重载实现可以传入对象或者集合    public Map<Integer, Object> execute(String[] liname, String sql, Class<?>... clazz) throws SQLException {        List<?> list = null;        Map<Integer, ParamType> map = new LinkedHashMap<Integer, ParamType>();        Map<Integer, Object> maps = new LinkedHashMap<Integer, Object>();        try {            // 获取一个数组记录参数的类型(是输入参数还是输出参数)和序列            orders = getOrdersFromSql(sql);            cs = conn.prepareCall(sql.replaceAll("\\{\\w\\}", "?"));            for (int index = 0; index < orders.length; index++) {                try {                    // 设置传入参数                    // 如果有异常则说明这个参数为输出参数                    // 输入参数是用数字类型表示 而输出参数是用字母表示                    // 2代表参数为对象类型                    // 3代表参数为集合类型                    int order = Integer.parseInt(orders[index]);                    if (order == 2) {                        List<Object> listobj = new ArrayList<Object>();                        listobj.add(paras[index]);                        ARRAY vArray = gettoArray((List<?>) listobj, liname);                        cs.setObject(index + 1, vArray);                    } else if (order == 3) {                        ARRAY vArray = gettoArray((List<?>) paras[index], liname);                        cs.setObject(index + 1, vArray);                    } else {                        cs.setObject(index + 1, paras[index]);                    }                } catch (Exception e) {                    // TODO: handle exception                    // 注册传出参数                    switch (orders[index]) {                    case "c":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.CURSOR);                        map.put(index + 1, ParamType.CURSOR);                        break;                    case "i":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.INTEGER);                        map.put(index + 1, ParamType.INTEGER);                        break;                    case "s":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.VARCHAR);                        map.put(index + 1, ParamType.VARCHAR);                        break;                    case "o":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.DOUBLE);                        map.put(index + 1, ParamType.DOUBLE);                        break;                    case "d":                        cs.registerOutParameter(index + 1, oracle.jdbc.OracleTypes.DATE);                        map.put(index + 1, ParamType.DATE);                        break;                    default:                        throw new Exception("无法注册传出参数类型");                    }                }            }            cs.execute();            // 4.获取结果集并通过传递进来的bean的class加载并放到list中返回(如果需要)! 如果有输出参数            if (map.size() > 0) {                list = new ArrayList();                int clazz_index = 0;// 对于传进来的bean.class是数组,我们需要用来初始化收集                Iterator<Integer> iterator = map.keySet().iterator();                while (iterator.hasNext()) {                    Integer key = iterator.next();// 获取注册输出参数时的序号(key值)                    ParamType paramType = map.get(key);// 获取注册参数的类型                    switch (paramType) {                    case CURSOR:                        // 获取结果集                        rs = (ResultSet) (cs.getObject(key));                        list = getBeans(rs, clazz[clazz_index]);                        if (list.size() == 0) {                            maps.put(clazz_index, null);                        } else if (list.size() == 1) {                            maps.put(clazz_index, list.get(0));                        } else {                            maps.put(clazz_index, list);                        }                        break;                    case INTEGER:                        maps.put(clazz_index, cs.getInt(key));                        break;                    case DOUBLE:                        maps.put(clazz_index, cs.getDouble(key));                        break;                    case VARCHAR:                        maps.put(clazz_index, cs.getString(key));                        break;                    case DATE:                        maps.put(clazz_index, cs.getDate(key));                        break;                    }                    clazz_index++;                }            }        } catch (SQLException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        } finally {            closeConn(conn, cs, rs);        }        return maps;    }    // 首先我们观察传入的SQL,简化成"{X X.X({1},{2},{o})}"    // 我们实质上是想得到其中的"1,2,o"    public String[] getOrdersFromSql(String sql) {        // 直接截取中括号里面的内容        sql = sql.substring(sql.indexOf("(") + 1, sql.indexOf(")"));        // 现在sql 为"{1},{2},{o}"再替换"{","}"为""        sql = sql.replaceAll("\\{|\\}", "");        // 现在sql为"1,2,o" 按","分割返回        return sql.split(",");    }    // 将集合转换为数据库对应的集合    public ARRAY gettoArray(List<?> list, String[] li)            throws IllegalAccessException, SQLException, NoSuchMethodException, InvocationTargetException {        StructDescriptor recDesc = StructDescriptor.createDescriptor(li[0], conn);        ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();        for (Object ord : list) {            int i = 0;            Field[] fields = ord.getClass().getDeclaredFields();            Object[] record = new Object[fields.length];            for (Field field : fields) {                field.setAccessible(true);                // 获取方法名                String firstLetter = field.getName().substring(0, 1).toUpperCase();                String getter = "get" + firstLetter + field.getName().substring(1);                // 获取当前方法的method对象                Method method = ord.getClass().getMethod(getter, null);                String a = method.getReturnType().toString().toLowerCase();                String s = a.substring(a.lastIndexOf(".") + 1);                // 判断是否是关联对象                if (s.equals(field.getName())) {                    // 执行method对象所代表的方法 获取关联对象                    Object ret = method.invoke(ord, null);                    Field[] fields2 = ret.getClass().getDeclaredFields();                    for (Field field2 : fields2) {                        for (String LIname : li) {                            if (field2.getName().equals(LIname)) {                                field2.setAccessible(true);                                record[i] = field2.get(ret);                            }                        }                    }                } else {                    record[i] = field.get(ord);                }                i++;            }            STRUCT item = new STRUCT(recDesc, conn, record);            pstruct.add(item);        }        ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor(li[1], conn);        ARRAY vArray = new ARRAY(tabDesc, conn, pstruct.toArray());        return vArray;    }    // 关闭链接    private void closeConn(Connection conn, CallableStatement prStmt, ResultSet rs) {        if (conn != null) {            try {                conn.close();            } catch (SQLException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        if (prStmt != null) {            try {                prStmt.close();            } catch (SQLException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        if (rs != null) {            try {                rs.close();            } catch (SQLException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}

还有两个附属工具类 一个解析结果集的BeanUtils类和一个类型识别的枚举BataType类

首先是枚举BataType类

package test.common.utils;public enum BataType {    //枚举类型  String("java.lang.String"),BigDecimal("java.math.BigDecimal"),Date("java.sql.Timestamp");      private String name;      //构造方法      private BataType(String name) {       this.name = name;      }      //根据name值获取枚举类型        public static BataType getName(String name) {          for (BataType c : BataType .values()) {            if (c.name .equals(name)){              return c;            }          }          return null;        }}

接着是解析结果集的BeanUtils对象

package test.common.utils;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.math.BigDecimal;import java.sql.ResultSet;import java.util.ArrayList;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;public class BeanUtils {    // 将结果集装配进对象返回对象集合    public static List<Object> getBeans(ResultSet rs, Class<?> clazz) throws Exception {        // 返回的list集合        List<Object> list = new ArrayList<Object>();        // 定义一个map集合 String存储对象和管理对象的属性值 List存储属性的Field值以及所对应的对象        Map<String, List<Object>> map = new LinkedHashMap<String, List<Object>>();        // 属性计数        int attrsCount = rs.getMetaData().getColumnCount();        int i = 1;        while (rs.next()) {            Object bean = clazz.newInstance();            Field[] prFields1 = clazz.getDeclaredFields();            // 返回 Field 对象的一个数组,这些对象反映此 Class对象所表示的类或接口所声明的所有字段。            // 存储对象和关联对象的属性值Field值以及所对应的对象            for (Field field : prFields1) {                String firstLetter = field.getName().substring(0, 1).toUpperCase();                String getter = "get" + firstLetter + field.getName().substring(1);                Method method = bean.getClass().getMethod(getter, null);                String a = method.getReturnType().toString().toLowerCase();                String s = a.substring(a.lastIndexOf(".") + 1);                // 如何相等当前属性为关联对象 所以bean命名要规范                if (s.equals(field.getName())) {                    // 获取空关联对象                    Object object = method.getReturnType().newInstance();                    // 获取管理对象的Field数组                    Field[] fields = method.getReturnType().getDeclaredFields();                    for (Field field2 : fields) {                        List<Object> lists = new ArrayList<Object>();                        lists.add(field2);                        lists.add(object);                        lists.add(field);                        map.put(field2.getName(), lists);                    }                } else {                    List<Object> lists = new ArrayList<Object>();                    lists.add(field);                    lists.add(bean);                    map.put(field.getName(), lists);                }            }            // 解析结果集并写入对象放入list集合            for (int j = 1; j <= attrsCount; j++) {                List<Object> list2 = map.get(rs.getMetaData().getColumnLabel(j).toLowerCase());                if (list2 == null) {                    break;                }                Field field3 = (Field) list2.get(0);                field3.setAccessible(true);                Object object = list2.get(1);                if (object == bean) {                    // 获取枚举类型进行类型匹配                    BataType bataType = BataType.getName(rs.getMetaData().getColumnClassName(j));                    switch (bataType) {                    case String:                        field3.set(object, rs.getString(j));                        break;                    case BigDecimal:                        BigDecimal b = rs.getBigDecimal(j);                        if (b != null) {                            if (new BigDecimal(b.intValue()).compareTo(b) == 0) {                                field3.set(object, rs.getInt(j));                            } else {                                field3.set(object, rs.getDouble(j));                            }                        }                        break;                    case Date:                        field3.set(object, rs.getDate(j));                        break;                    }                } else {                    BataType bataType = BataType.getName(rs.getMetaData().getColumnClassName(j));                    switch (bataType) {                    case String:                        field3.set(object, rs.getString(j));                        break;                    case BigDecimal:                        BigDecimal b = rs.getBigDecimal(j);                        if (b != null) {                            if (new BigDecimal(b.intValue()).compareTo(b) == 0) {                                field3.set(object, rs.getInt(j));                            } else {                                field3.set(object, rs.getDouble(j));                            }                        }                        break;                    case Date:                        field3.set(object, rs.getDate(j));                        break;                    }                    Field Field4 = (Field) list2.get(2);                    Field4.setAccessible(true);                    Field4.set(bean, object);                }            }            list.add(bean);        }        return list;    }}

最后就是我们的拦截器了

这里我们用cglib动态代理实现AOP拦截

package test.common.proxy;import java.lang.reflect.Field;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import test.common.ProcessingCenter;public class CglibProxy implements MethodInterceptor{    private Object target;    //生成代理对象    public Object getintercept(Object target){        this.target=target;        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(target.getClass());        enhancer.setCallback(this);        return enhancer.create();    }    //切面逻辑 这个拦截器的目的是将目标对象的参数写入数据处理中心(ProcessingCenter)并注入进目标对象    @Override    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {        // TODO Auto-generated method stub        Class<?> superclass = target.getClass().getSuperclass();        Field field=superclass.getDeclaredField("pr");        ProcessingCenter re =new ProcessingCenter(args,superclass);        field.set(target, re);         Object ret;              ret=method.invoke(target, args);         return ret;    }}

OK大功告成
不过还有一些类型没戏 以后慢慢写
常用的都已经写了

接下来是存储过程

create or replace procedure getbyname (ids in number,O_RES OUT SYS_REFCURSOR)as begin  OPEN O_RES FOR    SELECT * from emp t left join dept d on t.deptno = d.deptno where t.empno= ids; end;create or replace procedure getmgr (ids in number,mgr out varchar2)as begin    SELECT MGR into mgr from emp where empno= ids; end;create or replace procedure getname (ids in number,namea out nvarchar2)as begin    SELECT ENAME into namea from emp where empno= ids; end;--自定义对象类型CREATE OR REPLACE TYPE EMPOBJ AS OBJECT (     EMPNO     NUMBER(4),     ENAME     NVARCHAR2(10),     JOB       NVARCHAR2(9),     MGR       NUMBER(4),     HIREDATE  DATE,     SAL       NUMBER(7,2),     COMM      NUMBER(7,2),     DEPTNO    NUMBER(2))--自定义集合类型CREATE OR REPLACE TYPE EMPLIST AS TABLE OF EMPOBJcreate or replace procedure ADDEMP(i_orders IN EMPLIST)asctcOrder EMPOBJ:=i_orders(1);begin       INSERT INTO EMP          (EMPNO, ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)        VALUES          (ctcOrder.EMPNO,ctcOrder.ENAME,ctcOrder.JOB,ctcOrder.MGR,ctcOrder.HIREDATE,ctcOrder.SAL,ctcOrder.COMM, ctcOrder.DEPTNO);    exception when others then    raise;end;create or replace procedure getname (ids in number,namea out nvarchar2)as begin    SELECT ENAME into namea from emp where empno= ids; end;create or replace procedure getname (ids in number,namea out nvarchar2)as begin    SELECT ENAME into namea from emp where empno= ids; end;create or replace procedure getsal (ids in number,sals out number)as begin    SELECT SAL into sals from emp where empno= ids; end;create or replace procedure gethiredate (ids in number,hiredates out varchar2)as begin    SELECT HIREDATE into hiredates from emp where empno= ids; end;

然后是我们的test测试 有没有很激动啊

package test;import java.sql.SQLException;import java.util.Date;import test.bean.Emp;import test.common.proxy.CglibProxy;import test.dao.EmpDao;import test.dao.imp.EmpDaoImpl;/** * @author xiaoqin * */public class Test {    public static void main(String[] args) throws SQLException {        // TODO Auto-generated method stub        //获取增强后的目标对象      EmpDao dao=(EmpDao) new CglibProxy().getintercept(new EmpDaoImpl());          Emp emp = dao.getEmpbyid(7839);          System.out.println(emp.getEmpno());          System.out.println(emp.getEname());          System.out.println(emp.getJob());          System.out.println(emp.getMgr());          System.out.println(emp.getHiredate());          System.out.println(emp.getSal());          System.out.println(emp.getComm());//          System.out.println(emp.getDeptno());          System.out.println(emp.getDept().getDeptno());          System.out.println(emp.getDept().getDname());          System.out.println(emp.getDept().getLoc());          emp.setEmpno(1);          dao.addEmp(emp);          System.out.println("--------------------------------------");          String name = dao.getnamebyid(7839);          System.out.println(name);          System.out.println("--------------------------------------");          Integer mgRbyid = dao.getMGRbyid(7839);          System.out.println(mgRbyid);          System.out.println("--------------------------------------");          double saLbyid = dao.getSALbyid(1);          System.out.println(saLbyid);          System.out.println("--------------------------------------");          Date hiredatEbyid = dao.getHIREDATEbyid(1);          System.out.println(hiredatEbyid);    }}

看结果
这里写图片描述

在来看数据库
这里写图片描述

想想以后调用存储过程是多么的简单 一句话搞定 想想都想留鼻血有木有?

接下来将代码导出为jar包 以后就可以直接导入项目使用了
这里写图片描述

0 0
原创粉丝点击