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);
    }

關注微信公衆號【程序媛琬淇】,專注分享Java乾貨,給你意想不到的收穫。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章