hibernate关联查询hql,用SQL好还是用HQL好

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&一、Hibernate中的关联关系
1.1、单向一对多关联关系
按照以下步骤配置hibernate中持久化类的一对多对象关联:
(1).持久化类添加关联类的相关属性及getter/setter方法。
(2).映射文件中建立该属性和数据库表字段的映射信息。
比如班级对学生是一对多的关系,班级类Grade类和Grade.hbm.xml文件如下:
package com.pb.hibernate.
import java.util.HashS
import java.util.S
public class Grade {
private Set students=new HashSet();
public Set getStudents() {
public void setStudents(Set students) {
this.students =
public int getGid() {
public void setGid(int gid) {
this.gid =
public String getGname() {
public void setGname(String gname) {
this.gname =
public String getGdesc() {
public void setGdesc(String gdesc) {
this.gdesc =
public Grade() {
public Grade(int gid, String gname, String gdesc, Set students) {
this.gid =
this.gname =
this.gdesc =
this.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&
&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 --&
&/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.
import java.util.HashS
import java.util.S
public class Student {
private G// 定义班级属性
private Set courses=new HashSet();
public Set getCourses() {
public void setCourses(Set courses) {
this.courses =
public int getSid() {
public void setSid(int sid) {
this.sid =
public String getSname() {
public void setSname(String sname) {
this.sname =
public String getSex() {
public void setSex(String sex) {
this.sex =
public Grade getGrade() {
public void setGrade(Grade grade) {
this.grade =
public Paper getPaper() {
public void setPaper(Paper paper) {
this.paper =
public Student() {
  在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"/&
&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&
&/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"/&
&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&
&/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"/&
&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&
&/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.
import org.hibernate.HibernateE
import org.hibernate.S
import org.hibernate.SessionF
import org.hibernate.cfg.C
public class HibernateUtil {
* 初始化一个ThreadLocal对象,ThreadLocal对象有get(),set()方法;
private static final ThreadLocal&Session& sessionTL=new ThreadLocal&Session&();
private static C
private static
//静态代码块,只执行一次
//解析配置文件
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);
* 关闭session ,同时从ThreadLocal对象中清除缓存
public static void closeSession(){
Session session =sessionTL.get();
sessionTL.set(null);//先清空threadLocal
session.close();
  DAO层使用hql查询:
* 通过hql语句的query.list()方法得到所有的像的集合
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();
2.2、属性查询
属性查询只查找持久化类的部分属性而不是全部属性,通过属性查询有两种方式:
(1).通过直接指定属性进行属性查询,例如:
* @param deptName
* @param location
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]);
(2).通过构造方法进行属性查询,使用这种方法需要持久化类中添加相应的构造方法。
* @param deptName
* @param location
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]);
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);
//setXXxx:数据类型
query.setString(0,"%"+deptName+"%");
List&Dept& list=query.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());
2.4、Hibernate分页
* 通过hql语句的query.list()方法得到所有的像的集合
* 分页查询
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();
* 得到总页数
* @param deptName
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)
if (totalCount%3==0) {
return totalCount/3;
return totalCount/3+1;
2.5、Criteria查询概述
Criteria查询(Query By Criteria, QBC)是与HQL完全不同的一种查询机制。Criteria查询又称对象查询,它采用对象的方式,封装查询条件,并提供了Restriction等类型做辅助,可以使编写查询代码更加方便。
使用Criteria的示例:
    /**
* 使用Criteria查询
public Dept getDeptByCriteria(){
Session session=HibernateUtil.getCurrentSession();
Criteria criteria = session.createCriteria(Dept.class);
Dept dept=(Dept) criteria.uniqueResult();
} catch (HibernateException e) {
e.printStackTrace();
public Dept getDeptByCriteriaUseRestrictions(){
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();
} catch (HibernateException e) {
e.printStackTrace();
在Criteria查询中使用Example示例查询:
在使用Criteria查询时,设定查询条件并非一定使用Restrictions,如果属性条件更多,使用Restrictions也不方便,Criteria允许先创建一个对象模板,以这样一个对象模板作为查询依据,查询出来属性与类似的对象。也就是依照已有的对象,查询与其属性相同或者相似的其他对象,这种查询也称示例查询(Query By Example,QBE)。
public List&Dept& getDeptByExample(){
List&Dept& result =
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();
} catch (HibernateException e) {
e.printStackTrace();
使用Criteria实现统计、分组、分页:
* 使用Criteria查询
public List&Dept& getDeptByCriteria(){
List&Dept& result =
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();
} catch (HibernateException e) {
e.printStackTrace();
public List&Dept& getDeptByCriteriaPage(){
List&Dept& result =
Session session=HibernateUtil.getCurrentSession();
Criteria criteria = session.createCriteria(Dept.class);
criteria.setFirstResult(1);
criteria.setMaxResults(3);
result= criteria.list();
} catch (HibernateException e) {
e.printStackTrace();
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&
&!-- 略--&
&query name="dept"&
from Dept d where d.deptNo=:deptNo
&/hibernate-mapping&
public List&Dept& getDeptByCriteria(){
List&Dept& result =
Session session=HibernateUtil.getCurrentSession();
Query query = session.getNamedQuery("dept");
Dept dept = new Dept();
dept.setDeptNo(101);
query.setProperties(dept);
result= query.list();
} catch (HibernateException e) {
e.printStackTrace();
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 =
Integer[] intClassIds = new Integer[classIds.length];
for (int i = 0; i & classIds. i++) {
if (StringUtils.isEmpty(classIds[i])) {
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 =
//排除重复
if(result.size() & 0){
answer = (ZAnswer) result.get(0);
for (ZAnswer zAnswer : result) {
if(zAnswer.getId() != answer.getId()){
zAnswer.setIsDelete(1);
this.update(zAnswer);
2.9、Hibernate调用存储过程
创建两个存储过程,在存储过程中in表示输入,out表示输出。
  1.根据id查找某条数据:
CREATE PROCEDURE `findEmpById`(IN id INTEGER(11))
select * from emp where empId=
  2.根据id查找某个字段并返回
CREATE PROCEDURE `getNameById`(in id integer(11),out eName varchar(50))
select empName into eName from emp where empId=
  调用第一个存储过程:
package com.
import java.sql.CallableS
import java.sql.C
import java.sql.ResultS
import java.sql.SQLE
import org.hibernate.S
import org.hibernate.SessionF
import org.hibernate.cfg.C
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.
import java.sql.CallableS
import java.sql.C
import java.sql.SQLE
import org.hibernate.S
import org.hibernate.SessionF
import org.hibernate.cfg.C
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);
阅读(...) 评论()您现在的位置:&&>>&&>>&&>>&&>>&正文
Hibernate与&MyBatis的比较
&&& 第一章&&&& Hibernate与MyBatis&&& Hibernate 是当前最流行的O/R mapping框架,它出身于sf.net,现在已经成为Jboss的一部分。 Mybatis 是另外一种优秀的O/R mapping框架。目前属于apache的一个子项目。&&& MyBatis 参考资料官网:&&& Hibernate参考资料: &&& 1.1 Hibernate 简介&&& Hibernate对数据库结构提供了较为完整的封装,Hibernate的O/R Mapping实现了POJO 和数据库表之间的映射,以及SQL 的自动生成和执行。程序员往往只需定义好了POJO 到数据库表的映射关系,即可通过Hibernate 提供的方法完成持久层操作。程序员甚至不需要对SQL 的熟练掌握, Hibernate/OJB 会根据制定的逻辑,自动生成对应的SQL 并调用JDBC 接口加以执行。&&& 1.2 MyBatis简介&&& iBATIS 的着力点,则在于POJO 与SQL之间的映射关系。然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定POJO. 相对Hibernate"O/R"而言,iBATIS 是一种"Sql Mapping"的ORM实现。&&& 第二章 开发对比&&& 开发速度&&& Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate.&&& 开发社区&&& Hibernate 与Mybatis都是流行的持久层开发框架,但Hibernate开发社区相对多热闹些,支持的工具也多,更新也快,当前最高版本4.1.8.而Mybatis相对平静,工具较少,当前最高版本3.2.&&& 开发工作量&&& Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。&&& 针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap.而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。&&& 第三章 系统调优对比&&& Hibernate的调优方案&&& 制定合理的缓存策略;&&& 尽量使用延迟加载特性;&&& 采用合理的Session管理机制;&&& 使用批量抓取,设定合理的批处理参数(batch_size);&&& 进行合理的O/R映射设计&&& Mybatis调优方案&&& MyBatis在Session方面和Hibernate的Session生命周期是一致的,同样需要合理的Session管理机制。MyBatis同样具有二级缓存机制。 MyBatis可以进行详细的SQL优化设计。&&& SQL优化方面&&& Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。而Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。&&& Hibernate HQL语句的调优需要将SQL打印出来,而Hibernate的SQL被很多人嫌弃因为太丑了。MyBatis的SQL是自己手动写的所以调整方便。但Hibernate具有自己的日志统计。Mybatis本身不带日志统计,使用Log4j进行日志记录。&&& 扩展性方面&&& Hibernate与具体数据库的关联只需在XML文件中配置即可,所有的HQL语句与具体使用的数据库无关,移植性很好。MyBatis项目中所有的SQL语句都是依赖所用的数据库的,所以不同数据库类型的支持不好。&&& 第四章 对象管理与抓取策略&&& 对象管理&&& Hibernate 是完整的对象/关系映射解决方案,它提供了对象状态管理(state management)的功能,使开发者不再需要理会底层数据库系统的细节。也就是说,相对于常见的 JDBC/SQL 持久层方案中需要管理 SQL 语句,Hibernate采用了更自然的面向对象的视角来持久化
应用中的数据。&&& 换句话说,使用 Hibernate 的开发者应该总是关注对象的状态(state),不必考虑 SQL 语句的执行。这部分细节已经由 Hibernate 掌管妥当,只有开发者在进行系统性能调优的时候才需要进行了解。&&& 而MyBatis在这一块没有文档说明,用户需要对对象自己进行详细的管理。&&& 抓取策略&&& Hibernate对实体关联对象的抓取有着良好的机制。对于每一个关联关系都可以详细地设置是否延迟加载,并且提供关联抓取、查询抓取、子查询抓取、批量抓取四种模式。 它是详细配置和处理的。&&& 而Mybatis的延迟加载是全局配置的。&&& 第五章 缓存机制对比&&& Hibernate缓存&&& Hibernate一级缓存是Session缓存,利用好一级缓存就需要对Session的生命周期进行管理好。建议在一个Action操作中使用一个Session.一级缓存需要对Session进行严格管理。&&& Hibernate二级缓存是SessionFactory级的缓存。 SessionFactory的缓存分为内置缓存和外置缓存。内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据(映射元素据及预定SQL语句等),对于应用程序来说,它是只读的。外置缓存中存放的是数据库数据的副本,其作用和一级缓存类似。二级缓存除了以内存作为介质外,还可以选用硬盘等外部存储设备。二级缓存称为进程级缓存或SessionFactory级缓存,它可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消亡。
【责编:peter】
?&[]?&[]?&[]?&[]?&[]?&[]?&[]?&[]?&[]?&[]
相关产品和培训
 友情推荐链接
 认证培训
 专题推荐
 ? ? ? ? ? ? ? ? ? ?
 今日更新
?&?&?&?&?&?&?&?&?&?&
 社区讨论
 博客论点
 频道精选
 Java 频道导航

我要回帖

更多关于 hibernate hql 子查询 的文章

 

随机推荐