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 > 0 ? 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[]>(); }
3.使用Criteria实现查询
虽然HQL功能强大,但在程序中嵌入字符串给人的感觉不是很舒服,那我们还可以采用Criteria查询,Criteria是通过一组条件表达式(expression_r)来加载数据的,它返回满足条件的对象集合。主要接口为ICriteria,nhibernate在session对象中为我们提供了一个方法CreateCriteria,此方法返回ICriteria接口。下面我们看一下如何使用Criteria查询 public IList<Fruit> Select() { //生成ICriteria引用实例 ICriteria crit = _Session.CreateCriteria(typeof(Fruit)); //按照Price字段升序排列 crit.AddOrder(new NHibernate.Criterion.Order("Price", true)); //添加价格在1-5元之间的查询条件 crit.Add(Restrictions.Between("Price", 1, 5)); //添加货架在1,3,5,2货架的查询条件 crit.Add(Restrictions.In("Stack", new string[] { "1", "3", "5", "2" })); //从第6条记录开始查询 crit.SetFirstResult(6); //每次查询出来的最多记录条数 crit.SetMaxResults(2); //返回泛型集合 IList<Fruit> list = crit.List<Fruit>(); return list; } 主要方法: SetMaxResults:设置返回的最大结果数,可用于分页; SetFirstResult:设置首个对象返回的位置,可用于分页; Add:加入条件表达式(expression_r对象),此方法可多次调用以组合多个条件; AddOrder:加入排序的字段(Order对象); List:返回满足条件的对象集合。expression_r是一个abstract(抽象)类,它通过一组static方法实现Factory Method(工厂方法)模式,这些static方法返回的都是expression_r类的子类,下面列出一些常用的:
Eq:这是一个相等判断的表达式; Like:这是一个like判断的表达式; Gt:这是一个大于判断的表达式; And:这是两个表达式And操作后的表达式; Or:这是两个表达式Or操作后的表达式; Between:这是一个范围筛选的条件表达式,在两个数之间的范围。 In:这也是一个范围筛选的条件表达式,在多个离散的值中进行筛选。 下面以几个例子来说明Criteria数据加载的用法: 1. 取得用户名(username)为billy的用户对象: expression_r ex = expression_r.Eq( "Username", "billy" ); IList users = session.CreateCriteria(typeof(User)).Add( ex ).List(); 2.取得用户名(username)为billy, 密码为123456的用户对象 expression_r ex = expression_r.And( expression_r.Eq("Username", "billy"), expression_r.Eq("Password", "123456") ); IList users = session.CreateCriteria(type(User)).Add( ex ).List(); 3. 取得数据中第20-40的用户对象。 IList users = session.CreateCriteria(typeof(User)) .SetFirstResult(20).SetMaxResults(40) .List(); 对于SQLSERVER,数据定位采用的是IDataReader前滚至firstResult处,然后取maxResults条记录。 4. 取得按注册日期(Regdate)降序排序后的用户对象. ICriteria c = session.CreateCriteria(typeof(User)); IList users = c.AddOrder( Order.Desc("Regdate") ).List();二、向数据库新增记录
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(); }