Hibernate调用Oracle存储过程

准备工作

1、操作数据表

Oracle数据库scott用户下的EMP员工表

-- Create table
create table EMP
(
  empno    NUMBER(4) primary key,
  ename    VARCHAR2(10),
  job      VARCHAR2(9),
  mgr      NUMBER(4),
  hiredate DATE,
  sal      NUMBER(7,2),
  comm     NUMBER(7,2),
  deptno   NUMBER(2)
)

在这里插入图片描述

2、实体类
Emp.java

package cn.demo.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;

/**
 * 员工类
 */
@Entity
@Table(name="EMP")
public class Emp {

    /**
     * 员工编号
     */
    @Id
    @Column(name="EMPNO")
    private Integer empNo;

    /**
     * 员工姓名
     */
    @Column(name="ENAME")
    private String eName;

    /**
     * 员工职位
     */
    @Column(name="JOB")
    private String job;

    /**
     * 所属领导
     */
    @Column(name="MGR")
    private Integer mgr;

    /**
     * 入职日期
     */
    @Column(name="HIREDATE")
    private Date hireDate;

    /**
     * 薪水
     */
    @Column(name="SAL")
    private Double sal;

    /**
     * 奖金
     */
    @Column(name="COMM")
    private Double comm;

    /**
     * 所属部门编号
     */
    @Column(name="DEPTNO")
    private Integer deptNo;
	
	//省略getter/setter方法
}

3、配置hibernate映射文件

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
    <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
    <property name="connection.username">scott</property>
    <property name="connection.password">123456</property>

    <!--每个数据库都有其对应的方言(Dialect)以匹配其平台特性-->
    <property name="dialect">
      org.hibernate.dialect.Oracle10gDialect
    </property>
    <!--指定当前session范围和上下文-->
    <property name="current_session_context_class">
      thread
    </property>
    <!--是否将运行期生成的sql输出到日志以供调试-->
    <property name="show_sql">true</property>
    <!--是否格式化sql-->
    <property name="format_sql">true</property>
    <!--映射实体类-->
    <mapping class="cn.demo.pojo.Emp"/>

    <!-- DB schema will be updated if needed -->
    <!-- <property name="hbm2ddl.auto">update</property> -->
  </session-factory>
</hibernate-configuration>

4、创建管理SessionFactory和Session的工具类HibernateUtil.java

package cn.demo.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

/**
 * 工具类:管理SessionFactory和Session
 */
public class HibernateUtil {

    private static Configuration configuration;
    private final static SessionFactory SESSION_FACTORY;

    /**
     * 初始化Configuration和SessionFactory
     */
    static{
        try {
            configuration=new AnnotationConfiguration().configure();
            SESSION_FACTORY=configuration.buildSessionFactory();
        }catch (HibernateException ex){
            throw new ExceptionInInitializerError();
        }
    }

    /**
     *  获取session对象
     * @return session
     */
    public static Session getSession(){
        return SESSION_FACTORY.getCurrentSession();
    }
}

Demo1:调用带输出参数的存储过程

创建存储过程

-- 获取所有员工信息
create or replace procedure pro_findAllEmp(
       cur_emps out sys_refcursor       --存放所有员工信息的游标
)
as
begin
       open cur_emps for select * from scott.emp;
  end;

