`
24334784
  • 浏览: 19934 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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

阅读更多
原文出处: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,建表语句如下:
 DROP TABLE IF EXISTS `user`;

CREATE TABLE `tbl_user` (

  `userid` varchar(50) NOT NULL,

  `name` varchar(50) default '',

  `blog` varchar(50) default '',

  PRIMARY KEY (`userid`)

) ENGINE=InnoDB DEFAULT CHARSET=gb2312;



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

INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('ant', '蚂蚁', 'http://www.blogjava.net/qixiangnj');

INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('beansoft', 'bean', 'http://www.blogjava.net/beansoft');

INSERT INTO `tbl_user` (`userid`,`name`,`blog`) VALUES ('sterning', '似水流年', 'http://www.blogjava.net/sterning');

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

DROP PROCEDURE IF EXISTS `getUserList`;

CREATE PROCEDURE `getUserList`()

begin

     select * from tbl_user;

end;



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

DROP PROCEDURE IF EXISTS `createUser`;

CREATE PROCEDURE `createUser`(IN userid varchar(50), IN name varchar(50), IN blog varchar(50))

begin

    insert into tbl_user values(userid, name, blog);

end;




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

DROP PROCEDURE IF EXISTS `updateUser`;

CREATE PROCEDURE `updateUser`(IN nameValue varchar(50), IN blogValue varchar(50), IN useidValue varchar(50))

begin

    update tbl_user set name = nameValue, blog = blogValue where userid = useridValue;

end;




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

DROP PROCEDURE IF EXISTS `deleteUser`;

CREATE PROCEDURE `deleteUser`(IN useridValue int(11))

begin

    delete from tbl_user where userid = useridValue;

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格式的映射文件,该文件如下(部分内容略):
……
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>

        <property name="connection.username">root</property>

        <property name="connection.password">root</property>

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <property name="show_sql">true</property>

        <mapping resource="com/amigo/proc/model/User.hbm.xml"/> 

    ……

2、OR Mapping文件

产生的OR Mapping文件有User.java以及其对应的hibernate映射文件User.hbm.xml。其中User.java的内容如下:
package com.amigo.proc.model;

 

/** *//**

 * 用户信息对象

 */

public class User implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    /** *//** 用户id*/

    private String userid;

    /** *//** 用户姓名*/

    private String name;

    /** *//** 用户blog*/

    private String blog;

//省略get/set方法

}


User.hbm.xml文件的内容如下:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping package="com.amigo.proc.model">

    <class name="User" table="tbl_user">

        <id name="userid" column="userid">

            <generator class="assigned"/>

        </id>

        <property name="name" column="name" type="string" />

        <property name="blog" column="blog" type="string" />

    </class>

    

    <sql-query name="getUserList" callable="true">

        <return alias="user" class="User">

            <return-property name="userid" column="userid"/>

            <return-property name="name" column="name"/>

            <return-property name="blog" column="blog" />

        </return>

        {call getUserList()}

    </sql-query>

</hibernate-mapping>


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

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

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


package com.amigo.proc;

import java.io.ByteArrayOutputStream;

import java.io.OutputStreamWriter;

 

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

/** *//**

 * Hibernate相关控制

 */

public class HibernateSessionFactory {

    /** *//** Hibernate配置文件 */

    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";

 

    /** *//** 存储一个单独的session实例 */

    private static final ThreadLocal threadLocal = new ThreadLocal();

 

    /** *//** Hibernate配置相关的一个实例 */

    private static Configuration configuration = null;

 

    /** *//** Hibernate SessionFactory的一个实例 */

    private static SessionFactory sessionFactory;

 

    /** *//** Hibernate的字符编码集*/

    private static String charSet;

    /** *//** 若Hibernate未设置字符编码集时,采用的字符编码集*/

    private static final String encoding = (new OutputStreamWriter(

            new ByteArrayOutputStream())).getEncoding();

 

    /** *//**

     * 默认构造函数

     */

    public HibernateSessionFactory() {

    }

 

    /** *//**

     * 打开Hibernate的数据库连接

     */

    public static final synchronized void open() {

        if (sessionFactory != null)

            return;

        try {

            sessionFactory = getConfiguration().buildSessionFactory();

            charSet = configuration.getProperty("hibernate.connection.charSet");

            if (charSet == null)

                charSet = encoding;

            return;

        } catch (Throwable throwable) {

            throw new ExceptionInInitializerError(throwable);

        }

    }

 

    /** *//**

     * 配置Hibernate数据库,并将其打开

     */

    private static synchronized void configure() throws HibernateException {

        if (sessionFactory == null) {

            if (configuration == null) {

                getConfiguration().configure(CONFIG_FILE_LOCATION);

            }

            open();

        }

    }

 

    /** *//**

     * 获得配置实例

     */

    public static synchronized final Configuration getConfiguration() {

        if (configuration == null) {

            configuration = new Configuration();

        }

        return configuration;

    }

 

    /** *//**

     * 功能说明:获得SessionFactory

     */

    public static final SessionFactory getSessionFactory() {

        return sessionFactory;

    }

 

    /** *//**

     * 功能说明:获得session

     */

    public static final Session getSession() throws HibernateException {

        configure();

        Session session = null;

        if (threadLocal.get() == null) {

            session = getSessionFactory().openSession();

            threadLocal.set(session);

        } else {

            try {

                session = (Session)threadLocal.get();

            } catch(Exception ex) {

                session = getSessionFactory().openSession();

                threadLocal.set(session);

            }

        }

        return session;

    }

    //其余方法略

}


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

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

package com.amigo.proc;

 

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.util.List;

 

import com.amigo.proc.model.User;

 

import org.hibernate.Session;

import org.hibernate.Transaction;

 

/** *//**

 * hibernate调用存储过程

 * @author Amigo Xie(xiexingxing1121@126.com)

 * @since 2007/04/30

 */

public class ProcTest {

 

    /** *//**

     * @param args

     */

    public static void main(String[] args) throws Exception {

        ProcTest proc = new ProcTest();

        Session session = HibernateSessionFactory.getSession();

        proc.testProcQuery(session);

        proc.testProcUpdate(session);

        System.out.println("update successfully");

        

        proc.testProcInsert(session);

        System.out.println("insert successfully");

        

        proc.testProcDelete(session);

        System.out.println("delete successfully");

        session.close();

    }

    

    /** *//**

     * 测试实现查询的存储过程

     * @throws Exception

     */

    private void testProcQuery(Session session) throws Exception {

        //查询用户列表

        List list = session.getNamedQuery("getUserList").list();

        for (int i = 0; i < list.size(); i++) {

            User user = (User) list.get(i);    

            System.out.print("序号: " + (i+1));

            System.out.print(", userid: " + user.getUserid());

            System.out.print(", name: " + user.getName());

            System.out.println(", blog: " + user.getBlog());

        }

    }

    

    /** *//**

     * 测试实现更新的存储过程

     * @throws Exception

     */

    private void testProcUpdate(Session session) throws Exception {

        //更新用户信息

        Transaction tx = session.beginTransaction(); 

        Connection con = session.connection(); 

        String procedure = "{call updateUser(?, ?, ?)}"; 

        CallableStatement cstmt = con.prepareCall(procedure); 

        cstmt.setString(1, "陈xx");

        cstmt.setString(2, "http://www.blogjava.net/sterningChen");

        cstmt.setString(3, "sterning");

        cstmt.executeUpdate(); 

        tx.commit();

    }

 

    /** *//**

     * 测试实现插入的存储过程

     * @throws Exception

     */

    private void testProcInsert(Session session) throws Exception {

        //创建用户信息

        session.beginTransaction();

        PreparedStatement st = session.connection().prepareStatement("{call createUser(?, ?, ?)}");

        st.setString(1, "amigo");

        st.setString(2, "阿蜜果");

        st.setString(3, "http://www.wblogjava.net/amigoxie");

        st.execute();

        session.getTransaction().commit(); 

    }

    

    /** *//**

     * 测试实现删除的存储过程

     * @throws Exception

     */

    private void testProcDelete(Session session) throws Exception {

        //删除用户信息

        session.beginTransaction();

        PreparedStatement st = session.connection().prepareStatement("{call deleteUser(?)}");

        st.setString(1, "amigo");

        st.execute();

        session.getTransaction().commit();

    }

}

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

该类的执行结果如下:

Hibernate: {call getUserList()}

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

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

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

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

update successfully

insert successfully

delete successfully

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

相关推荐

    Spring.3.x企业应用开发实战(完整版).part2

    11.2.6 调用存储过程 11.3 BLOB/CLOB类型数据的操作 11.3.1 如何获取本地数据连接 11.3.2 相关的操作接口 11.3.3 插入Lob类型的数据 11.3.4 以块数据方式读取Lob数据 11.3.5 以流数据方式读取Lob数据 11.4 自增键和...

    Spring3.x企业应用开发实战(完整版) part1

    11.2.6 调用存储过程 11.3 BLOB/CLOB类型数据的操作 11.3.1 如何获取本地数据连接 11.3.2 相关的操作接口 11.3.3 插入Lob类型的数据 11.3.4 以块数据方式读取Lob数据 11.3.5 以流数据方式读取Lob数据 11.4 自增键和...

    ssh(structs,spring,hibernate)框架中的上传下载

     需要指定的是Spring 1.2.5提供了两套Hibernate的支持包,其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,...

    Java 面试宝典

    3、说说&和&&的区别。 ............................................................................................... 8 4、在 JAVA 中如何跳出当前的多重嵌套循环? .........................................

    Spring中文帮助文档

    使用SimpleJdbcCall调用存储过程 11.5.6. 声明SimpleJdbcCall使用的参数 11.5.7. 如何定义SqlParameters 11.5.8. 使用SimpleJdbcCall调用内置函数 11.5.9. 使用SimpleJdbcCall返回的ResultSet/REF Cursor 11.6...

    Spring API

    使用SimpleJdbcCall调用存储过程 11.5.6. 声明SimpleJdbcCall使用的参数 11.5.7. 如何定义SqlParameters 11.5.8. 使用SimpleJdbcCall调用内置函数 11.5.9. 使用SimpleJdbcCall返回的ResultSet/REF Cursor 11.6...

    Spring攻略(第二版 中文高清版).part2

    11.11.3 工作原理 472 11.12 使用GORM查询 475 11.12.1 问题 475 11.12.2 解决方案 475 11.12.3 工作原理 475 11.13 创建自定义标记 477 11.13.1 问题 477 11.13.2 解决方案 477 11.13.3 工作原理...

    Spring攻略(第二版 中文高清版).part1

    11.11.3 工作原理 472 11.12 使用GORM查询 475 11.12.1 问题 475 11.12.2 解决方案 475 11.12.3 工作原理 475 11.13 创建自定义标记 477 11.13.1 问题 477 11.13.2 解决方案 477 11.13.3 工作原理...

    JAVA上百实例源码以及开源项目

    2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户...

    JAVA上百实例源码以及开源项目源代码

    FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户可以在终端上...

    Spring in Action(第二版 中文高清版).part2

    第一部分 Spring的核心 第1章 开始Spring之旅 ...B.3 使用Spring进行综合测试 B.3.1 测试装配后的对象 B.3.2 综合测试事务处理对象 B.3.3 测试数据库 B.3.4 使用Gienah Testing在JUnit 4中进行测试 B.4 小结

    Spring in Action(第二版 中文高清版).part1

    第一部分 Spring的核心 第1章 开始Spring之旅 ...B.3 使用Spring进行综合测试 B.3.1 测试装配后的对象 B.3.2 综合测试事务处理对象 B.3.3 测试数据库 B.3.4 使用Gienah Testing在JUnit 4中进行测试 B.4 小结

    最新Java面试宝典pdf版

    22、用JDBC如何调用存储过程 109 23、JDBC中的PreparedStatement相比Statement的好处 110 24. 写一个用jdbc连接并访问oracle数据的程序代码 111 25、Class.forName的作用?为什么要用? 111 26、大数据量下的分页解决...

    Java面试笔试资料大全

    22、用JDBC如何调用存储过程 109 23、JDBC中的PreparedStatement相比Statement的好处 110 24. 写一个用jdbc连接并访问oracle数据的程序代码 111 25、Class.forName的作用?为什么要用? 111 26、大数据量下的分页解决...

Global site tag (gtag.js) - Google Analytics