Hibernate關聯映射及高級查詢

来源:http://www.cnblogs.com/ablejava/archive/2016/08/06/5731018.html
-Advertisement-
Play Games

一、Hibernate中的關聯關係 1.1、單向一對多關聯關係 按照以下步驟配置hibernate中持久化類的一對多對象關聯: (1).持久化類添加關聯類的相關屬性及getter/setter方法。 (2).映射文件中建立該屬性和資料庫表欄位的映射信息。 比如班級對學生是一對多的關係,班級類Grad ...


一、Hibernate中的關聯關係

1.1、單向一對多關聯關係

按照以下步驟配置hibernate中持久化類的一對多對象關聯:

(1).持久化類添加關聯類的相關屬性及getter/setter方法。

(2).映射文件中建立該屬性和資料庫表欄位的映射信息。

比如班級對學生是一對多的關係,班級類Grade類和Grade.hbm.xml文件如下:

package com.pb.hibernate.po;

import java.util.HashSet;
import java.util.Set;

public class Grade {
	private int gid;
	private String gname;
	private String gdesc;
	private Set students=new HashSet();
	
	public Set getStudents() {
		return students;
	}
	public void setStudents(Set students) {
		this.students = students;
	}
	public int getGid() {
		return gid;
	}
	public void setGid(int gid) {
		this.gid = gid;
	}
	public String getGname() {
		return gname;
	}
	public void setGname(String gname) {
		this.gname = gname;
	}
	public String getGdesc() {
		return gdesc;
	}
	public void setGdesc(String gdesc) {
		this.gdesc = gdesc;
	}
	public Grade() {
		super();
	}
	public Grade(int gid, String gname, String gdesc, Set students) {
		super();
		this.gid = gid;
		this.gname = gname;
		this.gdesc = gdesc;
		this.students = students;
	}	

}

  Grade.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 >

    <class name="com.pb.hibernate.po.Grade" table="GRADE" lazy="false" schema="scott">
        <id name="gid" type="java.lang.Integer">
        	<column name="GID"></column>
        	<generator class="assigned"></generator>
        </id>
        <property name="gname" type="java.lang.String">
        	<column name="GNAME" length="20" not-null="true"></column>
        </property>
        <property name="gdesc" type="java.lang.String">
        	<column name="GDESC" length="50"></column>
        </property>
        <set name="students" cascade="save-update" inverse="true">
        	<key column="GID"></key> <!--學生表的外鍵 -->
        	<one-to-many class="com.pb.hibernate.po.Student"/> <!-- 一對多關聯關係one-to-many -->
        </set>
    </class>

</hibernate-mapping>

  使用<set>元素和<one-to-many>元素配置一對多關係,<set>元素常用屬性如下:

1.name:關聯類屬性的名稱,是必須填寫,沒有預設值。

2.table:關聯類的目標資料庫表,可以不關聯數據表,沒有預設值。

3.lazy:指定關聯對象延遲載入策略,預設為true.

4.fetch:設置抓取數據的策略,預設為select.

5.inverse:描述對象之間關聯關係的維護方式,預設為false.

1.2、單向多對一關聯關係

多對一關聯關係和配置一對多關聯關係步驟一樣,不同的是在配置文件中使用<many-to-one>元素配置多對一關聯。

package com.pb.hibernate.po;

import java.util.HashSet;
import java.util.Set;

public class Student {
	private int sid;
	private String sname;
	private String sex;
	private Grade grade;// 定義班級屬性
	private Paper paper;
	private Set courses=new HashSet();
	
	public Set getCourses() {
		return courses;
	}
	public void setCourses(Set courses) {
		this.courses = courses;
	}
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	public Grade getGrade() {
		return grade;
	}
	public void setGrade(Grade grade) {
		this.grade = grade;
	}
	
	public Paper getPaper() {
		return paper;
	}
	public void setPaper(Paper paper) {
		this.paper = paper;
	}
	public Student() {
		super();
	}	

}

  在Student.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 >

    <class name="com.pb.hibernate.po.Student" table="STUDENT" schema="scott">
        <id name="sid" column="SID" type="java.lang.Integer">
            <generator class="assigned"/> 
        </id>
        <property name="sname" type="java.lang.String">
        	<column name="SNAME" length="20" not-null="true"></column>
        </property>
        <property name="sex" type="java.lang.String">
        	<column name="SEX" length="20"></column>
        </property>
        <!-- 配置學生與班級關聯關係 -->
        <many-to-one name="grade" class="com.pb.hibernate.po.Grade">
        	<column name="GID"></column>
        </many-to-one>
        <one-to-one name="paper" class="com.pb.hibernate.po.Paper" cascade="all" property-ref="student"></one-to-one>
        <set name="courses" table="SC_HIB" cascade="save-update">
        	<key column="sid"></key>
        	<many-to-many class="com.pb.hibernate.po.Course" column="cid"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

