Nhibernate系列学习之(三) Criteria查询表达式增删改查
Criteria查询表达式:
正如我们所见,Expression对查询语句的表达式进行了封装和限制,下表列出了Expression所有的方法,以及每个方法所对应的查询表达式及其限制。
Restrictions的用法:
方法 |
说明 |
Restrictions.eq |
= |
Restrictions.allEq |
利用Map来进行多个等于的限制 |
Restrictions.gt |
> |
Restrictions.ge |
>= |
Restrictions.lt |
< |
Restrictions.le |
<= |
Restrictions.between |
BETWEEN |
Restrictions.like |
LIKE eg: Restrictions.Like("Inquirer", "%"+condition.Inquirer+"%") |
Restrictions.in |
in |
Restrictions.and |
and |
Restrictions.or |
or |
Restrictions.sqlRestriction |
用SQL限定查询 |
方法描述
注意:Expression各方法中的属性参数(各方法中的第一个参数)所指定的属性名称(如:name,sex),并不是数据库表中的实际字段名称,而是实体对象中映射实际数据表字段的类属性名称。
NHibernate.ICriteria接口表示特定持久类的一个查询。ISession是 ICriteria实例的工厂。
这里以Northwind数据库为示例数据库
示例数据表:Employees
现在只用雇员表中部分字段。
持久类如下:
- public class Employees
- {
- public virtual int EmployeeID { get; set; }
- public virtual string LastName { get; set; }
- public virtual string FirstName { get; set; }
- public virtual DateTime BirthDate { get; set; }
- public virtual string Address { get; set; }
- public virtual string City { get; set; }
- public virtual string PostalCode { get; set; }
- }
映射文件如下:
- <?xml version="1.0" encoding="utf-8" ?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain.Entities">
- <class name="Employees" table="Employees">
- <id name="EmployeeID" column="EmployeeID">
- <generator class="identity"></generator>
- </id>
- <property name="LastName" column="LastName" type="String"></property>
- <property name="FirstName" column="FirstName" type="String"></property>
- <property name="BirthDate" column="BirthDate" type="DateTime"></property>
- <property name="Address" column="Address" type="String"></property>
- <property name="City" column="City" type="String"></property>
- <property name="PostalCode" column="PostalCode" type="String"></property>
- </class>
- </hibernate-mapping>
1、使用ISession对象的Get()方法来根据主键查询对象
语法:T
ISession.Get<T>(object Id)
通常使用这种方法来根据主键Id值来查询对象的,并返回查询到的实体对象。
2、使用HQL语句来实现查询。
为了实现对对象的灵活操作,NHibernate也引入了Hibernate查询语言(HQL,NHibernate
Query Language),这种语句与SQL语句很像,但它是基于面向对象查询语言。它实际上是用OOP中的对象和属性映射了数据库中的表和列。
例如这一句:select
c.Firstname from Customer c
Customer是一个对象,Firstname是Customer对象的属性。
在这里主要讨论一下from子句,select子句,where子句,order
by子句,group by子句几个常用的子句。
from子句:
如“from
Fruit”:就是取出Fruit实体类所映射的表的所有记录。还可以加上别名“from Fruit as f”。
- public IList<Fruit> Select()
- {
- IList<Fruit> list = _Session.CreateQuery("from Fruit").List<Fruit>();
- return list;
- }
这里返回的是Fruit实体对象的集合。
select子句:
用来指定要从实体类所对应的表中检索出哪些属性。
- public IList<object[]> SelectAll()
- {
- IList<object[]> list = _Session.CreateQuery("select f.Id,f.Name,f.Price from Fruit as f ").List<object[]>();
- return list;
- }
由于只是查询了有限的列出来,所以返回的不是实体对象的集合,而是object[]数组的集合。只要在select子句中指定多列,就不能返回实体对象的集合,而是返回object[]的集合。
另外需要注意的是:HQL语句中实体类的名子和属性的名子大小写敏感。
下面的代码是只查询不重复的Stack属性值的集合,由于查询结果只有一列,所以返回一个字符串的集合就可以了。
- public IList<string> GetStacks()
- {
- IList<string> list = _Session.CreateQuery("select distinct f.Stack from Fruit as f").List<string>();
- return list;
- }
where子句:
用来从实体类对应的表中筛选出指定的对象集合。我们所知道的where中的and、or、not、is、like、between、in、>、<、=等等都可以直接拿来使用,
如:
select p.Name from Person p where p.Age > 20
from Person p where p.Age between 20 and 30
from person p where p.Age in (20,30)
from person p where p.Name is null
from person p where p.Name like 'Jaki%'
那如何在where子句中使用参数呢?比如我们要做一个登录,需要根据用户名和密码查询,那我们的HQL语句应当使用变量参数,变量参数以":参数名"的形式表示
from Login as login where login.Id=:u and login.Password=:p
那我们如何给:u和:p赋值呢?我们可以使用IQuery的SetXXX()方法(SetString(),SetBoolean(),SetInt32()......)来为参数赋值
下面是我们登录的代码段:
- public bool Select(string uid, string pwd)
- {
- //写法1
- //IList<Login> list = _Session.CreateQuery("from Login as login where login.Id='"+uid+"' and login.Password='"+pwd+"'").List<Login>();
- //写法2
- //IList<Login> list = _Session.CreateQuery("from Login as login where login.Id=? and login.Password=?").SetString(0,uid).SetString(1,pwd).List<Login>();
- //写法3
- IList<Login> list = _Session.CreateQuery("from Login as login where login.Id=:u and login.Password=:p").SetString("u",uid).SetString("p",pwd).List<Login>();
- return list.Count > ? true : false;
- }
书写HQL参数有四种写法:
写法1:可能会引起SQL注入,不要使用。
写法2:ADO.NET风格的参数,NHibernate的参数从0开始计数。
写法3:命名参数用:name的形式在查询字符串中表示,这时IQuery接口把实际参数绑定到命名参数。
写法4:命名的参数列表,把一些参数添加到一个集合列表中的形式,比如可以查询数据是否在这个集合列表
order by子句与group by 子句与SQL语法很像,在此不多说了,代码如下。
- public IList<Customer> Orderby()
- {
- return _session.CreateQuery("select from Customer c order by c.Firstname asc,c.Lastname desc").List<Customer>();
- }
- public IList<object[]> Groupby()
- {
- return _session.CreateQuery("select c.Firstname, count(c.Firstname) from Customer c group by c.Firstname").List<object[]>();
- }
一、开始
(一) 返回所有实例(返回所有雇员)
这里返回的所有实例,且是全部的属性(字段)
- ICriteria crt = _session.CreateCriteria(typeof(Employees));
- return crt.List<Employees>();
Isession创建条件查询实例有4个构造方法。
(二) 返回部分实例(返回2个雇员)
- ICriteria crt = _session.CreateCriteria(typeof(Employees));
- crt.SetMaxResults();
- return crt.List<Employees>();
(三)条件查询的约束条件
(1)Expression
- ICriteria crt = _session.CreateCriteria(typeof(Employees));
- crt.Add(Expression.Eq("City","London"));
- return crt.List<Employees>();
查询内容为:雇员的城市是在伦敦的。其中Expression的名字空间为:NHibernate.Criterion
Expression类 定义了获得某些内置ICriterion类型的工厂方法,这里用到了等于
(2)Restriction
- ICriteria crt = _session.CreateCriteria(typeof(Employees));
- crt.Add(Restrictions.Eq("City", "London"));
- return crt.List<Employees>();
查询内容为:雇员的城市是在伦敦的。其中Restrictions的名字空间为:NHibernate.Criterion
(3)通过实例来查询
- Employees ee = new Employees { City = "London", BirthDate = Convert.ToDateTime("1955-03-04 00:00:00.000") };
- ICriteria crt = _session.CreateCriteria(typeof(Employees));
- crt.Add(Example.Create(ee));
- return crt.List<Employees>();
查询伦敦的,生日在那个时间的。(为什么这里我要加个生日上去?因为我的持久类中有这个属性,如果在实例查询中不给定这个值,会有日期越界的异常。在下边的例子中,来处理这种情况)这是限制的相等的实现。下边实现一个相似的例子:
- Employees ee = new Employees { FirstName = "a"};
- Example exp=Example.Create(ee).EnableLike(MatchMode.Start).ExcludeProperty("BirthDate").IgnoreCase();
- ICriteria crt = _session.CreateCriteria(typeof(Employees));
- crt.Add(exp);
- return crt.List<Employees>();
这个例子中,指定相似的姓名等a,看实例exp:
·采用相似比较EnableLike
·相似比较匹配模式MatchMode.Start,开头匹配,这个应该类似于SQL中的a%
·排除比较属性ExcludeProperty,这个方法就是用于处理排除的。上个例子中日期没给,所以会出现异常,而这个方法则排除了这种异常发生(其实就是排除不比较的属性(字段))。
·忽略大小写
(四)排序
- ICriteria crt = _session.CreateCriteria(typeof(Employees));
- crt.AddOrder(new NHibernate.Criterion.Order("FirstName", true));
- return crt.List<Employees>();
排序字段:名字,升序(true)
(五)聚合
(1)查询人数
- ICriteria crt = _session.CreateCriteria(typeof(Employees));
- crt.SetProjection(Projections.RowCount());
- return crt.List();
NHibernate.Expression.Projections是 IProjection 的实例工厂。通过调用 SetProjection()应用投影到一个查询。
(2)Avg
从这个开始到以下的例子又回到以Products为示例数据表
- ICriteria crt = _session.CreateCriteria(typeof(Products));
- crt.SetProjection(Projections.ProjectionList().Add(Projections.Avg("Price")));
- return crt.List();
通过投影列表来添加投影聚合方法。
这里取得产品的平均价格,这里没有条件约束,下边这个例子取得产品类别为2的产品的平均价格:
- ICriteria crt = _session.CreateCriteria(typeof(Products));
- crt.SetProjection(Projections.ProjectionList().Add(Projections.Avg("Price"))).Add(Expression.Eq("CategoryID",));
- return crt.List();
(3)Max(最大价格)
- ICriteria crt = _session.CreateCriteria(typeof(Products));
- crt.SetProjection(Projections.ProjectionList().Add(Projections.Max("Price")));
- return crt.List();
(4)Min(最低价格)
- ICriteria crt = _session.CreateCriteria(typeof(Products));
- crt.SetProjection(Projections.ProjectionList() .Add(Projections.Min ("Price")));
- return crt.List();
(5)Sum(和)
- ICriteria crt = _session.CreateCriteria(typeof(Products));
- crt.SetProjection(Projections.ProjectionList().Add(Projections.Sum ("Price")));
- return crt.List();
(6)分组
- ICriteria crt = _session.CreateCriteria(typeof(Products));
- crt.SetProjection(Projections.ProjectionList().Add(Projections.GroupProperty("CategoryID")));
- return crt.List<int>();
这个分组只是返回一个属性,所以用int泛型可以了。下边的例子返回分组,并返回各组的数目
- ICriteria crt = _session.CreateCriteria(typeof(Products));
- crt.SetProjection(Projections.ProjectionList().Add(Projections.GroupProperty("CategoryID")).Add(Projections.RowCount()));
- return crt.List();
这里的List为System.Collections.Ilist,且是object[]类型的
二、向数据库新增记录
1.新建对象;
2.调用ISession.Save();
3.调用Flush()同步到数据库。
- public void Insert(Fruit fruit)
- {
- _Session.Save(fruit);
- _Session.Flush();
- }
三、修改记录
1.获取对象;
2.修改它的一些属性;
3.调用ISession.Update();
4.调用Flush同步到数据库。
- public void Update(Fruit fruit)
- {
- _Session.Update(fruit);
- _Session.Flush();
- }
四、删除记录
1.获取要删除的对象;
2.调用ISession.Delete();
3.调用Flush同步到数据库。
- public void Delete(Fruit fruit)
- {
- _Session.Delete(fruit);
- _Session.Flush();
- }
Nhibernate系列学习之(三) Criteria查询表达式增删改查的更多相关文章
- Nhibernate系列学习之(二) 简单增删改查
实例中解决方案简单的创建三层架构,符合开发过程中最简单的运用: 1:首先在数据库中创建一个表T_School,脚本如下: USE [TestDb] GO /****** 对象: Table [dbo] ...
- ASP.NET MVC学习---(三)EF简单增删改查
那么现在我们已经大概从本质上了解了ef 巴拉巴拉说了一大堆之后 总算要进入ef的正题了 总在口头说也太不行了是吧~ 没错,现在要用ef进行一些实际的操作 做什么呢? 就做一个入门级的增删改查操作吧 废 ...
- NHibernate系列文章三:简单的增删改查询
摘要 上一篇文章只完成了简单的NHibernate安装.配置和连接数据库.这篇文章介绍怎样实现最简单的数据库读写操作. 1. 重构ISessionFactory生成过程 将生成ISessionFact ...
- MongoDB学习【三】—MongoDB数据库增删改查
一.数据库的增删查 # 增加 use db # 有则切换,无则新 增 # 查看 show dbs # 查看所有数据库 db # 查看当前库 # 删除 db.dropDatabase() # 不会就用h ...
- Python(三)字典的增删改查和遍历
一.增加
- ORM 多表操作查询及增删改查
------------------------------------------只有对前途乐观的人,才能不怕黑暗,才能有力量去创造光明.乐观不是目的,而是人生旅途中的一种态度. 多表操作 创建模型 ...
- MyBatis(三)MyBatis的增删改查
(1)接口中编写方法 public Emp getEmp(Integer id); public void addEmp(Emp emp); public void deleteEmp(Integer ...
- sql的一般查询语句(增删改查中的查)
/*例子 判断规则 http://xxx.xxx/new.php?id=57 and 1=1 正确 http://xxx.xxx/new.php?id=57 and 1=2 错误 http://xxx ...
- 第二部分 Mongodb增删改查
学习内容:1.mongodb增加操作2.mongodb删除操作3.mongodb查询操作增删改查的高级应用Capped Collection(固定集合)GridFS 大文件上传或下载 1: inser ...
随机推荐
- Javascript 广告浮动效果在浏览器中间N秒后移动到右下角
Javascript 广告浮动效果在浏览器中间N秒后移动到右下角 闲着无聊做了一个,本人原创...就是这个页面的广告效果....怎么样???? 刚刚学习的javascript
- LeetCode:螺旋矩阵||【59】
LeetCode:螺旋矩阵||[59] 题目描述 给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵. 示例: 输入: 3 输出: [ [ 1, 2, 3 ...
- Django 补充models操作,中间件, 缓存,信号,分页
1.Model 一对多 补充 models如下: class UserType(models.Model): caption = models.CharField(max_length=16) cla ...
- PAT 天梯赛 L1-038. 新世界 【水】
题目链接 https://www.patest.cn/contests/gplt/L1-038 AC代码 #include <iostream> #include <cstdio&g ...
- 查看linux系统版本信息(Oracle Linux、Centos Linux、Redhat Linux、Debian、Ubuntu)
一.查看Linux系统版本的命令(3种方法) 1.cat /etc/issue,此命令也适用于所有的Linux发行版. [root@S-CentOS home]# cat /etc/issue Cen ...
- Unity Json 之三
今天在网上看到一个simplejson,直接调用这两个API就可以了,简单易用 string jsonstr = SimpleJson.SimpleJson.SerializeObject(json) ...
- 数据库系统概论学习4-SQL 语句和关系代数(二)单表查询
4.12 字符匹配 精确查询和模糊查询 在这一节之前,我们学习的查询几乎都是精确查询,这就需要我们明确地知道某些属性的具体值.例如我们需要查询 'Wangxiaoxiao' 同学的信息,就需要在WHE ...
- 修改redhat默认显示语言为中文
[delmore@localhost Desktop]$ su //切换到最高权限 Password: ...
- ssm搭建相关的问题
在搭建ssm框架时候踩得坑:1.对于拦截器url-parttern的设置:第一次设置的是/** 本以为这个是表示拦截所有,没想到这是错误的写法,正确的写法是/ 启动项目不会报错,但是会出现404 ...
- vim 乱码问题的方法参考
linux 中设置当前用户的系统默认编码为 UTF-8 格式解决 vim 乱码问题的方法参考 任侠 2013-05-02 11:58 电脑基础 抢沙发 13,732 views 在使用 l ...