分享

Hibernate3.x调用存储过程(转)

 毁灭号 2010-10-12
原文出处:http://tech.it168.com/j/d/2007-05-14/200705141007843.shtml

摘要:本文以详尽的实例展示了hibernate3.x中调用存储过程各步骤,从建立测试表、存储过程的建立、工程的建立以及类的编写和测试一步一步引导用户学习hibernate3.x中调用存储过程的方法.

如果底层数据库(eg. Oracle、mysql、sqlserver)等支持存储过程,可通过存储过程执行批量删除、更新等操作。本文以实例说明在hibernate3.x中如何调用存储过程。

  说明:本例hibernate所用版本为3.0,mysql所用版本为5.0,所用数据库驱动为mysql-connector-java-5.0.4-bin.jar。

一.             建表与初始化数据

在mysql的test数据库中建立一张新表:tbl_user,建表语句如下:
Sql代码 复制代码
  1.  DROP TABLE IF EXISTS `user`;   
  2.   
  3. CREATE TABLE `tbl_user` (   
  4.   
  5.   `userid` varchar(50) NOT NULL,   
  6.   
  7.   `namevarchar(50) default '',   
  8.   
  9.   `blog` varchar(50) default '',   
  10.   
  11.   PRIMARY KEY (`userid`)   
  12.   
  13. ) ENGINE=InnoDB DEFAULT CHARSET=gb2312;  



建表成功后,在该表中插入如下4条初始数据,对应的sql语句如下:

Sql代码 复制代码
  1. INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('ant''蚂蚁''http://www./qixiangnj');   
  2.   
  3. INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('beansoft''bean''http://www./beansoft');   
  4.   
  5. INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('sterning''似水流年''http://www./sterning');   
  6.   
  7. INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('tom''tom' , 'http://www./tom');  



二.             建立存储过程

为测试hibernate3.x中存储过程的调用,我们在user表中建立getUserList、createUser、updateUser和deleteUser这四个存储过程,在mysql中建立存储过程的语句如下:

1. 获得用户信息列表的存储过程--getUserList

Sql代码 复制代码
  1. DROP PROCEDURE IF EXISTS `getUserList`;   
  2.   
  3. CREATE PROCEDURE `getUserList`()   
  4.   
  5. begin  
  6.   
  7.      select * from tbl_user;   
  8.   
  9. end;  



2. 通过传入的参数创建用户的存储过程--createUser

Sql代码 复制代码
  1. DROP PROCEDURE IF EXISTS `createUser`;   
  2.   
  3. CREATE PROCEDURE `createUser`(IN userid varchar(50), IN name varchar(50), IN blog varchar(50))   
  4.   
  5. begin  
  6.   
  7.     insert into tbl_user values(userid, name, blog);   
  8.   
  9. end;  




3. 通过传入的参数更新用户信息的存储过程--updateUser

Sql代码 复制代码
  1. DROP PROCEDURE IF EXISTS `updateUser`;   
  2.   
  3. CREATE PROCEDURE `updateUser`(IN nameValue varchar(50), IN blogValue varchar(50), IN useidValue varchar(50))   
  4.   
  5. begin  
  6.   
  7.     update tbl_user set name = nameValue, blog = blogValue where userid = useridValue;   
  8.   
  9. end;  




4. 删除用户信息的存储过程--deleteUser

Sql代码 复制代码
  1. DROP PROCEDURE IF EXISTS `deleteUser`;   
  2.   
  3. CREATE PROCEDURE `deleteUser`(IN useridValue int(11))   
  4.   
  5. begin  
  6.   
  7.     delete from tbl_user where userid = useridValue;   
  8.   
  9. end;  


三.             编程前准备工作

1.    建立工程

在进入代码编写前,建立新的java工程proc, 目录结构如下:

proc

   -lib

    -bin

    -src

      -com

        -amigo

          -proc

            -model

2.    引入所需包

   将hibernate3.0的包以及其相关包放入编译路径中,另注意:还需将mysql的数据库驱动jar包mysql-connector-java-5.0.4-bin.jar放入编译路径中。



四.             编码与测试

在准备工作完成后,进入编码与测试阶段,本例演示了在hibernate3.0中调用mysql的存储过程的方法。

1、hibernate的配置文件

在hibernate的配置文件中包含数据库的连接信息,以及加入OR mapping的xml格式的映射文件,该文件如下(部分内容略):
……
Xml代码 复制代码
  1. <property name="connection.url">jdbc:mysql://localhost:3306/test</property>  
  2.   
  3. <property name="connection.username">root</property>  
  4.   
  5. <property name="connection.password">root</property>  
  6.   
  7. <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
  8.   
  9. <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  
  10.   
  11. <property name="show_sql">true</property>  
  12.   
  13. <mapping resource="com/amigo/proc/model/User.hbm.xml"/>   

    ……

2、OR Mapping文件

产生的OR Mapping文件有User.java以及其对应的hibernate映射文件User.hbm.xml。其中User.java的内容如下:
Java代码 复制代码
  1. package com.amigo.proc.model;   
  2.   
  3.     
  4.   
  5. /** *//**  
  6.  
  7.  * 用户信息对象  
  8.  
  9.  */  
  10.   
  11. public class User implements java.io.Serializable {   
  12.   
  13.     private static final long serialVersionUID = 1L;   
  14.   
  15.     /** *//** 用户id*/  
  16.   
  17.     private String userid;   
  18.   
  19.     /** *//** 用户姓名*/  
  20.   
  21.     private String name;   
  22.   
  23.     /** *//** 用户blog*/  
  24.   
  25.     private String blog;   
  26.   
  27. //省略get/set方法   
  28.   
  29. }  


User.hbm.xml文件的内容如下:
Xml代码 复制代码
  1. <?xml version="1.0"?>  
  2.   
  3. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
  4.   
  5. "http://hibernate./hibernate-mapping-3.0.dtd">  
  6.   
  7.     
  8.   
  9. <hibernate-mapping package="com.amigo.proc.model">  
  10.   
  11.     <class name="User" table="tbl_user">  
  12.   
  13.         <id name="userid" column="userid">  
  14.   
  15.             <generator class="assigned"/>  
  16.   
  17.         </id>  
  18.   
  19.         <property name="name" column="name" type="string" />  
  20.   
  21.         <property name="blog" column="blog" type="string" />  
  22.   
  23.     </class>  
  24.   
  25.        
  26.   
  27.     <sql-query name="getUserList" callable="true">  
  28.   
  29.         <return alias="user" class="User">  
  30.   
  31.             <return-property name="userid" column="userid"/>  
  32.   
  33.             <return-property name="name" column="name"/>  
  34.   
  35.             <return-property name="blog" column="blog" />  
  36.   
  37.         </return>  
  38.   
  39.         {call getUserList()}   
  40.   
  41.     </sql-query>  
  42.   
  43. </hibernate-mapping>  


在该文件中需注意<sql-query…></sql-query>中的这段代码,调用的存储过程在其中定义,并定义了调用存储过程后将记录组装成User对象,同时对记录的字段与对象的属性进行相关映射。

3.    管理hibernate的session以及事务的类HibernateSessionFactory

该类包括打开session等方法,主要用于管理hibernate的session和事务。该类的内容如下(部分内容略):


Java代码 复制代码
  1. package com.amigo.proc;   
  2.   
  3. import java.io.ByteArrayOutputStream;   
  4.   
  5. import java.io.OutputStreamWriter;   
  6.   
  7.     
  8.   
  9. import org.hibernate.HibernateException;   
  10.   
  11. import org.hibernate.Session;   
  12.   
  13. import org.hibernate.SessionFactory;   
  14.   
  15. import org.hibernate.Transaction;   
  16.   
  17. import org.hibernate.cfg.Configuration;   
  18.   
  19. /** *//**  
  20.  
  21.  * Hibernate相关控制  
  22.  
  23.  */  
  24.   
  25. public class HibernateSessionFactory {   
  26.   
  27.     /** *//** Hibernate配置文件 */  
  28.   
  29.     private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";   
  30.   
  31.     
  32.   
  33.     /** *//** 存储一个单独的session实例 */  
  34.   
  35.     private static final ThreadLocal threadLocal = new ThreadLocal();   
  36.   
  37.     
  38.   
  39.     /** *//** Hibernate配置相关的一个实例 */  
  40.   
  41.     private static Configuration configuration = null;   
  42.   
  43.     
  44.   
  45.     /** *//** Hibernate SessionFactory的一个实例 */  
  46.   
  47.     private static SessionFactory sessionFactory;   
  48.   
  49.     
  50.   
  51.     /** *//** Hibernate的字符编码集*/  
  52.   
  53.     private static String charSet;   
  54.   
  55.     /** *//** 若Hibernate未设置字符编码集时,采用的字符编码集*/  
  56.   
  57.     private static final String encoding = (new OutputStreamWriter(   
  58.   
  59.             new ByteArrayOutputStream())).getEncoding();   
  60.   
  61.     
  62.   
  63.     /** *//**  
  64.  
  65.      * 默认构造函数  
  66.  
  67.      */  
  68.   
  69.     public HibernateSessionFactory() {   
  70.   
  71.     }   
  72.   
  73.     
  74.   
  75.     /** *//**  
  76.  
  77.      * 打开Hibernate的数据库连接  
  78.  
  79.      */  
  80.   
  81.     public static final synchronized void open() {   
  82.   
  83.         if (sessionFactory != null)   
  84.   
  85.             return;   
  86.   
  87.         try {   
  88.   
  89.             sessionFactory = getConfiguration().buildSessionFactory();   
  90.   
  91.             charSet = configuration.getProperty("hibernate.connection.charSet");   
  92.   
  93.             if (charSet == null)   
  94.   
  95.                 charSet = encoding;   
  96.   
  97.             return;   
  98.   
  99.         } catch (Throwable throwable) {   
  100.   
  101.             throw new ExceptionInInitializerError(throwable);   
  102.   
  103.         }   
  104.   
  105.     }   
  106.   
  107.     
  108.   
  109.     /** *//**  
  110.  
  111.      * 配置Hibernate数据库,并将其打开  
  112.  
  113.      */  
  114.   
  115.     private static synchronized void configure() throws HibernateException {   
  116.   
  117.         if (sessionFactory == null) {   
  118.   
  119.             if (configuration == null) {   
  120.   
  121.                 getConfiguration().configure(CONFIG_FILE_LOCATION);   
  122.   
  123.             }   
  124.   
  125.             open();   
  126.   
  127.         }   
  128.   
  129.     }   
  130.   
  131.     
  132.   
  133.     /** *//**  
  134.  
  135.      * 获得配置实例  
  136.  
  137.      */  
  138.   
  139.     public static synchronized final Configuration getConfiguration() {   
  140.   
  141.         if (configuration == null) {   
  142.   
  143.             configuration = new Configuration();   
  144.   
  145.         }   
  146.   
  147.         return configuration;   
  148.   
  149.     }   
  150.   
  151.     
  152.   
  153.     /** *//**  
  154.  
  155.      * 功能说明:获得SessionFactory  
  156.  
  157.      */  
  158.   
  159.     public static final SessionFactory getSessionFactory() {   
  160.   
  161.         return sessionFactory;   
  162.   
  163.     }   
  164.   
  165.     
  166.   
  167.     /** *//**  
  168.  
  169.      * 功能说明:获得session  
  170.  
  171.      */  
  172.   
  173.     public static final Session getSession() throws HibernateException {   
  174.   
  175.         configure();   
  176.   
  177.         Session session = null;   
  178.   
  179.         if (threadLocal.get() == null) {   
  180.   
  181.             session = getSessionFactory().openSession();   
  182.   
  183.             threadLocal.set(session);   
  184.   
  185.         } else {   
  186.   
  187.             try {   
  188.   
  189.                 session = (Session)threadLocal.get();   
  190.   
  191.             } catch(Exception ex) {   
  192.   
  193.                 session = getSessionFactory().openSession();   
  194.   
  195.                 threadLocal.set(session);   
  196.   
  197.             }   
  198.   
  199.         }   
  200.   
  201.         return session;   
  202.   
  203.     }   
  204.   
  205.     //其余方法略   
  206.   
  207. }  

4. hibernate调用存储过程的测试类

本类是该例的核心类,在本类中,以实例清楚地说明了在hibernate中如何调用存储过程,例示了hibernate调用查询、更新、插入和删除这四类存储过程的方法,该类的内容如下:

Java代码 复制代码
  1. package com.amigo.proc;   
  2.   
  3.     
  4.   
  5. import java.sql.CallableStatement;   
  6.   
  7. import java.sql.Connection;   
  8.   
  9. import java.sql.PreparedStatement;   
  10.   
  11. import java.util.List;   
  12.   
  13.     
  14.   
  15. import com.amigo.proc.model.User;   
  16.   
  17.     
  18.   
  19. import org.hibernate.Session;   
  20.   
  21. import org.hibernate.Transaction;   
  22.   
  23.     
  24.   
  25. /** *//**  
  26.  
  27.  * hibernate调用存储过程  
  28.  
  29.  * @author Amigo Xie(xiexingxing1121@126.com)  
  30.  
  31.  * @since 2007/04/30  
  32.  
  33.  */  
  34.   
  35. public class ProcTest {   
  36.   
  37.     
  38.   
  39.     /** *//**  
  40.  
  41.      * @param args  
  42.  
  43.      */  
  44.   
  45.     public static void main(String[] args) throws Exception {   
  46.   
  47.         ProcTest proc = new ProcTest();   
  48.   
  49.         Session session = HibernateSessionFactory.getSession();   
  50.   
  51.         proc.testProcQuery(session);   
  52.   
  53.         proc.testProcUpdate(session);   
  54.   
  55.         System.out.println("update successfully");   
  56.   
  57.            
  58.   
  59.         proc.testProcInsert(session);   
  60.   
  61.         System.out.println("insert successfully");   
  62.   
  63.            
  64.   
  65.         proc.testProcDelete(session);   
  66.   
  67.         System.out.println("delete successfully");   
  68.   
  69.         session.close();   
  70.   
  71.     }   
  72.   
  73.        
  74.   
  75.     /** *//**  
  76.  
  77.      * 测试实现查询的存储过程  
  78.  
  79.      * @throws Exception  
  80.  
  81.      */  
  82.   
  83.     private void testProcQuery(Session session) throws Exception {   
  84.   
  85.         //查询用户列表   
  86.   
  87.         List list = session.getNamedQuery("getUserList").list();   
  88.   
  89.         for (int i = 0; i < list.size(); i++) {   
  90.   
  91.             User user = (User) list.get(i);       
  92.   
  93.             System.out.print("序号: " + (i+1));   
  94.   
  95.             System.out.print(", userid: " + user.getUserid());   
  96.   
  97.             System.out.print(", name: " + user.getName());   
  98.   
  99.             System.out.println(", blog: " + user.getBlog());   
  100.   
  101.         }   
  102.   
  103.     }   
  104.   
  105.        
  106.   
  107.     /** *//**  
  108.  
  109.      * 测试实现更新的存储过程  
  110.  
  111.      * @throws Exception  
  112.  
  113.      */  
  114.   
  115.     private void testProcUpdate(Session session) throws Exception {   
  116.   
  117.         //更新用户信息   
  118.   
  119.         Transaction tx = session.beginTransaction();    
  120.   
  121.         Connection con = session.connection();    
  122.   
  123.         String procedure = "{call updateUser(?, ?, ?)}";    
  124.   
  125.         CallableStatement cstmt = con.prepareCall(procedure);    
  126.   
  127.         cstmt.setString(1"陈xx");   
  128.   
  129.         cstmt.setString(2"http://www./sterningChen");   
  130.   
  131.         cstmt.setString(3"sterning");   
  132.   
  133.         cstmt.executeUpdate();    
  134.   
  135.         tx.commit();   
  136.   
  137.     }   
  138.   
  139.     
  140.   
  141.     /** *//**  
  142.  
  143.      * 测试实现插入的存储过程  
  144.  
  145.      * @throws Exception  
  146.  
  147.      */  
  148.   
  149.     private void testProcInsert(Session session) throws Exception {   
  150.   
  151.         //创建用户信息   
  152.   
  153.         session.beginTransaction();   
  154.   
  155.         PreparedStatement st = session.connection().prepareStatement("{call createUser(?, ?, ?)}");   
  156.   
  157.         st.setString(1"amigo");   
  158.   
  159.         st.setString(2"阿蜜果");   
  160.   
  161.         st.setString(3"http://www.w/amigoxie");   
  162.   
  163.         st.execute();   
  164.   
  165.         session.getTransaction().commit();    
  166.   
  167.     }   
  168.   
  169.        
  170.   
  171.     /** *//**  
  172.  
  173.      * 测试实现删除的存储过程  
  174.  
  175.      * @throws Exception  
  176.  
  177.      */  
  178.   
  179.     private void testProcDelete(Session session) throws Exception {   
  180.   
  181.         //删除用户信息   
  182.   
  183.         session.beginTransaction();   
  184.   
  185.         PreparedStatement st = session.connection().prepareStatement("{call deleteUser(?)}");   
  186.   
  187.         st.setString(1"amigo");   
  188.   
  189.         st.execute();   
  190.   
  191.         session.getTransaction().commit();   
  192.   
  193.     }   
  194.   
  195. }  

   在本类中,调用查询类存储过程时,调用session.getNamedQuery("…")方法来获得User.hbm.xml中配置的查询存储过程。在其余的存储过程调用的测试中,首先通过hibernate的session获得connection,然后调用connection对象的相应方法来实现存储过程的调用。

该类的执行结果如下:

Hibernate: {call getUserList()}

序号: 1, userid: ant, name: 蚂蚁, blog: http://www./qixiangnj

序号: 2, userid: beansoft, name: bean, blog: http://www./beansoft

序号: 3, userid: sterning, name: 似水流年, blog: http://www./sterning

序号: 4, userid: tom, name: tom, blog: http://www./tom

update successfully

insert successfully

delete successfully

五.总结
   本例提出了在hibernate3中调用mysql的存储过程的实现方案,从本例可以看出,hibernate提供了在*.hbm.xml中配置调用存储过程,并通过向用户提供session.getNamedQuery(“…”)方法来调用配置的调用查询相关的存储过程的方法,另外,hibernate还提供了取得sql的connection的方法,从而能够通过connection中存储过程调用相关的方法来实现存储过程的调用。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多