目录
1.1Hibernate中实现连接查询技术及应用实例. (2)
1.1.1设计项目中相关的数据库表 (2)
1.1.2构建数据库访问项目中的hibernate.cfg.xml配置文件 (2)
1.1.3构建相关的PO类 (3)
1.1.4构建PO类的XML映射配置定义文件 (8)
1.1.5构建创建SessionFactory对象的HibernateUtil类 (10)
1.1.6构建数据库访问类 (11)
1.1.7构建数据库访问类的测试类 (16)
1.1Hibernate中实现连接查询技术及应用实例. 1.1.1设计项目中相关的数据库表
1、学生信息表
CREATE TABLE `studentinfo` (
`studentName` varchar(255) DEFAULT NULL,
`studentID` int(11) NOT NULL DEFAULT '0',
`studentMajor` varchar(255) DEFAULT NULL,
`collegeID` int(11) DEFAULT NULL,
PRIMARY KEY (`studentID`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
INSERT INTO `studentinfo` V ALUES ('张三', '1', '计算机应用', '1'); INSERT INTO `studentinfo` V ALUES ('李四', '2', '网络应用', '2');
2、相互关联的学院信息表
CREATE TABLE `collegeinfo` (
`collegeID` int(11) NOT NULL DEFAULT '0',
`collegeName` varchar(255) DEFAULT NULL,
PRIMARY KEY (`collegeID`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
INSERT INTO `collegeinfo` V ALUES ('1', '计算机学院'); INSERT INTO `collegeinfo` V ALUES ('2', '网络学院');
1.1.2构建数据库访问项目中的hibernate.cfg.xml配置文件
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://www.sodocs.net/doc/769882883.html,/dtd/hibernate-configuration-3.0.dtd">
1.1.3构建相关的PO类
1、StudentInfoPO类
package com.px1987.hebernate.po;
public class StudentInfoPO {
public StudentInfoPO() {
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public Integer getStudentID() {
return studentID;
}
public void setStudentID(Integer studentID) {
this.studentID = studentID;
}
public String getStudentMajor() {
return studentMajor;
}
public void setStudentMajor(String studentMajor) {
this.studentMajor = studentMajor;
}
public CollegeInfoPO getStudentCollegeInfoPO() {
return studentCollegeInfoPO;
}
public void setStudentCollegeInfoPO(CollegeInfoPO studentCollegeInfoPO) { this.studentCollegeInfoPO = studentCollegeInfoPO;
}
private String studentName;
private Integer studentID;
private String studentMajor;
/**
* 实现studentinfo表和collegeinfo之间的一对一关联,在StudentInfoPO类中不再需要定义出collegeID属性,
* 因为它为外键关联字段。
*/
private CollegeInfoPO studentCollegeInfoPO;
}
2、CollegeInfoPO类
package com.px1987.hebernate.po;
import java.util.Set;
public class CollegeInfoPO {
public CollegeInfoPO() {
}
public Integer getCollegeID() {
return collegeID;
}
public void setCollegeID(Integer collegeID) {
this.collegeID = collegeID;
}
public String getCollegeName() {
return collegeName;
}
public void setCollegeName(String collegeName) {
this.collegeName = collegeName;
}
public Set
return allStudentInCollege;
}
public void setAllStudentInCollege(Set
this.allStudentInCollege = allStudentInCollege;
}
private Integer collegeID;
private String collegeName;
/**
* 实现collegeinfo表和studentinfo之间的一对多关联
*/
private Set
}
3、组合StudentAndCollegeInfoPO类
该组合StudentAndCollegeInfoPO类主要用来存放查询出的结果集,整体当成一个PO对象,在该组合StudentAndCollegeInfoPO类中至少需要包含有查询的各个目标变量,并且需要一个无参构造方法和一个包含所有要查询的参数的构造方法。
package com.px1987.hebernate.po;
public class StudentAndCollegeInfoPO {
public StudentAndCollegeInfoPO() {
}
public StudentAndCollegeInfoPO(Integer studentID,String studentName,String studentMajor,
Integer collegeID,String collegeName) {
this.studentID =studentID;
this.studentName =studentName;
this.studentMajor =studentMajor;
this.collegeID =collegeID;
this.collegeName =collegeName;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) { this.studentName = studentName;
}
public Integer getStudentID() {
return studentID;
}
public void setStudentID(Integer studentID) { this.studentID = studentID;
}
public String getStudentMajor() {
return studentMajor;
}
public void setStudentMajor(String studentMajor) { this.studentMajor = studentMajor;
}
public Integer getCollegeID() {
return collegeID;
}
public void setCollegeID(Integer collegeID) { this.collegeID = collegeID;
}
public String getCollegeName() {
return collegeName;
}
public void setCollegeName(String collegeName) {
this.collegeName = collegeName;
}
private String studentName;
private Integer studentID;
private String studentMajor;
private Integer collegeID;
private String collegeName;
}
1.1.4构建PO类的XML映射配置定义文件
1、StudentInfoPO.hbm.xml
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://www.sodocs.net/doc/769882883.html,/hibernate-mapping-3.0.dtd">
column="collegeID" unique="true" lazy="false" /> 注意,在Hibernate中实现各种连接查询,如果在数据访问类中使用HQL查询语句,那么在hibernate的O/R Mapping映射配置文件中,必须要配置关联映射——比如:多对一或者一对多等形式;当然,也可以用Hibernate的DAO类中应用createSQLQuery方法,就可以不用写HQL语句,而是直接用SQL语句查询,就像JDBC那样。 2、CollegeInfoPO.hbm.xml PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "https://www.sodocs.net/doc/769882883.html,/hibernate-mapping-3.0.dtd"> 1.1.5构建创建SessionFactory对象的HibernateUtil类 package com.px1987.hebernate.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory; static{ try{ sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { throw new ExceptionInInitializerError(ex); } } public static final ThreadLocal threadLocal = new ThreadLocal(); public static Session getCurrentSession() { Session currentSession = (Session) threadLocal.get(); if (currentSession == null) { currentSession = sessionFactory.openSession(); threadLocal.set(currentSession); } return currentSession; } public static void closeCurrentSession(){ Session currentSession = (Session) threadLocal.get(); if (currentSession != null) currentSession.close(); threadLocal.set(null); } } 1.1.6构建数据库访问类 package com.px1987.hebernate.dao; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import com.px1987.hebernate.po.CollegeInfoPO; import com.px1987.hebernate.po.StudentInfoPO; import com.px1987.hebernate.util.HibernateUtil; public class StudentInfoCRUD { public StudentInfoCRUD() { } public List Session session = null; Transaction tx = null; List try { /** * (1)首先获得session对象 */ session = HibernateUtil.getCurrentSession(); /** * (2)启动事务 */ tx = session.beginTransaction(); /** * (3)下面为具体的数据访问操作的代码(根据不同的应用要求改变) */ Query oneQuery=session.createQuery(queryStudentInfoHQL); allQueryResultList = oneQuery.list(); https://www.sodocs.net/doc/769882883.html,mit(); } catch (HibernateException he){ if (tx != null){ /** * (4)恢复前面所完成的修改行为 */ tx.rollback(); } throw he; } finally { /** (5)由于由Hibernate抛出的异常都视为不可以恢复的,因此应该确保在finally 代码块中 调用close()方法,以关闭掉Session。 */ HibernateUtil.closeCurrentSession(); } return allQueryResultList; } public List Session session = null; Transaction tx = null; List try { /** * (1)首先获得session对象 */ session = HibernateUtil.getCurrentSession(); /** * (2)启动事务 */ tx = session.beginTransaction(); /** * (3)下面为具体的数据访问操作的代码(根据不同的应用要求改变) */ Query oneQuery=session.createQuery(queryCollegeInfoHQL); allQueryResultList = oneQuery.list(); https://www.sodocs.net/doc/769882883.html,mit(); } catch (HibernateException he){ if (tx != null){ /** * (4)恢复前面所完成的修改行为 */ tx.rollback(); } throw he; } finally { /** (5)由于由Hibernate抛出的异常都视为不可以恢复的,因此应该确保在finally 代码块中 调用close()方法,以关闭掉Session。 */ HibernateUtil.closeCurrentSession(); } return allQueryResultList; } public List doQueryStudentAndCollegeInfo(String someOnequeryHQL) throws HibernateException{ Session session = null; Transaction tx = null; List allQueryResultList=null; try { /** * (1)首先获得session对象 */ session = HibernateUtil.getCurrentSession(); /** * (2)启动事务 */ tx = session.beginTransaction(); /** * (3)下面为具体的数据访问操作的代码(根据不同的应用要求改变) */ Query oneQuery=session.createQuery(someOnequeryHQL); allQueryResultList = oneQuery.list(); https://www.sodocs.net/doc/769882883.html,mit(); } catch (HibernateException he){ if (tx != null){ /** * (4)恢复前面所完成的修改行为 */ tx.rollback(); } throw he; } finally { /** (5)由于由Hibernate抛出的异常都视为不可以恢复的,因此应该确保在finally 代码块中 调用close()方法,以关闭掉Session。 */ HibernateUtil.closeCurrentSession(); } return allQueryResultList; } } 1.1.7构建数据库访问类的测试类 package com.px1987.hebernate.testdao; import java.util.Iterator; import java.util.List; import java.util.Set; import com.px1987.hebernate.dao.StudentInfoCRUD; import com.px1987.hebernate.po.CollegeInfoPO; import com.px1987.hebernate.po.StudentAndCollegeInfoPO; import com.px1987.hebernate.po.StudentInfoPO; public class TestStudentInfoCRUD { public TestStudentInfoCRUD() { } /** * 下面的方法是测试“一对一”关联映射 */ public void testDoQueryStudentInfo() { StudentInfoCRUD oneStudentInfoCRUD=new StudentInfoCRUD(); String queryStudentInfoHQL="from com.px1987.hebernate.po.StudentInfoPO "; List allQueryResultList =oneStudentInfoCRUD.doQueryStudentInfo(queryStudentInfoHQL); Iterator while(someStudentInfoList.hasNext()){ StudentInfoPO someOneStudentInfoPO =(StudentInfoPO)someStudentInfoList.next(); System.out.println(someOneStudentInfoPO.getStudentName()+","+ someOneStudentInfoPO.getStudentMajor()); CollegeInfoPO studentCollegeInfoPO =someOneStudentInfoPO.getStudentCollegeInfoPO(); System.out.println(studentCollegeInfoPO.getCollegeID()+","+studentCollegeInfoPO.getColleg eName()); } } /** * 迫切内连接可以解决在 * class="com.px1987.hebernate.po.CollegeInfoPO" column="collegeID" unique="true" lazy="true" />中的“lazy="true"的查询问题,直接在代码中决定 是否需要立即加载关联的“一对一”或者“一对多”中的目标对象数据。 */ public void testInnerJoinFetchQuery() { StudentInfoCRUD oneStudentInfoCRUD=new StudentInfoCRUD(); /** * 不能使用如下的查询语句,否则将会出现query specified join fetching, but the owner of the fetched * association was not present in the select list的异常错误信息。 String someOnequeryHQL="select new com.px1987.hebernate.po.StudentAndCollegeInfoPO(studentInfo.studentName,collegeInfo.college Name) "+ "from com.px1987.hebernate.po.StudentInfoPO as studentInfo "+ " inner join fetch "+ "studentInfo.studentCollegeInfoPO as collegeInfo "; */ String queryStudentInfoHQL="select studentInfo "+ "from com.px1987.hebernate.po.StudentInfoPO as studentInfo "+ " inner join fetch "+ "studentInfo.studentCollegeInfoPO as collegeInfo "; List allQueryResultList =oneStudentInfoCRUD.doQueryStudentInfo(queryStudentInfoHQL); Iterator while(someStudentInfoList.hasNext()){ StudentInfoPO someOneStudentInfoPO =(StudentInfoPO)someStudentInfoList.next(); System.out.println(someOneStudentInfoPO.getStudentName()+","+ someOneStudentInfoPO.getStudentMajor()); CollegeInfoPO studentCollegeInfoPO =someOneStudentInfoPO.getStudentCollegeInfoPO(); System.out.println(studentCollegeInfoPO.getCollegeID()+","+studentCollegeInfoPO.getColleg eName()); } } /** * 下面的方法是测试“一对多”关联映射 */ public void testDoQueryCollegeInfo() { StudentInfoCRUD oneStudentInfoCRUD=new StudentInfoCRUD(); String queryCollegeInfoHQL="from com.px1987.hebernate.po.CollegeInfoPO"; List allQueryResultList =oneStudentInfoCRUD.doQueryCollegeInfo(queryCollegeInfoHQL); Iterator while(someCollegeInfoList.hasNext()){ CollegeInfoPO someOneCollegeInfoPO =(CollegeInfoPO)someCollegeInfoList.next(); System.out.println(someOneCollegeInfoPO.getCollegeID()+","+someOneCollegeInfoPO.getC ollegeName()); Set =someOneCollegeInfoPO.getAllStudentInCollege(); Iterator someStudentInfoList =allStudentInCollege.iterator(); while(someStudentInfoList.hasNext()){ StudentInfoPO someOneStudentInfoPO =(StudentInfoPO)someStudentInfoList.next(); System.out.println(someOneStudentInfoPO.getStudentName()+","+ someOneStudentInfoPO.getStudentMajor()); } } } /** *内连接所对应的两个数据库表的PO类必须要进行“多对一”或者“一对多”的关联定义,否则在数据访问时将会出现 *DOT node with no left-hand-side!的错误;其中的“inner join”可以简化为“join”;下面的方法实现等值 *内连接 * public void testInnerJoinQuery_EqualValue() { StudentInfoCRUD oneStudentInfoCRUD=new StudentInfoCRUD(); /** 下面的HQL语句的连接条件为studentInfo.collegeID = collegeInfo.collegeID,并且可以自定义返回数据的PO对象 String someOnequeryHQL="select new com.px1987.hebernate.po.StudentAndCollegeInfoPO(studentInfo.studentName,collegeInfo.college Name) "+ "from com.px1987.hebernate.po.StudentInfoPO as studentInfo "+ " inner join "+ "studentInfo.studentCollegeInfoPO as collegeInfo "; */ /** * 注意其中的连接数据的过滤条件可以采用标准SQL语句中的where(如:where collegeInfo.collegeID =1), * 也可以采用Hibernate自己的条件with(with collegeInfo.collegeID =1);但最终的连接方式仍然为等值连接: * 也就是连接条件仍然为studentInfo.collegeID = collegeInfo.collegeID */ String someOnequeryHQL="select new com.px1987.hebernate.po.StudentAndCollegeInfoPO(studentInfo.studentName,collegeInfo.college Name) "+ "from com.px1987.hebernate.po.StudentInfoPO as studentInfo "+ " inner join "+ "studentInfo.studentCollegeInfoPO as collegeInfo "+ "with collegeInfo.collegeID =1";