java封装调用存储过程

之前闲来无事在研究存储过程 觉得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 {
    private int empno;
    private String ename;
    private String job;
    private int mgr;
    private Date hiredate;
    private double sal;
    private double comm;
    // int deptno;
    private 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;
    // }
    @Override
    public String toString() {
        return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate
                + ", sal=" + sal + ", comm=" + comm + ", dept=" + dept + "]";
    }

}

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

然后是dept实体对象

package test.bean;

public class Dept {
    private int deptno;
    private String dname;                  
    private 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;
    }
    @Override
    public String toString() {
        return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
    }



}

这个就没什么好讲的了


第二步我们的dao层

接口我就不写了

package test.dao.imp;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import qin.common.ProcessingCenter;
import test.DBHelper;
import test.bean.Dept;
import test.bean.Emp;
import test.dao.EmpDao;
import test.dao.ProxyObjects;

public class EmpDaoImpl extends ProxyObjects implements EmpDao  {

    /*
     *数字代表传入参数  
     *返回的是一个MAP集合 key(int)对应传出参数的个数(按序)
     *1代表普通类型  2代表对象类型 3代表集合类型
     *
     *字母代表传出参数
     *c代表游标
     *s代表String
     *i代表Integer
     *o代表double
     *d代表data
     */
    // 测试 sql 更具id获取对象
    @Override
    public Emp finEmp(int id) throws Exception {
        String SQL="select * from emp where empno=? ";
         List<Emp> list = (List<Emp>) pr.executefindsql(SQL,Emp.class);
        return list.get(0);
    }
    // 测试 sql 更新操作
    @Override
    public int updateEmp(String ename, int id) throws Exception {
        // TODO Auto-generated method stub
        String SQL = "update emp set ename = ? where empno = ?";
        return  pr.executeUpdatesql(SQL);
    }
    // 测试存储过程 根据编号获取对象
    @Override
    public Emp getEmpbyid(int id) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call getEmpbyid({1},{c})}";
        Map<Integer, Object> map = pr.execute(SQL, Emp.class);
         List<Emp> list = (List<Emp>) map.get(0);
        return  list.get(0);
    }
    // 测试存储过程 根据编号 获取集合
    @Override
    public List<Map<String, Object>> getListbyid(int id) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call getEmpbyid({1},{c})}";
        return (List<Map<String, Object>>) pr.execute(SQL).get(0);
    }
    // 测试存储过程 根据用户名称获取对象集合
    @Override
    public List<Emp> getEmpListByEname(String ename) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call getEmpListByEname({1},{c})}";
        Map<Integer, Object> execute = pr.execute(SQL,Emp.class);
        return  (List<Emp>) execute.get(0);
    }
    // 测试存储过程 添加对象
    @Override
    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);

    }
    // 测试存储过程 添加集合
    @Override
    public void addEmps(List<Emp> list) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call addEmp({3})}";
        //如果想传入一个对象进行添加必须在数据库创建对应数据类型
        //第一个为对象类型,第二个为集合类型  第三个为关联字段以 如果关联字段不同 以被关联对象的关联字段为准 这里的deptno为dept对象中的管理字段
        String[] li={"EMPOBJ","EMPLIST","deptno"};
        pr.execute(li, SQL);

    }
    // 测试存储过程 添加多个类型入参
    @Override
    public void addLists(Emp emp, int w, List<Emp> list) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call ADDOBJ({2},{1},{3})}";
        //如果想传入一个对象进行添加必须在数据库创建对应数据类型
        //第一个为对象类型,第二个为集合类型  第三个为关联字段以 如果关联字段不同 以被关联对象的关联字段为准 这里的deptno为dept对象中的管理字段
        String[] li={"EMPOBJ","EMPLIST","deptno"};
        String[] lis={"EMPOBJ","EMPLIST"};
        List<String[]> arry=new ArrayList<String[]>();
        arry.add(li);
        arry.add(lis);
        pr.execute(arry, SQL);

    }
    // 测试存储过程 根据id获取String类型
    @Override
    public String getNameById(int id) throws SQLException {
        // TODO Auto-generated method stub
        String sql="{call getname({1},{s})}";
        return (String) pr.execute(sql).get(0);
    }
    // 测试存储过程 根据id获取Integer类型
    @Override
    public Integer getMgrById(int id) throws SQLException {
        // TODO Auto-generated method stub
        String sql="{call getmgr({1},{i})}";
        return  (Integer) pr.execute(sql).get(0);
    }
    // 测试存储过程 根据id获取double类型
    @Override
    public double getSalById(int id) throws SQLException {
        // TODO Auto-generated method stub
        String sql="{call getsal({1},{o})}";
        return (double) pr.execute(sql).get(0);
    }
    // 测试存储过程 根据id获取DateE类型
    @Override
    public Date getHiredateById(int id) throws SQLException {
        // TODO Auto-generated method stub
        String sql="{call gethiredate({1},{d})}";
        return (Date) pr.execute(sql).get(0);
    }

}

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

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