1.3、雙向一對多關聯關係:

單向一對多和單向多對一可以分別配置使用,如果同時配置了兩者,就成了雙向一對多關聯關係,其實在上面就完成了雙向一對多關聯關係。

1.4、一對一關聯關係

資料庫表的一對一關聯關係可以通過主鍵關聯以及外鍵關聯實現,常使用外鍵進行關聯。

使用學生表Student和學生證表paper是一對一關聯,xml配置文件如下:

Student表的hibernate.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 >

    <class name="com.pb.hibernate.po.Paper" table="PAPER" schema="scott">
        <id name="pid" column="PID" type="int">
            <generator class="assigned"/> 
        </id>
        <property name="pdesc" type="string">
        	<column name="PDESC" length="50" not-null="true"></column>
        </property>
        <many-to-one name="student" class="com.pb.hibernate.po.Student" unique="true">
        	<column name="SID"></column>
        </many-to-one>
    </class>

</hibernate-mapping>

 需要註意的是在Student.hbm.xml中,<one-to-one>並不需要指定屬性所對應的數據表的列,而是通過paperty-ref指向paper類中的關聯對象屬性student,在paper.hbm.xml中添加了屬性upique="true"的<many-to-one>作用等同與<one-to-one>。

1.5、多對多關聯關係

Hibernate中多對多對象關聯的實現方式有一下兩種:

1.不創建中間表的持久化類,只創建兩端資料庫表的持久化類,在映射文件中使用<many-to-many>標簽設置映射。

2.創建中間表,兩端數據表的持久化類,針對中間表的持久化類分別和兩端的資料庫表的持久化類創建一對多關聯。

資料庫中多對多關聯關係是通過中間表實現的,通過中間表,將兩個表之間的多對多關聯關係分別轉換為它們和中間表之間的一對多關聯關係。

使用學生Student對課程Course之間的多對多關聯關係為例設置多對多關聯關係,其中Student類的xml文件的配置已經在上面描述,下麵是Course類的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 >

    <class name="com.pb.hibernate.po.Course" table="COURSE_HIB" schema="scott">
        <id name="cid" column="CID" type="int">
            <generator class="assigned"/> 
        </id>
        <property name="cname" type="string">
        	<column name="CNAME" length="20" not-null="true"></column>
        </property>
        <property name="cdesc" type="string">
        	<column name="CDESC" length="50"></column>
        </property>
        <set name="students" table="SC_HIB" cascade="save-update" inverse="true">
        	<key column="cid"></key>
        	<many-to-many class="com.pb.hibernate.po.Student" column="sid"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

  在配置Student對象和Course對象時候我們註意到有兩個屬性:cascade(級聯)和inverse(反轉)

1.cascade屬性:級聯操作是指當主控方執行某項操作時,是否要對被關聯放也執行相同的操作,常用的有<many-to-one/>,<one-to-one/>,<set/>,使用cascade屬性的常用值如下:

(1).all:對所有操作進行級聯操作。

(2).save-update:執行保存和更新操作時進行級聯操作。

(3).delete:執行刪除操作時進行級聯操作。

(4).none:對所有操作不進行級聯操作。

2.inverse屬性:是對象之間關聯關係的維護方式,它可以將維護關聯關係的任務反轉,由對方完成,inverse只存在與集合標記的元素中,inverse為true時,數量為一的一方反轉關聯關係維護給多的一方,inverse為false時為主動方,有主動方負責維護關聯關係。

二、Hibernate檢索方式

Hibernate中提供了一下幾種在資料庫中檢索對象的方式:

(1).導航對象圖檢索方式:根據已經載入的對象,導航到其他對象,如關聯對象的查詢。

(2).OID檢索方式:按照對象的OID來檢索對象。

(3).HQL檢索方式:使用專門的HQL查詢介面和麵向對象的HQL查詢語言。

