hibernate使用from (select ……)子查询的方法
hibernate 条件查询的一些写法

hibernate 条件查询的一些写法默认分类 2010-09-28 22:14:38 阅读39 评论0 字号:大中小订阅这里定义了两个实体类,是一对多双向关联:public class SimpleConditionQuery extends TestCase { //public void testQuery1(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select id,name from Student s where like '%1%'");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}//使用占位符public void testQuery2(){Session session = HibernateUtil.getSession();session.beginTransaction();// Query query = session.createQuery("select id,name from Student s where like ?"); // query.setParameter(0, "%1%");// List list = query.list();//基于方法链的编程List list = session.createQuery("select id,name from Student s where like ?") .setParameter(0, "%1%").list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}//另外一种写法,:参数名称的方式传递参数public void testQuery3(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select id,name from Student s where like :myname");query.setParameter("myname", "%1%");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}//public void testQuery4(){Session session = HibernateUtil.getSession();session.beginTransaction();List list = session.createQuery("select id,name from Student s where like :myname and s.id=:myid").setParameter("myname", "%1%").setParameter("myid", 12).list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}//支持in,需要使用setParameterList进行参数传递,后一个参数传数组public void testQuery5(){Session session = HibernateUtil.getSession();session.beginTransaction();List list = session.createQuery("select id,name from Student s where s.id in(:myid)") .setParameterList("myid", new Object[]{1,3,5,7,9}).list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}、//分页查询 setFirstResult(),从0开始//setMaxResults,每页显示多少条数据//对象导航查询,在 hql中采用. 进行导航public void testQuery11(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select from Student s where like '%1%'");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){String name = (String) iter.next();System.out.println(name);}session.getTransaction().commit();}//连接查询,内连接,外连接,(左/右连接),//内连public void testQuery12(){Session session = HibernateUtil.getSession();session.beginTransaction();//数据库里,我们查询是这样写Select From A Left Join B On A.id=B.id//仔细看看在hibernate里是怎么写Query query = session.createQuery("select , from Student s join s.classes c where like '%班级9%'");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}//左连接,即,把没有学生的班级也可以加载上来public void testQuery13(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select , from Classes c left join c.students s ");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}//右连接,把没有班级的无业游民也加载上来public void testQuery14(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select , from Classes c right join c.students s ");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}//统计查询public void testQuery15(){Session session = HibernateUtil.getSession();session.beginTransaction();// Query query = session.createQuery("select count(*) from Student ");// List list = query.list();//因为 count(*)得到的是一个单一值,所以可以如下Long count = (Long) session.createQuery("select count(*) from Student").uniqueResult();System.out.println(count);session.getTransaction().commit();}public void testQuery16(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select ,count(*) from Classes c join c.students group by order by ");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]);}session.getTransaction().commit();}//hibernate也提供原生SQL查询,session.createSQLQuery()public void testQuery9(){Session session = HibernateUtil.getSession();session.beginTransaction();List list = null;list = session.createSQLQuery("select * from student").list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+"---"+obj[1]+"---"+obj[2]);}session.getTransaction().commit();}//hibernate 也可以使用外置命名查询,即:sql语句与程序解耦//具体做法,在映射文件中采用 query标签,//<query name="searchStudent">//<![CDATA[// select s form Student s where s.id<?// ]]>// </query>//在代码里采用session.getNamedQuery("searchStudent")public void testQuery10(){Session session = HibernateUtil.getSession();session.beginTransaction();List list = null;list = session.getNamedQuery("searchStudent").setParameter(0, 10).list();Iterator iter = list.iterator();while(iter.hasNext()){Student stu = (Student) iter.next();System.out.println(stu.getId()+"---"+stu.getName());}session.getTransaction().commit();}}//查询多个简单属性,其集合元素是对象数组//数组元素的类型和对应的属性在实体类中的类型一致//数组的长度取决与select中属性的个数public void testQuery2(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select id,name from Student");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+" "+obj[1]);}session.getTransaction().commit();}//如果认为返回数组不够对象化,可以采用hql动态实例化student对象//此时list中为student对象集合,这是,Student实体要提供相应属性的构造函数public void testQuery3(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select new Student(id,name) from Student");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Student stu = (Student) iter.next();System.out.println(stu.getId()+"---"+stu.getName());}session.getTransaction().commit();}//多个属性查询,可以使用别名public void testQuery4(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select s.id, from Student s");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+" "+obj[1]);}session.getTransaction().commit();}//可以使用as命别名public void testQuery5(){Session session = HibernateUtil.getSession();session.beginTransaction();Query query = session.createQuery("select s.id, from Student as s");List list = query.list();Iterator iter = list.iterator();while(iter.hasNext()){Object[] obj = (Object[]) iter.next();System.out.println(obj[0]+" "+obj[1]);}session.getTransaction().commit();}。
hibernate sql写法

hibernate sql写法Hibernate是一个开源的、高效的、强大的Java持久化框架,它提供了面向对象的方式来操作关系型数据库。
使用Hibernate,开发者可以以一种简单、灵活的方式进行数据库操作,而无需编写大量的SQL 语句。
在Hibernate中,我们可以通过编写映射文件或注解来定义实体类与数据库表之间的映射关系,通过Session对象来执行对数据库的操作。
在Hibernate中,SQL语句可以通过多种方式来编写。
下面将针对Hibernate中的SQL编写进行详细介绍。
1. HQL(Hibernate Query Language)Hibernate Query Language(HQL)是一种面向对象的查询语言,它类似于SQL语句,但是使用的是实体类和属性名,而不是表名和列名。
HQL可以实现对实体对象的查询、更新和删除等操作。
以下是HQL的一些常用语法:-查询所有的实体对象:FROM实体类名-条件查询:FROM实体类名WHERE条件-投影查询:SELECT属性列表FROM实体类名-排序查询:FROM实体类名ORDER BY属性ASC/DESC-分页查询:FROM实体类名LIMIT开始位置,查询数量HQL的编写与SQL类似,但是可以直接使用实体类和属性名,从而更加面向对象。
例如,以下HQL语句可以查询出所有年龄大于18岁的用户:FROM User WHERE age > 182.原生SQL查询除了HQL,Hibernate还支持原生的SQL查询。
原生SQL查询可以直接编写传统的SQL语句,但是需要使用Session对象的createNativeQuery方法来执行。
以下是原生SQL查询的一些常用语法:-执行查询:session.createNativeQuery("SELECT * FROM表名").getResultList()-执行更新或删除:session.createNativeQuery("UPDATE/DELETE FROM表名WHERE条件").executeUpdate()-参数绑定:Query.setParameter(参数名,参数值)原生SQL查询可以更灵活地操作数据库,但是需要注意SQL语句的安全性和兼容性问题。
通常使用的Hibernate通常是三种查询及调用

相关文章:∙SSH通用查询DAO(2)∙应用Hibernate3的DetachedCriteria实现分页查询∙基于spring与hibernate的通用分页实现推荐圈子: GT-Grid更多相关推荐通常使用的Hibernate通常是三种:hql查询,QBC查询和QBE查询:1、QBE(Qurey By Example)检索方式QBE是最简单的,但是功能也是最弱的,QBE的功能不是特别强大,仅在某些场合下有用。
一个典型的使用场合就是在查询窗口中让用户输入一系列的查询条件,然后返回匹配的对象。
QBE只支持=和like比较运算符,无法不大区间值,及其或的匹配。
在这种情况下,还是采用HQL检索方式或QBC检索方式。
Java代码1./**2. * @function 根据传递过来的Object,分页显示在数据库中与其匹配的记录3. * @param pageNo4. * 当前页数5. * @param pageSize6. * 每页显示的记录数7. * @param object8. * 将查询条件封装为Object9. * @return 将查询结果封装为Pager返回10. */11.public Pager findPageByExample(int pageNo, int pageSize, Objectobject)12.{13. Pager pager = null;14. try15. {16. Criteria criteria = this.getSession().createCriteria(17. Class.forName(this.getEntity()));18.19. if (object != null)20. {21. criteria.add(Example.create(object).enableLike());22. }23.24. // 获取根据条件分页查询的总行数25. int rowCount = (Integer) criteria.setProjection(26. Projections.rowCount()).uniqueResult();27. criteria.setProjection(null);28.29. criteria.setFirstResult((pageNo - 1) * pageSize);30. criteria.setMaxResults(pageSize);31.32. List result = criteria.list();33.34. pager = new Pager(pageSize, pageNo, rowCount, result);35.36. } catch (RuntimeException re)37. {38. throw re;39. } finally40. {41. return pager;42. }43.44.}注意代码的第20行,即criteria.add(Example.create(object).enableLike());这一行,需将Example.create(object)调用.enableLike()方法,不然不能模糊查询。
Hibernate高级查询技巧

Hibernate高级查询技巧分页查询:在应用系统开发中,尤其是Web应用系统开发中,数据分页是一项普遍而又非常重要的非功能性的技术需求。
因为它对于提高系统运行效率,以及减少客户端与服务器间的通信量都有着非常非常重要的作用。
但是数据分页在系统实现中往往会带来很大的工作量,在基于JDBC的程序中,更是如此,因为不同的数据库提供了不同的数据分页技术(比如MySQL通过它的Limit字句实现数据分页,而Oracle通过它的rownum字句实现数据分页),这不但给实现带来了一定的困难,也为系统在不同数据间的移植带来了问题。
Hibernate通过对不同的数据库提供统一的接口设计,实现了通用化透明化的数据分页机制,比如我们可以通过QBC查询实现数据分页。
如下面代码所示:Criteria criteria=session.createCriteria(User.class);criteria.add(Expression.eq(“age”,20));//从检索结果中获取从第100条开始到第120条结束的20条记录criteria.setFirstResult(100);criteria.setFetchSize(20);同样,在Query接口中也提供了与其一致的方法。
这是Hibernate API提供的数据分页技术,但是有时候我们需要针对某一个底层数据库,提供应用系统统一的数据分页机制。
这时候我们可以通过实现Hibernate中的抽象类net.sf.hibernate.dialect.Dialect在Hibernate3中为org.hibernate.dialect.Dialect,这个抽象类是Hibernate提供的本地方言类,在本地方言类中封装了对各种不同的主流数据库特性的实现,如果需要针对某种数据库提供方言类支持,可以在Hibernate主配置文件中通过配置来指定(配置hibernate.dialect元素),通过对不同的数据库提供相应的dialect实现,可以消除不同数据库间的差异,从而在上层提供了一个透明的,数据库无关的存储层基础。
hibernate hql连接查询语法

Hibernate HQL(Hibernate Query Language)是一种基于SQL 的查询语言,它提供了一种方便的方式来执行数据库查询,同时也可以避免一些SQL 注入等安全问题。
在Hibernate HQL 中,可以使用以下语法进行连接查询:1. 内连接查询(INNER JOIN):```sqlSELECT entity1, entity2FROM entity1INNER JOIN entity2 ON entity1.id = entity2.idWHERE conditions```上面的查询会返回所有`entity1` 和`entity2` 之间存在连接的记录,其中`entity1.id` 和`entity2.id` 相等。
2. 左连接查询(LEFT JOIN):```sqlSELECT entity1, entity2FROM entity1LEFT JOIN entity2 ON entity1.id = entity2.idWHERE conditions```上面的查询会返回所有`entity1` 的记录以及与之相连接的`entity2` 的记录,如果`entity2` 不存在,则返回`null` 值。
3. 右连接查询(RIGHT JOIN):```sqlSELECT entity1, entity2FROM entity2RIGHT JOIN entity1 ON entity1.id = entity2.idWHERE conditions```上面的查询会返回所有`entity2` 的记录以及与之相连接的`entity1` 的记录,如果`entity1` 不存在,则返回`null` 值。
在连接查询中,`entity1` 和`entity2` 表示要连接的两个实体类,`id` 是实体类中的主键属性,`conditions` 是查询条件。
如果需要指定连接的条件,可以在`JOIN` 关键字后面指定连接条件。
hibernate查询数据库的三种方式

Hibernate查询数据库的三种方式一、Hibernate的HQL与SQL查询1.Hql(Hibernate Query Language)是面向对象的查询查询方式,HQL查询提供了更加丰富的和灵活的查询特性,因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,提供了类似标准SQL语句的查询方式,同时也提供了面向对象的封装。
HQL查询语句from关键字后面跟的类名+类对象,where后用对象的属性做条件;示例代码:(User是映射数据库的一个类)public boolean checkUser(UserForm userForm){//TODO Auto-generated method stub//String HQLString="from User u whereername='"+userForm.getUsername()+"'";String HQLString="from User u where ername=:uname";Session session=HibernateSessionFactory.currentSession();//获取事务session.beginTransaction();Query query=session.createQuery(HQLString);query.setParameter("uname",userForm.getUsername());//绑定参数Object list=query.list().get(0);//list获取数据集,get获取数据集的某条记录//提交事务session.getTransaction().commit();//关闭SessionHibernateSessionFactory.closeSession();User user=(User)list;if(user.getPassword().equals(userForm.getPassword())){return true;}else{return false;}}2.sql是面向数据库表查询,from后面跟的是表名,where后用表中字段做条件;示例代码:([xxdb].[dbo].[student]就是要查询的数据库表)public boolean checkUser(UserForm userForm){//TODO Auto-generated method stub//String SQLString="select*from[xxdb].[dbo].[student]u whereerName='"+userForm.getUsername()+"'";String SQLString=”select*from[xxdb].[dbo].[student]u whereerName=:uname”;Session session=HibernateSessionFactory.currentSession();session.beginTransaction();//Query query=session.createSQLQuery(SQLString).addEntity(User.class);//实体查询Query query=session.createSQLQuery(SQLString).addScalar("userid",StandardBasicTypes.INTEGER).addScalar("username",StandardBasicTypes.STRING).addScalar("password",StandardBasicTypes.STRING).addScalar("gender",StandardBasicTypes.INTEGER);//标量查询query.setParameter("uname",userForm.getUsername());//绑定参数Object list=query.list().get(0);//list获取数据集,get获取数据集的某条记录session.getTransaction().commit();HibernateSessionFactory.closeSession();User user=(User)list;if(user.getPassword().equals(userForm.getPassword())){return true;}else{return false;}}3.对比hql和sql查询方式我们可以发现他们之间的不同:a.首先是查询语句的不同,hql语句from后面跟的类名+类对象,where后用对象的属性做条件,而sql语句from后面跟的是表名,where后用表中字段做条件,这也就是面向对象和面向数据库的一个区别。
Hibernate查询语句大全

HQL: Hibernate查询语言Hibernate装备了一种非常强大的查询语言,这种语言看上去很像SQL。
但是不要被语法构造上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询,它可以理解如继承、多态和关联之类的概念。
1.大小写敏感性问题除了Java类与属性的名称外,查询语句对大小写并不敏感。
所以SeLeCT 与sELEct 以及SELECT 是一样的,但是org.hibernate.eg.FOO 并不等价于org.hibernate.eg.Foo 并且foo.barSet 也不等价于foo.BARSET 。
本手册中的HQL关键字将使用小写字母. 很多用户发现使用完全大写的关键字会使查询语句的可读性更强, 但我们发现,当把查询语句嵌入到Java语句中的时候使用大写关键字比拟难看。
子句Hibernate中最简单的查询语句的形式如下:该子句简单的返回eg.Cat 类的所有实例。
通常我们不需要使用类的全限定名, 因为auto-import 〔自动引入〕是缺省的情况。
所以我们几乎只使用如下的简单写法:from Cat大多数情况下, 你需要指定一个别名, 原因是你可能需要在查询语句的其它局部引用到Catfrom Cat as cat这个语句把别名cat 指定给类Cat 的实例, 这样我们就可以在随后的查询中使用此别名了。
关键字as 是可选的,我们也可以这样写:from Cat cat子句中可以同时出现多个类, 其查询结果是产生一个笛卡儿积或产生跨表的连接。
from Formula, Parameterfrom Formula as form, Parameter as param查询语句中别名的开头局部小写被认为是理论中的好习惯,这样做与Java变量的命名标准保持了一致(比方,domesticCat )。
3.关联(Association)与连接(Join)我们也可以为相关联的实体甚至是对一个集合中的全部元素指定一个别名, 这时要使用关键字join 。
Hibernate查询sql结果行数、查询列表的几种方法

Hibernate查询sql结果⾏数、查询列表的⼏种⽅法⼀、前⾔这个东西,难度⼏乎没有,就是繁琐。
⼀条简单的select count(*) from table_name都能有多种书写⽅式。
总是忘,这⾥记录下。
⼀、通过Criteria 查询查询⾏数:Criteria criteriaCount = getCriteria();criteriaCount = criteriaCount.add(Restrictions.eq("dispatchTaskId", dispatchTaskId));criteriaCount.setProjection(Projections.rowCount());Integer totalCount = ((Long) criteriaCount.uniqueResult()).intValue();查询列表:Criteria criteria = getCriteria();criteria.add(Restrictions.eq("eventId", eventInformationId));List<EventTaskAssignment> list = criteria.list();⼆、通过原⽣sql查询查询⾏数:SQLQuery queryCount = getSession().createSQLQuery("SELECT COUNT(*) FROM incidentInformation WHERE ii.incidentInformationId = :incidentInformationId AND dti.taskstate = :taskstate");queryCount.setParameter("incidentInformationId", incidentInformationId);queryCount.setParameter("taskstate", ETaskStatus.STATUS_INIT.getStatusValue());int count = ((BigDecimal) queryCount.uniqueResult()).intValue();return count;查询列表:1、返回的item为数据库表对应poSQLQuery query = getSession().createSQLQuery(sqlQuery);query.setParameter("userId", userId);query.addEntity(EventTaskAssignment.class);List<EventTaskAssignment> items = query.list();2、返回的item为voSQLQuery query = getSession().createSQLQuery(sqlBuffer.toString());query.setParameter("eventInformationId", eventInformationId);query.addScalar("userId", StandardBasicTypes.STRING);query.addScalar("userName", StandardBasicTypes.STRING);query.setResultTransformer(Transformers.aliasToBean(UserRoles.class));List<UserRoles> list = query.list();三、通过hibernate的查询语⾔查询String countHql = "select count(*) from a where and a.approveResult = :approveResult and a.approverId = :approverId";Query countQuery = getSession().createQuery(countHql);countQuery.setParameter("approverId", approverId);int count = ((Long) countQuery.uniqueResult()).intValue();。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
今天徒弟用到了一句复杂的查询语句。
结果执行报错,但是在SQL中执行没有问题,于是来求助我了。
语句的HQL/SQL格式如下:select count(1) ,cxltype,sum(dzsje),sum(iperson)from (selectxl.cxltype,g.iperson,(select sum(y.dzsje) from Ysklist as y wherey.cykpid = g.cregno) as dzsje from Guestreg as g,Xl as xl where g.xluuid = xl.uuid ) as t where …… group by t.cxltype结果执行出错,最终发现,HQL无法支持from后面跟子查询的方式,网上查了N 多资料,发现遇到这个问题的人还真是不少,但每一个相关的问题帖都没有满意的答复,甚至于多数都是没有跟帖的。
一阵心寒,hibernate叱咤风云,竟然对这个支持如此之弱?虽然这个语句可以通过另外的方法来做(比如建视图或者直接使用SQL来做),但总是不甘心,于是又开始查阅各处资料,最后找到了思路,觉得既然HQL不支持,那么只能把这种子查询封装为对象来做了,那么肯定是需要hbm配置这种临时的子查询对象的,于是开始着手hbm配置的资料中查,hbm中配置对象的都是class标签,开始把范围缩小,针对hbm的class标签的属性资料开始翻查,找到了几个比较可能的属性,where、subselect、mutable、entity-bean,貌似这些都可能跟临时对象有关。
于是反复尝试,并继续翻查资料最终在Hibernate reference 3.2.0 ga 正式版中文参考手册中找到了一些比较可靠的资料:5.1.3. class你可以使用class元素来定义一个持久化类:<classname="ClassName"table="tableName"discriminator-value="discriminator_value"mutable="true|false"schema="owner"catalog="catalog"proxy="ProxyInterface"dynamic-update="true|false"dynamic-insert="true|false"select-before-update="true|false"polymorphism="implicit|explicit"where="arbitrary sql where condition"persister="PersisterClass"batch-size="N"optimistic-lock="none|version|dirty|all"lazy="true|false"entity-name="EntityName"check="arbitrary sql check condition"rowid="rowid"subselect="SQL expression"abstract="true|false"node="element-name"/>name (可选): 持久化类(或者接口)的Java全限定名。
如果这个属性不存在,Hibernate将假定这是一个非POJO的实体映射。
table (可选 - 默认是类的非全限定名): 对应的数据库表名。
discriminator-value (可选 - 默认和类名一样): 一个用于区分不同的子类的值,在多态行为时使用。
它可以接受的值包括 null 和 not null。
mutable (可选,默认值为true): 表明该类的实例是可变的或者不可变的。
schema (可选): 覆盖在根<hibernate-mapping>元素中指定的schema名字。
catalog (可选): 覆盖在根<hibernate-mapping>元素中指定的catalog名字。
proxy (可选): 指定一个接口,在延迟装载时作为代理使用。
你可以在这里使用该类自己的名字。
dynamic-update (可选, 默认为 false): 指定用于UPDATE 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。
dynamic-insert (可选, 默认为 false): 指定用于INSERT的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。
select-before-update (可选, 默认为 false): 指定Hibernate除非确定对象真正被修改了(如果该值为true-译注),否则不会执行SQL UPDATE 操作。
在特定场合(实际上,它只在一个瞬时对象(transient object)关联到一个新的session中时执行的update()中生效),这说明Hibernate 会在UPDATE 之前执行一次额外的SQL SELECT操作,来决定是否应该执行UPDATE。
polymorphism(多态) (可选, 默认值为 implicit (隐式) ): 界定是隐式还是显式的使用多态查询(这只在Hibernate的具体表继承策略中用到-译注)。
where (可选) 指定一个附加的SQLWHERE 条件,在抓取这个类的对象时会一直增加这个条件。
persister (可选): 指定一个定制的ClassPersister。
batch-size (可选,默认是1) 指定一个用于根据标识符(identifier)抓取实例时使用的"batch size"(批次抓取数量)。
optimistic-lock(乐观锁定) (可选,默认是version): 决定乐观锁定的策略。
(16)lazy (可选): 通过设置lazy="false",所有的延迟加载(Lazy fetching)功能将被全部禁用(disabled)。
(17)entity-name (可选,默认为类名): Hibernate3允许一个类进行多次映射(前提是映射到不同的表),并且允许使用Maps或XML代替Java层次的实体映射(也就是实现动态领域模型,不用写持久化类-译注)。
更多信息请看第 4.4 节“动态模型(Dynamic models)” and 第 18 章XML映射。
(18)check (可选): 这是一个SQL表达式,用于为自动生成的schema添加多行(multi-row)约束检查。
(19)rowid (可选): Hibernate可以使用数据库支持的所谓的ROWIDs,例如:Oracle数据库,如果你设置这个可选的rowid, Hibernate可以使用额外的字段rowid实现快速更新。
ROWID是这个功能实现的重点,它代表了一个存储元组(tuple)的物理位置。
(20)subselect (可选): 它将一个不可变(immutable)并且只读的实体映射到一个数据库的子查询中。
当你想用视图代替一张基本表的时候,这是有用的,但最好不要这样做。
更多的介绍请看下面内容。
(21)abstract (可选): 用于在<union-subclass>的继承结构(hierarchies)中标识抽象超类。
注意其中红色的字体,这就是关键之处,往下我找到了相关的内容:对Hibernate映射来说视图和表是没有区别的,这是因为它们在数据层都是透明的(注意:一些数据库不支持视图属性,特别是更新的时候)。
有时你想使用视图,但却不能在数据库中创建它(例如:在遗留的schema中)。
这样的话,你可以映射一个不可变的(immutable)并且是只读的实体到一个给定的SQL子查询表达式:<class name="Summary"><subselect>select , max(bid.amount), count(*)from itemjoin bid on bid.item_id = item.idgroup by </subselect><synchronize table="item"/><synchronize table="bid"/><id name="name"/>...</class>定义这个实体用到的表为同步(synchronize),确保自动刷新(auto-flush)正确执行,并且依赖原实体的查询不会返回过期数据。
<subselect>在属性元素和一个嵌套映射元素中都可见。
显然这就是我一直在找的东东了,hibernate支持自身建立视图,而不需要依赖于数据库。
虽然它本身的说法这是用来替代视图的,但其实这就是带子查询的sql,看我们最终的配置结果。
临时子查询视图Bean[其中第二个非默认的构造函数是不能少的,不然对象无法创建]:Java代码1.public class TestBean {2.private Integer id;3.private String cxltype;4.private Integer iperson;5.private Double dzsje;6.public TestBean(){}7.8.public TestBean(String cxltype, Integer iperson, Double dzsje) {9.super();10.this.cxltype = cxltype;11.this.iperson = iperson;12.this.dzsje = dzsje;13.}14.public String getCxltype() {15.return cxltype;16.}17.public void setCxltype(String cxltype) {18.this.cxltype = cxltype;19.}20.public Integer getIperson() {21.return iperson;22.}23.public void setIperson(Integer iperson) {24.this.iperson = iperson;25.}26.public Double getDzsje() {27.return dzsje;28.}29.public void setDzsje(Double dzsje) {30.this.dzsje = dzsje;31.}32.33.public Integer getId() {34.return id;35.}36.37.public void setId(Integer id) {38.this.id = id;39.}40.}TestBean的hbm配置:Xml代码1.<hibernate-mapping>2.<class name="TestBean" mutable="false">3.<subselect>4.select xl.cxltype,g.iperson,(select sum(y.dzsje) from Ysklist asy where y.cykpid = g.cregno) as dzsje5.from Guestreg as g,Xl as xl6.where g.xluuid = xl.uuid7.</subselect>8.<synchronize table="Guestreg"/>9.<synchronize table="Xl"/>10.<id name="id" type="integer">11.<column name="id" />12.<generator class="identity" />13.</id>14.<property name="cxltype" type="string">15.<column name="cxltype"></column>16.</property>17.<property name="iperson" type="integer">18.<column name="iperson"></column>19.</property>20.<property name="dzsje" type="double">21.<column name="dzsje"></column>22.</property>23.</class>24.</hibernate-mapping>HQL语句:select t.cxltype,sum(t.dzsje),sum(t.iperson) from TestBean as twhere …… group by t.cxltypeHibernate生成的SQL语句:Hibernate: select testbean0_.cxltype as col_0_0_, sum(testbean0_.dzsje) as col_1_0_, sum(testbean0_.iperson) as col_2_0_ from (select xl.cxltype,g.iperson,(select sum(y.dzsje) from Ysklist as y where y.cykpid = g.cregno) as dzsjefrom Guestreg as g,Xl as xlwhere g.xluuid = xl.uuid) testbean0_ where 1=1 group by testbean0_.cxltype可以看得出来,这就是文章最开始要完成的SQL子查询语句到此告一段落,花了我半个下午的时间搞定。