第三步是我们要封装一个入口啦也就是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.dao.imp;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import qin.common.ProcessingCenter;
import test.DBHelper;
import test.bean.Dept;
import test.bean.Emp;
import test.dao.EmpDao;
import test.dao.ProxyObjects;

public class EmpDaoImpl extends ProxyObjects implements EmpDao  {

    /*
     *数字代表传入参数  
     *返回的是一个MAP集合 key(int)对应传出参数的个数(按序)
     *1代表普通类型  2代表对象类型 3代表集合类型
     *
     *字母代表传出参数
     *c代表游标
     *s代表String
     *i代表Integer
     *o代表double
     *d代表data
     */
    // 测试 sql 更具id获取对象
    @Override
    public Emp finEmp(int id) throws Exception {
        String SQL="select * from emp where empno=? ";
         List<Emp> list = (List<Emp>) pr.executefindsql(SQL,Emp.class);
        return list.get(0);
    }
    // 测试 sql 更新操作
    @Override
    public int updateEmp(String ename, int id) throws Exception {
        // TODO Auto-generated method stub
        String SQL = "update emp set ename = ? where empno = ?";
        return  pr.executeUpdatesql(SQL);
    }
    // 测试存储过程 根据编号获取对象
    @Override
    public Emp getEmpbyid(int id) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call getEmpbyid({1},{c})}";
        Map<Integer, Object> map = pr.execute(SQL, Emp.class);
         List<Emp> list = (List<Emp>) map.get(0);
        return  list.get(0);
    }
    // 测试存储过程 根据编号 获取集合
    @Override
    public List<Map<String, Object>> getListbyid(int id) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call getEmpbyid({1},{c})}";
        return (List<Map<String, Object>>) pr.execute(SQL).get(0);
    }
    // 测试存储过程 根据用户名称获取对象集合
    @Override
    public List<Emp> getEmpListByEname(String ename) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call getEmpListByEname({1},{c})}";
        Map<Integer, Object> execute = pr.execute(SQL,Emp.class);
        return  (List<Emp>) execute.get(0);
    }
    // 测试存储过程 添加对象
    @Override
    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);

    }
    // 测试存储过程 添加集合
    @Override
    public void addEmps(List<Emp> list) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call addEmp({3})}";
        //如果想传入一个对象进行添加必须在数据库创建对应数据类型
        //第一个为对象类型,第二个为集合类型  第三个为关联字段以 如果关联字段不同 以被关联对象的关联字段为准 这里的deptno为dept对象中的管理字段
        String[] li={"EMPOBJ","EMPLIST","deptno"};
        pr.execute(li, SQL);

    }
    // 测试存储过程 添加多个类型入参
    @Override
    public void addLists(Emp emp, int w, List<Emp> list) throws SQLException {
        // TODO Auto-generated method stub
        String SQL="{call ADDOBJ({2},{1},{3})}";
        //如果想传入一个对象进行添加必须在数据库创建对应数据类型
        //第一个为对象类型,第二个为集合类型  第三个为关联字段以 如果关联字段不同 以被关联对象的关联字段为准 这里的deptno为dept对象中的管理字段
        String[] li={"EMPOBJ","EMPLIST","deptno"};
        String[] lis={"EMPOBJ","EMPLIST"};
        List<String[]> arry=new ArrayList<String[]>();
        arry.add(li);
        arry.add(lis);
        pr.execute(arry, SQL);

    }
    // 测试存储过程 根据id获取String类型
    @Override
    public String getNameById(int id) throws SQLException {
        // TODO Auto-generated method stub
        String sql="{call getname({1},{s})}";
        return (String) pr.execute(sql).get(0);
    }
    // 测试存储过程 根据id获取Integer类型
    @Override
    public Integer getMgrById(int id) throws SQLException {
        // TODO Auto-generated method stub
        String sql="{call getmgr({1},{i})}";
        return  (Integer) pr.execute(sql).get(0);
    }
    // 测试存储过程 根据id获取double类型
    @Override
    public double getSalById(int id) throws SQLException {
        // TODO Auto-generated method stub
        String sql="{call getsal({1},{o})}";
        return (double) pr.execute(sql).get(0);
    }
    // 测试存储过程 根据id获取DateE类型
    @Override
    public Date getHiredateById(int id) throws SQLException {
        // TODO Auto-generated method stub
        String sql="{call gethiredate({1},{d})}";
        return (Date) pr.execute(sql).get(0);
    }

}

