為了在 Hibernate 中使用存儲過程,你必須遵循一些規則。不遵循這些規則的存儲過程將不可用。如果你仍然想使用他們,你必須通過 session.connection() 來執行他們。這些規則針對于不同的數據庫。因為數據庫提供商有各種不同的存儲過程語法和語義。
對存儲過程進行的查詢無法使用 setFirstResult()/setMaxResults() 進行分頁。
建議采用的調用方式是標準 SQL92: { ? = call functionName(<parameters>) } 或者 { ? = call procedureName(<parameters>) }。原生調用語法不被支持。
對于 Oracle 有如下規則:
對于 Sybase 或者 MS SQL server 有如下規則:
?
?
?http://www.iteye.com/topic/176032
Java代碼
CREATE TABLE `proctab` (
`id` int ( 11 ) NOT NULL auto_increment,
`Name` varchar ( 20 ),
`age` int ( 11 ),
PRIMARY KEY (`id`)
)
簡單的存儲過程
Java代碼
create PROCEDURE proc()beginselect * from proctab;end ;
一種方法是通過hibernate傳統的xml映射方式去調用
Java代碼
<class name="com.test.User" table="proctab"><id name="id" column="id"><generator class="native"/></id><property name="name" column="name" type="string" /><property name="age" column="age" type="integer" />
</class><sql-query name="getUser" callable="true"><return alias="user" class="com.test.User"><return-property name="id" column="id" /><return-property name="name" column="name" /><return-property name="age" column="age" /></return>{call proc()}</sql-query>
調用方法
Java代碼
Session ss= HibernateSessionFactory.getSession()List li=ss.getNamedQuery("getUser").list();ss.close();
及其類似jdbc的方法
Java代碼
Session session =HibernateSessionFactory.getSession();
Connection conn = session.connection();
ResultSet rs =null;
CallableStatement call = conn.prepareCall("{Call proc()}");
rs = call.executeQuery();
rs.close();
session.close();
這種方法基本上就是jdbc,不過很簡單,總是感覺怪怪的~! 還有就是通過強大的createSQLQuery來實現 o(∩_∩)o...哈哈? 個人比較喜歡這種方法
Java代碼
Session session =HibernateSessionFactory.getSession();
SQLQuery query = session.createSQLQuery("{Call proc()}");
List list =query.list();
session.close();
如果沒有返回值 直接用execute的方法就可以了 (*^__^*)? 忘了一個重要的問題就是存儲過程的傳參問題
Java代碼?? CallableStatement call = conn.prepareCall("{Call proc(?)}");
call.setString(1, 參數);
rs = call.executeQuery();
?
Java代碼
?
========================
http://dishell.iteye.com/blog/298217
摘要:本文以詳盡的實例展示了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代碼? 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語句如下:
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
Sql代碼
DROP PROCEDURE IF EXISTS `getUserList`;CREATE PROCEDURE `getUserList`()beginselect * from tbl_user;end;
2. 通過傳入的參數創建用戶的存儲過程--createUser
Sql代碼
DROP PROCEDURE IF EXISTS `createUser`;CREATE PROCEDURE `createUser`(IN userid varchar(50), IN name varchar(50), IN blog varchar(50))begininsert into tbl_user values(userid, name, blog);end;
3. 通過傳入的參數更新用戶信息的存儲過程--updateUser
Sql代碼
DROP PROCEDURE IF EXISTS `updateUser`;
CREATE PROCEDURE `updateUser`(IN nameValue varchar(50), IN blogValue varchar(50), IN useidValue varchar(50))
beginupdate tbl_user set name = nameValue, blog = blogValue where userid = useridValue;
end;
4. 刪除用戶信息的存儲過程--deleteUser
Sql代碼
DROP PROCEDURE IF EXISTS `deleteUser`;
CREATE PROCEDURE `deleteUser`(IN useridValue int(11))
begindelete from tbl_user where userid = useridValue;
end;
三 編程前準備工作 1. 建立工程 在進入代碼編寫前,建立新的java工程proc, 目錄結構如下:
Java代碼
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代碼
……<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的內容如下:
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代碼
<?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和事務。該類的內容如下(部分內容略):
Java代碼
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調用查詢、更新、插入和刪除這四類存儲過程的方法,該類的內容如下:
Java代碼
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對象的相應方法來實現存儲過程的調用。 該類的執行結果如下:
Java代碼
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/tomupdate successfullyinsert successfullydelete successfully
五.總結 ?? 本例提出了在hibernate3中調用mysql的存儲過程的實現方案,從本例可以看出,hibernate提供了在*.hbm.xml中配置調用存儲過程,并通過向用戶提供session.getNamedQuery(“…”)方法來調用配置的調用查詢相關的存儲過程的方法 ,另外,hibernate還提供了取得sql的connection的方法,從而能夠通過connection中存儲過程調用相關的方法來實現存儲過程的調用。 ?
總結
以上是生活随笔 為你收集整理的通过hibernate去调用存储过程 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。