Nhibernate回顾---父子关系查询 关联查询 使用HQL和Criteria API
2012-05-28 14:15
441 查看
one-to-many关联查询:
在关系模型中:可以使用子表作为内连接查询Customer,像这样:
select * from Customer c inner join Order o on c.CustomerId=o.CustomerId where o.CustomerId=<id of the Customer>
使用父表作为内连接查询Order,像这样:
select * from Oder o inner join Customer c on o.CustomerId=c.CustomerId where o.OrderId=<id of the Order>
下面我们来看看在NHibernate中使用原生SQL查询。这篇来完成查询订单在orderData之后的顾客列表不同查询的写法。
查询订单在orderData之后的顾客列表的HQL关联查询写法:
这里使用基于面向对象的HQL,一目了然,符合面向对象编程习惯。
3.Criteria API关联查询
我们使用CreateCriteria()在关联之间导航,很容易地在实体之间指定约束。这里第二个CreateCriteria()返回一个ICriteria的新实例,并指向Orders实体的元素。在查询中子对象使用子CreateCriteria语句,这是因为实体之间的关联我们在映射文件中已经定义好了。还有一种方法使用CreateAlias()不会创建ICriteria的新实例。
这个例子返回顾客列表有重复的,不是我们想要的结果。
预过滤
使用ICriteria接口的SetResultTransformer(IResultTransformer resultTransformer)方法返回满足特定条件的Customer。上面例子中使用条件查询,观察其生成的SQL语句并没有distinct,这时可以使用NHibernate.Transform命名空间中的方法或者使用NHibernate提供的NHibernate.CriteriaUtil.RootEntity、NHibernate.CriteriaUtil.DistinctRootEntity、NHibernate.CriteriaUtil.AliasToEntityMap静态方法实现预过滤的作用。那么上面的查询应该修改为:
这个例子从转换结果集的角度实现了我们想要的效果。
many-to-many:
这里需要使用Join告诉查询如何在表之间关联。无论多么复杂的关系,我们必须在查询语句中指定返回值。这里使用AddEntity设置返回的实体。
因为在映射文件已经定义实体之间一对多、多对多关系,NHibernate通过映射文件知道如何去关联这些实体,我们不需要在查询语句中重复定义。这里使用查询和上一篇使用HQL关联查询语句一样,NHibernate完全可以去关联对象,实现查询订单和产品。
因为实体之间的关联我们在映射文件中已经定义好了。所以我们在查询子对象使用子CreateCriteria语句关联对象之间导航,可以很容易地在实体之间指定约束。这里第二个CreateCriteria()返回ICriteria的新实例,并指向Orders实体的元素。第三个指向Products实体的元素。
一对多关联查询
1.原生SQL关联查询
在关系模型中:可以使用子表作为内连接查询Customer,像这样:select * from Customer c inner join Order o on c.CustomerId=o.CustomerId where o.CustomerId=<id of the Customer>
使用父表作为内连接查询Order,像这样:
select * from Oder o inner join Customer c on o.CustomerId=c.CustomerId where o.OrderId=<id of the Order>
下面我们来看看在NHibernate中使用原生SQL查询。这篇来完成查询订单在orderData之后的顾客列表不同查询的写法。
public IList<Customer> UseSQL_GetCustomersWithOrders(DateTime orderDate) { return _session.CreateSQLQuery("select distinct {customer.*} from Customer {customer}"+ " inner join [Order] o on o.Customer={customer}.CustomerId where o.OrderDate> :orderDate") .AddEntity("customer", typeof(Customer)) .SetDateTime("orderDate", orderDate) .List<Customer>(); }
2.HQL关联查询
查询订单在orderData之后的顾客列表的HQL关联查询写法:public IList<Customer> UseHQL_GetCustomersWithOrders(DateTime orderDate) { return _session.CreateQuery("select distinct c from Customer c inner join c.Orders o where o.OrderDate > :orderDate") .SetDateTime("orderDate", orderDate) .List<Customer>(); }
这里使用基于面向对象的HQL,一目了然,符合面向对象编程习惯。
3.Criteria API关联查询
我们使用CreateCriteria()在关联之间导航,很容易地在实体之间指定约束。这里第二个CreateCriteria()返回一个ICriteria的新实例,并指向Orders实体的元素。在查询中子对象使用子CreateCriteria语句,这是因为实体之间的关联我们在映射文件中已经定义好了。还有一种方法使用CreateAlias()不会创建ICriteria的新实例。
这个例子返回顾客列表有重复的,不是我们想要的结果。
public IList<Customer> UseCriteriaAPI_GetCustomersWithOrders(DateTime orderDate) { return _session.CreateCriteria(typeof(Customer)) .CreateCriteria("Orders") .Add(Restrictions.Gt("OrderDate", orderDate)) .List<Customer>(); }
预过滤
使用ICriteria接口的SetResultTransformer(IResultTransformer resultTransformer)方法返回满足特定条件的Customer。上面例子中使用条件查询,观察其生成的SQL语句并没有distinct,这时可以使用NHibernate.Transform命名空间中的方法或者使用NHibernate提供的NHibernate.CriteriaUtil.RootEntity、NHibernate.CriteriaUtil.DistinctRootEntity、NHibernate.CriteriaUtil.AliasToEntityMap静态方法实现预过滤的作用。那么上面的查询应该修改为:
public IList<Customer> UseCriteriaAPI_GetCustomersWithOrders(DateTime orderDate) { return _session.CreateCriteria(typeof(Customer)) .CreateCriteria("Orders") .Add(Restrictions.Gt("OrderDate", orderDate)) .SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer()) //或者.SetResultTransformer(NHibernate.CriteriaUtil.DistinctRootEntity) .List<Customer>(); }
这个例子从转换结果集的角度实现了我们想要的效果。
many-to-many:
1.原生SQL关联查询
public IList<Customer> UseSQL_GetCustomersWithOrdersHavingProduct(DateTime orderDate) { return _session.CreateSQLQuery("select distinct {customer.*} from Customer {customer}" + " inner join [Order] o on o.Customer={customer}.CustomerId"+ " inner join OrderProduct op on o.OrderId=op.[Order]"+ " inner join Product p on op.Product=p.ProductId where o.OrderDate> :orderDate") .AddEntity("customer", typeof(Customer)) .SetDateTime("orderDate", orderDate) .List<Customer>(); }
这里需要使用Join告诉查询如何在表之间关联。无论多么复杂的关系,我们必须在查询语句中指定返回值。这里使用AddEntity设置返回的实体。
2.HQL关联查询
public IList<Customer> UseHQL_GetCustomersWithOrdersHavingProduct(DateTime orderDate) { return _session.CreateQuery("select distinct c from Customer c ," + " c.Orders.elements o where o.OrderDate > :orderDate") .SetDateTime("orderDate", orderDate) .List<Customer>(); }
因为在映射文件已经定义实体之间一对多、多对多关系,NHibernate通过映射文件知道如何去关联这些实体,我们不需要在查询语句中重复定义。这里使用查询和上一篇使用HQL关联查询语句一样,NHibernate完全可以去关联对象,实现查询订单和产品。
3.Criteria API关联查询
因为实体之间的关联我们在映射文件中已经定义好了。所以我们在查询子对象使用子CreateCriteria语句关联对象之间导航,可以很容易地在实体之间指定约束。这里第二个CreateCriteria()返回ICriteria的新实例,并指向Orders实体的元素。第三个指向Products实体的元素。public IList<Customer> UseCriteriaAPI_GetCustomerswithOrdersHavingProduct() { return _session.CreateCriteria(typeof(Customer)) .Add(Restrictions.Eq("Firstname","YJing")) .CreateCriteria("Orders") .Add(Restrictions.Gt("OrderDate",new DateTime(2008,10,1))) .CreateCriteria("Products") .Add(Restrictions.Eq("Name","Cnblogs")) .List<Customer>(); }
相关文章推荐
- NHibernate回顾之---条件查询(Criteria Query)
- Nhibernate回顾---父子关系查询
- NHibernate 快速入门(四)使用 HQL 查询数据
- Asp.Net Nhibernate使用Criteria查询数据使用方法小记
- Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o
- Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o
- 三、NHibernate查询之HQL&Criteria
- NHibernate查询之HQL&Criteria
- JavaEE Tutorials (11) - 使用Criteria API创建查询
- 三、NHibernate查询之HQL&Criteria
- 使用NHibernate(6)-- HQL && ICriteria 简单介绍
- 时代互联 域名注册查询接口api的使用 (w3Sockets)(这篇文章,关于是放到C:\WINDOWS或者是C:\WINDOWS\system32要亲自试试,附带在 server 2008 R2下无法运行的解决方法)
- 使用HQL的select查询字段并构造出类
- 在HQL中使用单个的模糊查询,以及对于多个查询条件进行查询的话
- 在hibernate中hql语句使用连接查询
- 【JavaWeb-21】多对多关系、类和关联级别的加载策略、HQL查询详解、Hibernate连接池配置、Hibernate里悲观锁乐观锁使用
- TFS API: 获取自定义查询--使用QueryHierarchy
- Hibernate学习之---使用HQL查询
- Hibernate中使用Hql查询出一定时间段的记录
- JavaEE Tutorials (12) - 创建和使用基于字符串的Criteria查询