hibernate调用存储过程

摘要:本文以详尽的实例展示了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.blogjava.net/qixiangnj');  
  2.   
  3. INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('beansoft''bean''http://www.blogjava.net/beansoft');  
  4.   
  5. INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('sterning''似水流年''http://www.blogjava.net/sterning');  
  6.   
  7. INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('tom''tom' , 'http://www.blogjava.net/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. CREATE PROCEDURE `updateUser`(IN nameValue varchar(50), IN blogValue varchar(50), IN useidValue varchar(50))  
  3. begin  
  4.     update tbl_user set name = nameValue, blog = blogValue where userid = useridValue;  
  5. end;  

4. 删除用户信息的存储过程--deleteUser 
Sql代码   收藏代码
  1. DROP PROCEDURE IF EXISTS `deleteUser`;  
  2. CREATE PROCEDURE `deleteUser`(IN useridValue int(11))  
  3. begin  
  4.     delete from tbl_user where userid = useridValue;  
  5. end;  


三 编程前准备工作 

1. 建立工程 

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

Java代码   收藏代码
  1. proc  
  2.   
  3.    -lib  
  4.   
  5.     -bin  
  6.   
  7.     -src  
  8.   
  9.       -com  
  10.   
  11.         -amigo  
  12.   
  13.           -proc  
  14.   
  15.             -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. ……  
  2.         <property name="connection.url">jdbc:mysql://localhost:3306/test</property>  
  3.   
  4.         <property name="connection.username">root</property>  
  5.   
  6.         <property name="connection.password">root</property>  
  7.   
  8.         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
  9.   
  10.         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  
  11.   
  12.         <property name="show_sql">true</property>  
  13.   
  14.         <mapping resource="com/amigo/proc/model/User.hbm.xml"/>   
  15.   
  16.     ……  


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. public class User implements java.io.Serializable {  
  10.   
  11.     private static final long serialVersionUID = 1L;  
  12.   
  13.     /** *//** 用户id*/  
  14.   
  15.     private String userid;  
  16.   
  17.     /** *//** 用户姓名*/  
  18.   
  19.     private String name;  
  20.   
  21.     /** *//** 用户blog*/  
  22.   
  23.     private String blog;  
  24.   
  25. //省略get/set方法  
  26.   
  27. }  

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

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

   在本类中,调用查询类存储过程时,调用session.getNamedQuery("…")方法来获得User.hbm.xml中配置的查询存储过程。在其余的存储过程调用的测试中,首先通过hibernate的session获得connection,然后调用connection对象的相应方法来实现存储过程的调用。 
该类的执行结果如下: 
Java代码   收藏代码
  1. Hibernate: {call getUserList()}  
  2. 序号: 1, userid: ant, name: 蚂蚁, blog: http://www.blogjava.net/qixiangnj  
  3.   
  4. 序号: 2, userid: beansoft, name: bean, blog: http://www.blogjava.net/beansoft  
  5.   
  6. 序号: 3, userid: sterning, name: 似水流年, blog: http://www.blogjava.net/sterning  
  7.   
  8. 序号: 4, userid: tom, name: tom, blog: http://www.blogjava.net/tom  
  9.   
  10. update successfully  
  11.   
  12. insert successfully  
  13.   
  14. delete successfully  

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

你可能感兴趣的:(mysql,Hibernate,session,测试,Blog,存储)