1. 程式人生 > >java封裝呼叫儲存過程

java封裝呼叫儲存過程

之前閒來無事在研究儲存過程 覺得jdbc呼叫儲存過程效率太低就想有沒有更高效的方式?最好能用面對物件思想一個方法呼叫, 傳入過程名稱就好?於是打開了百度搜索一番 還真找到了一篇很讚的文章,英雄所見略同啊,想到一塊去了 博主已經封裝的很好了 叫 然後沒有了 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包 以後就可以直接匯入專案使用了
這裡寫圖片描述