还有两个附属工具类 一个解析结果集的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 qin.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.HashMap;
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对象
                Field field3 = (Field) list2.get(0);
                field3.setAccessible(true);
                //获取当前写入的bean对象
                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;
    }

    // 将结果集装配进 List<Map<String,Object>>并返回
    public static List<Map<String,Object>> getBeans(ResultSet rs) throws Exception {
        // 返回的list集合
        List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        Map<String,Object> map=new HashMap<String,Object>();
        // 属性计数
        int attrsCount = rs.getMetaData().getColumnCount();
         while (rs.next()) {  

                for (int i = 1; i <= attrsCount; i++) {  
                    // 每列给对应的属性赋值  
                    String attr = rs.getMetaData().getColumnLabel(i).toLowerCase();  
                    map.put(attr, rs.getObject(i));
                }  
           list.add(map);
            }  
        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 getEmpbyid (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 getEmpListByEname (ids in nvarchar2,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.ename= 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 EMPOBJ


create or replace procedure addEmp(i_orders IN EMPLIST)
as
ctcOrder 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 getmgr (ids in number,mgr out number)
as
 begin
    SELECT MGR into mgr 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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import qin.common.proxy.CglibProxy;
import test.bean.Emp;
import test.dao.EmpDao;
import test.dao.imp.EmpDaoImpl;

public class Test {

    public static void main(String[] args) throws SQLException, Exception {
        Emp emp = null;
        // 获取增强后的目标对象 ????
        EmpDao dao = (EmpDao) new CglibProxy().getintercept(new EmpDaoImpl());
        // 测试查询sql String sql="select * from emp where empno=? ";
        emp = dao.finEmp(7369);
        System.out.println(emp);

        // 测试更新sql String SQL = "update emp set ename = ? where empno = ?";
        int updateEmp = dao.updateEmp("xiaohei", 1111);
        System.out.println(updateEmp);

        // 测试存储过程 根据编号获取对象
        emp = dao.getEmpbyid(7369);
        System.out.println(emp);

        // 测试存储过程 根据编号 获取集合
        List<Map<String, Object>> list = dao.getListbyid(7369);
        System.out.println(list);

        // 测试存储过程 根据用户名称获取对象集合 ????
        List<Emp> empListByEname = dao.getEmpListByEname("SMITH");
        System.out.println(empListByEname);

        // 测试存储过程 添加对象
        emp.setEmpno(1224);
        // dao.addEmp(emp);

        // 测试存储过程 添加集合
        List<Emp> listEmp = new ArrayList<Emp>();
        listEmp.add(emp);
        // dao.addEmps(listEmp);

        // 测试存储过程 添加多个类型入参
        // dao.addLists(emp, 1, listEmp);

        // 测试存储过程 根据id获取String类型
        String nameById = dao.getNameById(7369);
        System.out.println(nameById);

        // 测试存储过程 根据id获取Integer类型
        Integer mgrById = dao.getMgrById(7369);
        System.out.println(mgrById);
        // 测试存储过程 根据id获取double类型
        double salById = dao.getSalById(7369);
        System.out.println(salById);
        // 测试存储过程 根据id获取DateE类型
        Date hiredateById = dao.getHiredateById(7369);
        System.out.println(hiredateById);

    }

    }

看结果
这里写图片描述

在来看数据库

这里写图片描述

想想以后调用存储过程是多么的简单 一句话代码就可以啦

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

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
注意,以下使用数据库为sql2000,驱动jtds1.2.2 一、调用存储过程(无结果集返回) Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?,?) }"); callableStatement.setString(1, "xxxxxxxx"); callableStatement.setString(2, "xxxxxxxx"); callableStatement.execute(); //获得sql的消息并输出,这个估计很多人都需要 SQLWarning sqlWarning = callableStatement.getWarnings(); while (sqlWarning != null) { System.out.println("sqlWarning.getErrorCode() = " + sqlWarning.getErrorCode()); System.out.println("sqlWarning.getSQLState() = " + sqlWarning.getSQLState()); System.out.println("sqlWarning.getMessage() = " + sqlWarning.getMessage()); sqlWarning = sqlWarning.getNextWarning(); } //close ConnectionHelper.closeConnection(callableStatement, connection); 二、调用存储过程,返回sql类型数据(非记录集) Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?,?,?) }"); callableStatement.setString(1, "xxxxxxxx"); callableStatement.setString(2, "xxxxxxxx"); //重点是这句1 callableStatement.registerOutParameter(3, Types.INTEGER); callableStatement.execute(); //取返回结果,重点是这句2 //int rsCount = callableStatement.getInt(3); //close ConnectionHelper.closeConnection(callableStatement, connection); 三、重点来了,返回记录集,多记录集 注意,不需要注册返回结果参数,只需要在sql中select出结果即可 例如:select * from tableName 即可得到返回结果 Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?) }"); //此处参数与结果集返回没有关系 callableStatement.setString(1, "xxxxxxxx"); callableStatement.execute(); ResultSet resultSet = callableStatement.getResultSet(); //以上两个语句,可以使用ResultSet resultSet = callableStatement.executeQuery();替代 //多结果返回 ResultSet resultSet2; if (callableStatement.getMoreResults()) { resultSet2 = callableStatement.getResultSet(); while (resultSet2.next()) { } } //close ConnectionHelper.closeConnection(callableStatement, connection); 提示:多结果返回可以使用如下代码(以上主要让

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值