(4).QBC(Query By Criteria)檢索方式:QBC提供的API來檢索對象,這種API封裝了基於字元串形式的查詢語言,提供了更加面向對象的查詢介面。

(5).本地SQL檢索方式:這也是官方推薦的標準查詢方式。

2.1、HQL查詢

HQL(Hibernate Query Language)是Hibernate提供的一種面向對象的查詢語言,HQL提供了了更加豐富靈活並且強大的功能。

>使用HQL可以避免使用JDBC查詢的一些弊端,不需要再編寫複雜的sql,將針對實體類及屬性進行查詢。

>查詢結果直接放在List中的對象中,不需要,再次封裝。

>獨立於資料庫,對不同的資料庫根據Hibernate dialect屬性自動生成不同的sql語句。

 Query介面是HQL查詢介面,提供了各種查詢功能,它相當於JDBC的Statement和PreparedStatement,通過Session的createQuery創建其對象。理解其list()與iterate()方法的查詢機制,將有助於查詢性能的優化。

>list()方法返回List對象,iterate()方法直接返回Iterator對象。

>list()方法將不會在緩存中讀取數據,它總是一次性地從資料庫中直接查詢所有符合條件的數據,同時將獲取的數據寫入緩存。

>iterate()方法是獲取符合條件的數據的id後,需要時根據id在緩存中尋找符合條件的數據,若緩存中沒有符合條件的數據,再到資料庫中查詢。

HibernateUtil工具類:

