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包 以后就可以直接导入项目使用了
- java封装调用存储过程
- 使用java调用存储过程的通用封装
- Java调用存储过程
- Java 调用存储过程
- Java 调用存储过程
- JAVA调用存储过程
- java调用存储过程
- java调用存储过程
- Java调用存储过程
- java调用存储过程
- java调用存储过程
- java 调用存储过程
- JAVA调用存储过程
- java调用存储过程
- java调用存储过程
- java 调用存储过程
- Java调用存储过程
- java调用存储过程
- 【Java 基础语法】
- linux网络笔记
- linux怎样使用top命令查看系统状态
- 15.9 Swift解决闭包引起的循环强引用问题
- Android 自己简单封装的Volley
- java封装调用存储过程
- java内部类使用小结
- 杨辉三角
- 学习SpringMVC——从HelloWorld开始
- 小记parse_str
- DBUtils
- Nginx+uWSGI安装与配置
- Android 5.0 SystemUI 视图框架
- 第二次写博客