• 一步步学习NHibernate(7)——HQL查询(1)


    请注明转载地址:http://www.cnblogs.com/arhat

    从本章开始,老魏带着大家来学习一下HQL语句。HQL语句NHibernate为我们提供的一种功能比较强大的查询语句,这个HQL语句和我们平时所用的SQL语句基本上是类似的,只不过有个别的地方需要们注意一下。

    好,下面我们看一下如何来学习HQL语句,首先老魏得介绍一个对象IQuery,这个对象是用来进行查询操作。那么这个对象又ISession提供的CreateQuery()方法来创建。首先呢,我们在主程序中先写两个示例程序,然后根据这个示例程序来更改我们的NHibernateHelper这个工具类。

    首先,我们来使用HQL语句来实现我们前面的查询,查询出所有的Student对象。更改主程序代码如下:

    static void Main(string[] args)
    
            {
    
    //定义一个HQL语句
    
    string hql = "from Student";
    
    //创建一个IQuery对象
    
                NHibernate.IQuery query = DAL.NHibernateHelper.GetCurrentSession().CreateQuery(hql);
    
    //执行IQuery对象,并把结果取出来
    
    IList<Model.Student> list = query.List<Model.Student>();
    
    foreach (Model.Student student in list)
    
                {
    
    Console.WriteLine(student.SName + "," + student.SSex + "," + student.SBirthday + "," + student.SId);
    
                }
    
            }

    我们来看看执行结果:

    wps_clip_image-5999

    好,现在我们来分一下这个HQL语句和普通的SQL语句之间的区别,从上面的例子中我们可以知道这个HQL语句以from语句开头,并没有出现select,这是因为我们查询的是Student的所有属性。所以得出下面的结论:

    1,如果查询的是所有属性,则可以不使用Select

    然而,大家会发现from后面的“表名”确实大写的,这里需要注意的是,这里不再是“表名”而是对象名,也就是Model中的Student.cs这类的类名,因为NHibernte查询的是对象而不是表。所以得出第二条结论:

    2,查询的不是“表名”而是“类名”

    我们使用IQuery对象的List<T>方法,将会把结果转换为我们的对象集合,返回的是IList<T>类型。所以我们得出第三个结论:

    3,查询结果一般为IList<T>类型。

    现在,我们要查询Student对象中的姓名和性别。如果使用Get或者Load方法的话,的确会查询出来,但是随着也查询出了我们不需要的字段。现在我们只想要姓名和性别。那么此时就应该使用HQL语句了。代码如下:

    //定义一个HQL语句
    
    string hql = "select SName,SSex from Student";
    
    //创建一个IQuery对象
    
                NHibernate.IQuery query = DAL.NHibernateHelper.GetCurrentSession().CreateQuery(hql);
    
    //执行IQuery对象,并把结果取出来
    
    IList<object[]> list = query.List<object[]>();
    
    foreach (object[] objs in list)
    
                {
    
    foreach (object obj in objs)
    
                    {
    
    Console.WriteLine(obj);
    
                    }
    
                }

    下面则是查询结果:

    wps_clip_image-10536

    由于,我们现在只需要两个属性,所以前面的select还是要带上的。同是需要注意的是,这里查询的不是表的“字段名”而是对象的“属性名”,也就是“SName,SSex”是Student对象的属性名。所以我们得出第4条结论。

    4,如果查询个别字段,则应该使用对象的”属性名“而不是表的“字段名”

    同时,由于我们查询出的只是个别字段,所以我们不能用对象来接受查询的结果,因为NHibernate只有在查询的是全属性的时候,在会返回一个对象,如果只是个别字段,则返回的是object或object[]对象。如果查询的属性名个数大于1,则返回的是object[],如果只有一个则返回object。所以我们得出第5个结论。

    5,查询个别字段时,应使用object(一个属性)或object[](多个属性)来接受返回的结果。

    下面,我们来查询一个字段,比如只取出学生的姓名。

    static void Main(string[] args)
    
            {
    
    //定义一个HQL语句
    
    string hql = "select SName from Student";
    
    //创建一个IQuery对象
    
                NHibernate.IQuery query = DAL.NHibernateHelper.GetCurrentSession().CreateQuery(hql);
    
    //执行IQuery对象,并把结果取出来
    
    IList<string> list = query.List<string>();
    
    foreach (string  name in list)
    
                {                
    
    Console.WriteLine(name);               
    
                }
    
            }

    wps_clip_image-30835

    为了减少装箱和拆箱操作,这里老魏使用了泛型,当然了你可以使用object(这个是万能的主啊,嘻嘻)。

    现在,老魏的要求又变了,现在我们要查询性别为男的学生。看到这样的要求很容易的就想到了使用where语句,那么我们看看怎么使用where语句。

    static void Main(string[] args)
    
            {
    
    //定义一个HQL语句
    
    string hql = "from Student where SSex='男'";
    
    //创建一个IQuery对象
    
                NHibernate.IQuery query = DAL.NHibernateHelper.GetCurrentSession().CreateQuery(hql);
    
    //执行IQuery对象,并把结果取出来
    
    IList<Model.Student> list = query.List<Model.Student>();
    
    foreach (Model.Student student in list)
    
                {
    
    Console.WriteLine("姓名:"+student.SName+",性别:"+student.SSex);               
    
                }
    
            }

    wps_clip_image-23136

    需要注意的是where条件后面的”字段名“也必须是对象的”属性名”。虽然这样达到我们的要求,但是从安全性上来说不好,因为容易SQL注入。如果能像ADO.NET那样使用setParameter多好啊,幸运的是NHibernate提供了这样的方法。下面我们来改写一下。

    static void Main(string[] args)
    
            {
    
    //定义一个HQL语句
    
    string hql = "from Student where SSex=?";
    
    //创建一个IQuery对象
    
                NHibernate.IQuery query = DAL.NHibernateHelper.GetCurrentSession().CreateQuery(hql);
    
                query.SetParameter(0, "");
    
    //执行IQuery对象,并把结果取出来
    
    IList<Model.Student> list = query.List<Model.Student>();
    
    foreach (Model.Student student in list)
    
                {
    
    Console.WriteLine("姓名:"+student.SName+",性别:"+student.SSex);               
    
                }
    
            }

    wps_clip_image-28060

    大家注意观察上面生成的SQL语句和这个生成的SQL语句是不同的,因为这个避免了SQL注入。大家需要注意的SetParameter的参数有两个(int position,object value)。而在HQL中使用”?”来作为占位符。当然NHibernate也提供了通过名字的方式,这个大家可以从帮助文档中来学习。

    至于其他的,order by,like,between ... and等和聚合函数,老魏将在下面的章节中继续给大家来演示。希望大家能够在空余的时间中多多练习一下HQL语句,因为这个很重要,需要大家转换的一个观点就是HQL语句查询的是对象,这一点尤其重要。还有,在使用HQL查询对象和属性的时候,对象名和属性名是区分大小写的。

  • 相关阅读:
    iframe脸面的页面和父页面之间的交互方法
    iframe高度自适应
    获取html元素所在页面的坐标
    自制的几个jquery插件
    将DataTable转换成Json格式
    QL 获取当前日期,年、月、日、周、时、分、秒
    DropdownList异步刷新GridView数据
    图片热区——map的用法
    Chart控件文档
    母版页改变被嵌套的页面中的控件ID的解决方法
  • 原文地址:https://www.cnblogs.com/arhat/p/3574674.html
Copyright © 2020-2023  润新知