package com.pb.hibernate.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	/**
	 * 初始化一個ThreadLocal對象,ThreadLocal對象有get(),set()方法;
	 */
	private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>();

	private static Configuration conf;
	private static  SessionFactory sf;
	//靜態代碼塊,只執行一次
	static{
		try {
			//解析配置文件
			conf=new Configuration().configure();
			//創建sesssion工廠
			sf=conf.buildSessionFactory();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 得到session對象,同時設置session對象到ThreadLocal對象
	 * 確保一個線程用一個session對象,而不是多個線程共用一個session對象
	 * @return 從ThradLocal對象中得到的session對象
	 */
	public static Session getCurrentSession(){
		//多線程不公用session
		Session session=sessionTL.get();
		if (session==null) {
			//得到session對象
			session=sf.openSession();
			//將session對象保存到threadLocal對象中
			sessionTL.set(session);
		}
		
		
		return session;
	}
	/**
	 * 關閉session ,同時從ThreadLocal對象中清除緩存
	 */
	public static void closeSession(){
		Session session =sessionTL.get();
		sessionTL.set(null);//先清空threadLocal
		session.close();
	}
	
}

  DAO層使用hql查詢:

/**
	 * 通過hql語句的query.list()方法得到所有的像的集合
	 * @return
	 */
	public List<Dept> getAll(){
		//1.得到session
		Session session=HibernateUtil.getCurrentSession();
		//2.hql語句
		String hql="from Dept";
		//得到query對象
		Query query=session.createQuery(hql);
		List<Dept> list=query.list();
		return list;
	}

2.2、屬性查詢

屬性查詢只查找持久化類的部分屬性而不是全部屬性,通過屬性查詢有兩種方式:

(1).通過直接指定屬性進行屬性查詢,例如:

      /**
	 * @param deptName
	 * @param location
	 * @return
	 */
	public List<Dept> getDeptByNameAndLoc(String deptName,String location){
		Session session=HibernateUtil.getCurrentSession();
		String hql="select deptName,location from Dept";
		Query query=session.createQuery(hql);
		List<Object[]> list2=query.list();
		for (Object[] objects : list2) {
			System.out.println(objects[0]+""+objects[1]);
		}
		return null;
	}

(2).通過構造方法進行屬性查詢,使用這種方法需要持久化類中添加相應的構造方法。

      /**
	 * @param deptName
	 * @param location
	 * @return
	 */
	public List<Dept> getDeptByNameAndLoc(String deptName,String location){
		Session session=HibernateUtil.getCurrentSession();
		String hql="select new Dept( deptName,location) from Dept";
		Query query=session.createQuery(hql);
		List<Object[]> list2=query.list();
		for (Object[] objects : list2) {
			System.out.println(objects[0]+""+objects[1]);
		}
		return null;
	}

2.3、參數綁定

(1).使用"?"占位符。

public List<Dept> getDeptByDeptName(String deptName){
		Session session=HibernateUtil.getCurrentSession();
		String hql="from Dept where deptName like ? ";
		Query query=session.createQuery(hql);
		//setXxx ;Xxx:數據類型
		query.setString(0,"%"+deptName+"%");
		List<Dept> list=query.list();
		return list;
	}

(2).使用命名參數。

//參數名稱綁定參數
	public List<Dept> get(){
		Session session=HibernateUtil.getCurrentSession();
		//命名參數
		String hql="from Dept where deptName=:deptName";
		Query query=session.createQuery(hql);
		/**
		 * 實體類以及對應的映射文件,自動生成
		 * 方向工程
		 */
		query.setString("deptName", "deptName");
// query.setParameter("deptName","deptName"); List<Dept> list=query.list(); for (Dept dept : list) { System.out.println(dept.getDeptName()); } return null; }

2.4、Hibernate分頁

       /**
	 * 通過hql語句的query.list()方法得到所有的像的集合
	 * 分頁查詢
	 * @return
	 */
	public List<Dept> getAll(int pageIndex){
		//1.得到session
		Session session=HibernateUtil.getCurrentSession();
		//2.hql語句
		String hql="from Dept";
		//得到query對象
		Query query=session.createQuery(hql);
		
		/**
		 * 每頁顯示2條數據
		 * 顯示第五頁
		 */
		query.setMaxResults(3);//pageSize每頁顯示多少條數據
		query.setFirstResult((pageIndex-1)*3);//設置第一個,不包括第一個數據(pageIndex-1)*pageSize
		
		
		List<Dept> list=query.list();
		return list;
	}

       /**
	 * 得到總頁數
	 * @param deptName
	 * @return
	 */
	public int getTotalCount(String deptName){
		Session session=HibernateUtil.getCurrentSession();
		StringBuffer hql=new StringBuffer("select count(*) from Dept where 1=1");
		List params=new ArrayList();
		if (deptName!=null&&!"".equals(deptName)) {
			hql.append(" and deptName like ?");
			params.add("%"+deptName+"%");
		}
		Query query=session.createQuery(hql.toString());
		for (int i = 0; i < params.size(); i++) {
			query.setParameter(i, params.get(i));//第二個參數放入的是Object類型
		}
		long count =(Long)query.uniqueResult();
		int totalCount=(int)count;
		if (totalCount%3==0) {
			return totalCount/3;
		}else {
			return totalCount/3+1;
		}
	}

2.5、Criteria查詢概述

Criteria查詢(Query By Criteria, QBC)是與HQL完全不同的一種查詢機制。Criteria查詢又稱對象查詢,它採用對象的方式,封裝查詢條件,並提供了Restriction等類型做輔助,可以使編寫查詢代碼更加方便。

使用Criteria的示例:

    /**
	 * 使用Criteria查詢
	 */
	public Dept getDeptByCriteria(){
		try {
			Session session=HibernateUtil.getCurrentSession();
			Criteria criteria = session.createCriteria(Dept.class);
			Dept dept=(Dept) criteria.uniqueResult();
			return dept;
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return null;
	}
	public Dept getDeptByCriteriaUseRestrictions(){
		try {
			Session session=HibernateUtil.getCurrentSession();
			Criteria criteria = session.createCriteria(Dept.class);
			criteria.add(Restrictions.eq("deptNo", "101"));// 添加限制條件
			//criteria.addOrder(Order.desc("deptNo"));排序
			Dept dept=(Dept) criteria.uniqueResult();
			return dept;
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return null;
	}

在Criteria查詢中使用Example示例查詢:

在使用Criteria查詢時,設定查詢條件並非一定使用Restrictions,如果屬性條件更多,使用Restrictions也不方便,Criteria允許先創建一個對象模板,以這樣一個對象模板作為查詢依據,查詢出來屬性與類似的對象。也就是依照已有的對象,查詢與其屬性相同或者相似的其他對象,這種查詢也稱示例查詢(Query By Example,QBE)。

public List<Dept> getDeptByExample(){
		List<Dept> result = null;
		try {
			Session session=HibernateUtil.getCurrentSession();
			Dept dept = new Dept();
			dept.setLocation("上海");
			Criteria criteria = session.createCriteria(Dept.class);
			/**
			 * Hibernate在自動生成SQL語句時,將自動過濾對象的空屬性,
			 * 根據有非空屬性生成查詢條件,如果要想更加精準可以設置更多屬性值
			 */
			criteria.add(Example.create(dept));
			result = criteria.list();
			return result;
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return null;
	}

使用Criteria實現統計、分組、分頁:

/**
	 * 使用Criteria查詢
	 */
	public List<Dept> getDeptByCriteria(){
		List<Dept> result = null;
		try {
			Session session=HibernateUtil.getCurrentSession();
			Criteria criteria = session.createCriteria(Dept.class);
			criteria.setProjection(Projections.projectionList()
					.add(Projections.groupProperty("deptName")) // 按部門名稱分組
					.add(Projections.rowCount()) // 統計所有記錄數
					.add(Projections.avg("deptName"))// 統計平均數
					.add(Projections.max("deptNo")));// 求最大
			result= criteria.list();
			return result;
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return null;
	}
	//分頁
	public List<Dept> getDeptByCriteriaPage(){
		List<Dept> result = null;
		try {
			Session session=HibernateUtil.getCurrentSession();
			Criteria criteria = session.createCriteria(Dept.class);
			criteria.setFirstResult(1);
			criteria.setMaxResults(3);
			result= criteria.list();
			return result;
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return null;
	}

2.6、命名HQL查詢

在Dept.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 >

    <class name="com.jbit.hwd.entity.Dept" table="DEPT">
        <id name="deptNo">
        	<column name="DEPTNO"></column>
        	<generator class="sequence">
        		<param name="sequence">seq_dept</param>
        	</generator>
        </id>
        <!-- 略-->
    </class>
 <query name="dept">
    	<![CDATA[
    		from Dept d where d.deptNo=:deptNo 
    	]]>
    </query>
</hibernate-mapping>

  查詢:

public List<Dept> getDeptByCriteria(){
		List<Dept> result = null;
		try {
			Session session=HibernateUtil.getCurrentSession();
			Query query = session.getNamedQuery("dept");
			Dept dept = new Dept();
			dept.setDeptNo(101);
			query.setProperties(dept);
			result= query.list();
			return result;
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return null;
	}

2.7、DetachedCriteria查詢

public List<StudentExam> getAllExamByExamId(Integer examId,
			String[] classIds) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(getEntityClass());
		detachedCriteria.add(Restrictions.eq("exam.id", examId));
		detachedCriteria.add(Restrictions.eq("isDelete",
				MySchoolConstant.IS_DELETED_NO));

		boolean error = false;
		Integer[] intClassIds = new Integer[classIds.length];
		for (int i = 0; i < classIds.length; i++) {
			if (StringUtils.isEmpty(classIds[i])) {
				error = true;
				break;
			}
			intClassIds[i] = Integer.valueOf(classIds[i]);
		}
		if (!error && intClassIds.length > 0) {
			detachedCriteria.add(Restrictions.in("classId", intClassIds));
		}
		return findList(detachedCriteria);
	}

2.8、本地sql查詢

HQL查詢並不能涵蓋所有的查詢特性,一些複雜的查詢還必須藉助sql達到期望的目標,也就是本地sql,使用query.createSQLQuery(String sql)方法,同時使用addEntity()方法將別名與實體類關聯起來。

public ZAnswer findStudentZAnswerListByParams(Integer recruitId,Integer examId,Integer questionId,Integer userId) {
		StringBuffer sql = new StringBuffer();
		sql.append(" SELECT * FROM Z_ANSWER t  ");
		sql.append(" WHERE t.`IS_DELETED` = 0 ");
		sql.append(" AND t.`RECRUIT_ID` = :recruitId ");
		sql.append(" AND t.`EXAM_ID` = :examId ");
		sql.append(" AND t.`TEST_QUESTION_ID` = :questionId ");
		sql.append(" AND t.`ANSWER_USER_ID` = :userId ");
		sql.append(" ORDER BY t.`IS_CURRENT` DESC,t.`CREATE_TIME` DESC ");
		
		
		Query query = this.getSession().createSQLQuery(sql.toString()).addEntity(ZAnswer.class);
		query.setParameter("recruitId", recruitId);
		query.setParameter("examId", examId);
		query.setParameter("questionId", questionId);
		query.setParameter("userId", userId);
		
		@SuppressWarnings("unchecked")
		List<ZAnswer> result = query.list();
		
		//取得第一條記錄
		ZAnswer answer = null;
		
		//排除重覆
		if(result.size() > 0){
			
			answer = (ZAnswer) result.get(0);
			
			for (ZAnswer zAnswer : result) {
				if(zAnswer.getId() != answer.getId()){
					zAnswer.setIsDelete(1);
					this.update(zAnswer);
				}
			}		
		}
		
		return answer;
	}

2.9、Hibernate調用存儲過程

創建兩個存儲過程,在存儲過程中in表示輸入,out表示輸出。

  1.根據id查找某條數據:

 CREATE PROCEDURE `findEmpById`(IN id INTEGER(11))
 begin
  select * from emp where empId=id;
end;

  2.根據id查找某個欄位並返回

CREATE PROCEDURE `getNameById`(in id integer(11),out eName varchar(50))
 begin
   select empName into eName from emp where empId=id;
 end;

  調用第一個存儲過程:

package com.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class 調用存儲過程 {

    /**
     * @param args
     * @throws SQLException 
     */
    public static void main(String[] args) throws SQLException {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Connection con = session.connection();
        String sql = "{call findEmpById(?)}";
        CallableStatement cs = con.prepareCall(sql);
        cs.setObject(1, 2);
        ResultSet rs = cs.executeQuery();
        while(rs.next()){
            int id = rs.getInt("empId");
            String name = rs.getString("empName");
            System.out.println(id+"\t"+name);
        }
    }

}

  調用第二個存儲過程:

package com.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class 調用存儲過程1 {

    
    public static void main(String[] args) throws SQLException {
        Configuration config = new Configuration().configure();
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Connection conn = session.connection();
        String sql = "{call getNameById(?,?)}";
        CallableStatement cs = conn.prepareCall(sql);  
        cs.setObject(1, 3); //設置輸出參數
        cs.registerOutParameter(2, java.sql.Types.VARCHAR); //設置第二個參數為輸出參數
        cs.execute(); //調用存儲過程
        String name = cs.getString(2);//獲取輸出參數
        System.out.println(name);
    }

}

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • quartznet 上篇說到quartznet這個東東,topshelf+quartznet有很多不錯的文章,可以查看七七同學的文章(http://www.cnblogs.com/jys509/p/4628926.html)。這裡我主要說說cron表達式,如果玩過linux下定時任務的肯定不陌生。 ...
  • 最近在項目中碰到一個很頭疼的問題,在前端連接事件中寫了一個廣播線程,該廣播線程寫在while迴圈中,但是前臺會有很多個客戶端,沒連接一次就會有一個廣播線程開啟,很吃資源,剛開始我解決這個問題的方法是每次觸發連接事件是檢測一下當前連接數,如果是count_client<=1,就開線程,否則跳過廣播,但 ...
  • 在開發過程中經常需要發佈到開發環境、測試環境或者預發佈環境上給其他同事進行測試驗證效果等等,每次發佈都要備份,拷貝,修改配置文件等等重覆操作非常的麻煩,效率大打折扣,而web部署提供了這樣的解決方案:在服務端安裝Web Deploy服務,由Web Deploy服務完成備份發佈等操作,今天小編就以圖文 ...
  • 一、前言 Treeview控制項常用於遍歷本地文件信息,通常與Datagridview與ImageList搭配。ImageList控制項用於提供小圖片給TreeView控制項,DatagridView通常顯示TreeNode節點下文件及文件夾的信息。 效果圖: 二、代碼 初始化窗體: 初始化DataGri ...
  • 項目架構採用:Asp.Net MVC4.0 + EntityFramework6.0 code first + AutoMapper + Unity(IOC) + SqlServer2012 項目地址:www.xiaoboke.net 這個博客會不斷開發完善哦 歡迎大家去吐槽和提建議,一起學習,一起 ...
  • 使用自動載入和解析url的參數,實現調用到不同的控制器,實現了pathinfo模式和普通的url模式 文件結構: |--Controller |--Index |--Index.php |--Application.php Application.php \Controller\Index\Inde ...
  • 前言:在javaweb開發中自定義標簽的用處還是挺多的。今天和大家一起看自定義標簽是如何實現的。 1:什麼是標簽 標簽是一種XML元素,通過標簽可以使JSP頁面變得簡介易用,而且標簽具有很好的復用性。 2:自定義標簽的標簽庫主要的介面以及類的繼承實現關係圖 3:一步步實現自定義標簽 3.1:Tag接 ...
  • rest api的參數想即能支持application/x-www-form-urlencoded也能支持application/json方式傳參。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...