zoukankan      html  css  js  c++  java
  • 二、使用NHibernate对数据库实现增、删、改、查操作

    NHibernate是使用ISession对象实现对数据库的增、删、改、查工作的。
    一、对数据库的查询:
    NHibernate对数据库的查询可以使用四种方式来实现:
        使用ISession对象的方法来实现查询
        使用HQL语句来实现查询
        使用Criteria实现查询
        使用原始SQL语句来实现查询
       
    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 > 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();
        }

  • 相关阅读:
    1343. Fairy Tale
    Codeforces Beta Round #97 (Div. 1)
    URAL1091. Tmutarakan Exams(容斥)
    1141. RSA Attack(RSA)
    hdu4003Find Metal Mineral(树形DP)
    hdu2196 Computer待续
    KMP
    莫比乌斯反演
    配对堆
    bzoj3224Treap
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/2040305.html
Copyright © 2011-2022 走看看