EmpDaoImpl.java

    /**
     * 获取全部用户
     */
    public List<Emp> findAllEmp(){
        List<Emp> empList=new ArrayList<>();
        try {
          	//调用存储过程
            CallableStatement call= HibernateUtil.getSession().connection().
                    prepareCall("{call pro_findAllEmp(?)}");
            //设置输出参数类型
            call.registerOutParameter(1, OracleTypes.CURSOR);
            //执行查询
            call.executeQuery();
            //接收结果集
            ResultSet resultSet=(ResultSet) call.getObject(1);
            //遍历
            while (resultSet.next()){
                Emp emp=new Emp();
                emp.setEmpNo(resultSet.getInt("empNo"));
                emp.seteName(resultSet.getString("eName"));
                emp.setJob(resultSet.getString("job"));
                empList.add(emp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return empList;
    }

EmpServiceImpl.java


  private EmpDaoImpl empDao=new EmpDaoImpl();
    /**
     * 获取所有员工
     * @return
     */
    public List<Emp> findAllEmp(){
        Transaction tx=null;    //创建事务
        List<Emp> empList=null;
        try {
            //开启事务
            tx= HibernateUtil.getSession().beginTransaction();
            empList=empDao.findAllEmp();
            tx.commit();
        }catch (HibernateException e){
            e.printStackTrace();
            if(tx!=null){
                tx.rollback();
            }
        }
        return empList;
    }

注意Hibernate需要添加事务。

测试方法


 public EmpServiceImpl empService=new EmpServiceImpl();
    /**
     * 获取所有员工
     */
    @Test
    public void testFindAllEmp(){
        List<Emp> emps=empService.findAllEmp();
        //输出
        for (Emp emp:emps){
            System.out.println("员工编号:"+emp.getEmpNo()+"\t员工姓名:"+emp.geteName());
        }
    }

输出结果

在这里插入图片描述

Demo2:调用带有输入输出参数的存储过程

创建存储过程

-- 根据员工职位和姓名查询员工信息
create or replace procedure pro_findDetail(
       v_job in varchar2,   --员工职位
       v_ename in varchar2, -- 员工姓名
       cur_emp out sys_refcursor --返回符合条件的结果集
)
as
begin
       open cur_emp for
            select * from scott.emp e where e.job = v_job and e.ename=v_ename;
  end;

EmpDaoImpl.java

    /**
     * 根据员工职位和姓名查找员工
     * @param job 员工职位
     * @param eName 员工姓名
     * @return
     */
    public  List<Emp> findEmpByCondition(String job,String eName){
        List<Emp> empList=new ArrayList<>();
        try {
            CallableStatement call= HibernateUtil.getSession().connection().
                    prepareCall("{call  pro_findDetail(?,?,?)}");
            //为查询条件赋值
            call.setString(1,job);
            call.setString(2,eName);
            //设置输出参数类型
            call.registerOutParameter(3, OracleTypes.CURSOR);
            //执行查询
            call.execute();
            //接收结果集
            ResultSet resultSet=(ResultSet) call.getObject(3);
            //遍历
            while (resultSet.next()){
                Emp emp=new Emp();
                emp.setEmpNo(resultSet.getInt("empNo"));
                emp.seteName(resultSet.getString("eName"));
                emp.setJob(resultSet.getString("job"));
                empList.add(emp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return empList;
    }

EmpServiceImpl.java

	
	private EmpDaoImpl empDao=new EmpDaoImpl();

    /**
     * 根据职位和姓名查询员工列表
     * @param job
     * @param eName
     * @return
     */
    public List<Emp> findEmpByCondition(String job,String eName){
        Transaction tx=null;    //创建事务
        List<Emp> empList=null;
        try {
            //开启事务
            tx= HibernateUtil.getSession().beginTransaction();
            empList=empDao.findEmpByCondition(job,eName);
            tx.commit();
        }catch (HibernateException e){
            e.printStackTrace();
            if(tx!=null){
                tx.rollback();
            }
        }
        return empList;
    }

测试方法

    /**
     * 测试条件获取员工信息
     */
    @Test
    public void testFindByCondition(){
        List<Emp> emps=empService.findEmpByCondition("CLERK","SMITH");
        //输出
        for (Emp emp:emps){
            System.out.println("员工编号:"+emp.getEmpNo()+"\t员工姓名:"+emp.geteName());
        }
    }

运行结果
在这里插入图片描述

Demo3:修改操作

(新增删除类似,此处不做演示)

创建存储过程

-- 修改指定员工的信息
create or replace procedure pro_updateEmp(
        v_empno in number,  --员工编号
        v_ename in varchar2,      --修改后的姓名
        v_job in varchar2,       -- 修改后的职位
        on_flag out number       --是否修改成功
)
as 
begin
        update scott.emp set ename=v_ename,job=v_job where empno=v_empno;
        commit;
        on_flag:=1;
        
       exception
               when others then
                 on_flag:=-1;
  end;

EmpDaoImpl.java

   /**
     * 修改员工信息
     * @param emp
     * @return
     */
    public int updateEmpInfo(Emp emp){
        int result=0;
        try {
            CallableStatement call= HibernateUtil.getSession().connection().
                    prepareCall("{call pro_updateEmp(?,?,?,?)}");
            //设置输入参数值
            call.setInt(1,emp.getEmpNo());
            call.setString(2,emp.geteName());
            call.setString(3,emp.getJob());

            //设置输出参数类型
            call.registerOutParameter(4,OracleTypes.INTEGER);
            //执行存储过程
            call.execute();
            //接收返回结果
            result=call.getInt(4);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

EmpServiceImpl.java

    /**
     * 修改员工信息
     * @param emp 修改后的员工对象
     * @return
     */
    public int updateEmp(Emp emp){
        Transaction tx=null;    //创建事务
        int result=0;
        try {
            //开启事务
            tx= HibernateUtil.getSession().beginTransaction();
            result=empDao.updateEmpInfo(emp);
            tx.commit();
        }catch (HibernateException e){
            e.printStackTrace();
            if(tx!=null){
                tx.rollback();
            }
        }
        return result;
    }

测试方法

    /**
     * 测试修改员工信息方法
     */
    @Test
    public void testUpdateEmp(){
        Emp emp=new Emp();
        emp.setEmpNo(210);
        emp.seteName("王六");
        emp.setJob("SALESMAN");
        //调用方法修改
        int result=empService.updateEmp(emp);
        System.out.println("修改成功返回1,修改失败返回-1:,输出结果:"+result);
    }

关注一下吧~【Pretty Kathy】
请添加图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值