zoukankan      html  css  js  c++  java
  • 使用 NHibernate 的示例查询

    示例查询最多的应用场合是组合查询,我们常常需要在界面上提供若干的查询选项,然后根据用户的输入返回符合条件的结果。

    使用代码直接进行处理往往需要涉及到复杂的条件,由于组合条件并不确定,导致逻辑判断语句结构复杂。对于多个可选的参数,情况会变得更加严重。

    使用示例查询可以很方便地处理这种问题。

    在查询的时候,将收集到的查询条件赋予一个对象的属性,当然,这个对象的类型就是需要查询的实体对象。

    例如,在 NHibernate 中存在一个 User 的类型,我们需要对它的姓名和口令进行组合查询,User 的定义如下:

    namespace Demo.Dao.Domain
    {
    // 用户对象
    public class User
    {
    public virtual int UserId { set; get; }
    public virtual string Username { set; get; }
    public virtual string Password { set; get; }

    public virtual Address Address { set; get; }
    }
    }

    在界面中,我们提供用户输入的输入框。

    <p>
    <label for="<%= this.tbxName %>">
    用户名:</label>
    <asp:TextBox ID="tbxName" runat="server"></asp:TextBox>
    </p>
    <p>
    <label for="<%= this.tbxPassword %>">
    口令:</label>
    <asp:TextBox ID="tbxPassword" runat="server"></asp:TextBox>
    </p>
    <p>
    <asp:Button ID="btnSearch" runat="server" Text="查询" OnClick="btnSearch_Click"/>
    </p>

    在按钮的点击事件中,我们将用户的输入组合为一个示例对象。然后提交给 NHibernate 进行查询。

    protected void btnSearch_Click(object sender, EventArgs e)
    {
    if (this.IsValid)
    {
    Demo.Dao.Domain.User example
    = new Demo.Dao.Domain.User()
    {
    Username = this.tbxName.Text,
    Password = this.tbxPassword.Text
    };
    IList<Demo.Dao.Domain.User> list = this.UserService.GetUsers(example);

    this.Repeater1.DataSource = list;
    this.Repeater1.DataBind();

    }
    }

    在后台的服务中,我们使用示例查询进行处理。

    示例查询类型定义在命名空间 NHibernate.Criterion 中,使用静态方法 Create 可以创建示例对象。

    首先创建一个查询条件对象,然后使用 Example 的 Create 方法创建出查询示例对象。最后就是实际的查询。

    public IList<Demo.Dao.Domain.User> GetUsers( Demo.Dao.Domain.User exampleUser)
    {
    // 创建查询标准
    global::NHibernate.ICriteria criteria
    = this.Session.CreateCriteria<Demo.Dao.Domain.User>();

    // 创建查询示例
    global::NHibernate.Criterion.Example example
    = global::NHibernate.Criterion.Example.Create(exampleUser);

    // 设置使用示例对象的查询条件
    criteria.Add(example);

    example.EnableLike(global::NHibernate.Criterion.MatchMode.Anywhere);

    IList< Demo.Dao.Domain.User> list = criteria.List<Demo.Dao.Domain.User>();

    return list;
    }

    对于字符串类型的条件来说,默认使用精确匹配,但是,可以通过示例的 EnableLike 进行设置。NHibernate.Criterion.MatchMode 是一个枚举,支持下面的匹配模式。

    // 默认字符串是完全匹配,可以通过 EnableLike 进行设置
    // Anywhere 表示任何位置匹配
    // End 出现在最后位置
    // Start 出现在起始位置
    // Exact 完全匹配,默认设置
    example.EnableLike(global::NHibernate.Criterion.MatchMode.Anywhere);

    当在姓名的输入框中输入 a 的时候,NHibernate 生成的 SQL 语句如下:

    SELECT this_.UserId as UserId0_0_, this_.Username as Username0_0_, this_.Password as Password0_0_, this_.AddressId as AddressId0_0_ 
    FROM
    tbl_Users this_
    WHERE
    (this_.Username like @p0)
     
    除了强大的 EnableLike 之外,还提供了几个设置参数,比较常用的有 ExcludeZeroes() 方法,它可以排除属性中值为 0 的属性。
    比如,在 User 中增加一个 Age 的整数类型属性,还导致查询语句变成下面的 SQL
    SELECT this_.UserId as UserId0_0_, this_.Username as Username0_0_, this_.Password as Password0_0_, 

    this_.Age as Age0_0_, this_.AddressId as AddressId0_0_
    FROM tbl_Users this_
    WHERE (this_.Username like @p0 and this_.Age = @p1)

    使用排除 0 的设置
    // 排除值为 0 的属性
    example.ExcludeZeroes();
    现在的 SQL 又成为
    SELECT this_.UserId as UserId0_0_, this_.Username as Username0_0_, this_.Password as Password0_0_, 

    this_.Age as Age0_0_, this_.AddressId as AddressId0_0_
    FROM tbl_Users this_
    WHERE (this_.Username like @p0)
    不过,还有两个设置就要小心了。
    ExcludeNulls() 方法,看起来是排除值为 null 的属性,不过,代码中是先调用了 ToString() 方法,然后再看字符串的长度,所以会使得前面的 ExcludeZeroes() 失效。
    SELECT this_.UserId as UserId0_0_, this_.Username as Username0_0_, this_.Password as Password0_0_, 

    this_.Age as Age0_0_, this_.AddressId as AddressId0_0_
    FROM tbl_Users this_
    WHERE (this_.Username like @p0 and this_.Age = @p1)
    ExcludeNone() 方法,表示需要使用示例对象的所有属性,也会使得 ExcludeZeroes() 失效。
    SELECT this_.UserId as UserId0_0_, this_.Username as Username0_0_, this_.Password as Password0_0_, 

    this_.Age as Age0_0_, this_.AddressId as AddressId0_0_
    FROM tbl_Users this_
    WHERE (this_.Username like @p0 and this_.Password is null and this_.Age = @p1)

    最后,还有一个 IgnoreCase() 方法, 使用不区分大小写的方法比较字符串,对于 Oracle 是有效的,对于 SQL Server 就用不到了。
    SELECT this_.UserId as UserId0_0_, this_.Username as Username0_0_, this_.Password as Password0_0_, 

    this_.Age as Age0_0_, this_.AddressId as AddressId0_0_
    FROM tbl_Users this_
    WHERE (lower(this_.Username) like lower(@p0) and this_.Age = @p1)
  • 相关阅读:
    采用多种算法,模拟摇奖:从1-36中随机抽出8个不重复的数字
    有一百匹马,驮一百担货,大马驮3担,中马驮2担,两只小马驮1担,问有大,中,小马各几匹?
    5文钱可以买一只公鸡,3文钱可以买一只母鸡,1文钱可以买3只雏鸡。现在用100文钱买100只鸡,那么各有公鸡、母鸡、雏鸡多少只?请编写程序实现。
    集合相关题目0927
    输入输出作业
    IO流,File类的测试........课堂加总结
    使用泛型............课堂
    Map 映射
    Set
    List相关知识点.......课堂加整理
  • 原文地址:https://www.cnblogs.com/haogj/p/2255848.html
Copyright © 2011-2022 走看看