Castle ActiveRecord学习实践(6):延迟加载和使用Where子句

Castle ActiveRecord学习实践(6):延迟加载和使用Where子句

摘要:在ActiveRecord中把数据库表之间的关联关系采用对象间的聚合关系来表现,然而这却带来一系列的性能上的问题。就像我在One-Many中用到的例子Blog,使用Blog.Find(1)查找了一个Blog对象,也许我们只用到它,但事实它却把该Blog所关联的Post对象也读取出来放在了内存中,于是我们就需要有一种方法来实现只在需要Post对象的时候框架再自动读取。另外ActiveRecord只提供了Find(id),FindAll()这样两个静态的查询方法,在我们查询中还远远不够,这方面ActiveRecord为我们提供了HQL语言的支持,同时也可以通过设置Where子句来实现一些简单的查询。

 

主要内容

1.实现延迟加载

2.使用Where子句

 

一.实现延迟加载

要实现延迟加载,其实只要在HasMany特性中使用Lazy=true就可以了。来看我们的Blog类是如何声明的:

None.gif
[ActiveRecord(

Blogs

)]
None.gif
None.gif

public
 
class
 Blog : ActiveRecordBase
None.gif
ExpandedBlockStart.gifContractedBlock.gif

dot.gif
{

InBlock.gif
InBlock.gif    
private int _id;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
private String _name;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
private String _author;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
private IList _posts;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    [PrimaryKey(PrimaryKeyType.Identity, 
blog_id)]
InBlock.gif
InBlock.gif    
public int Id
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _id; }
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _id = value; }
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    [Property(
blog_name)]
InBlock.gif
InBlock.gif    
public String Name
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _name; }
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _name = value; }
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    [Property(
blog_author)]
InBlock.gif
InBlock.gif    
public String Author
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _author; }
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _author = value; }
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    [HasMany(
typeof(Post), Table=posts, ColumnKey=post_blogid,Lazy=true)]
InBlock.gif
InBlock.gif    
public IList Posts
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _posts; }
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _posts = value; }
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
public static void DeleteAll()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{

InBlock.gif
InBlock.gif        DeleteAll( 
typeof(Blog) );
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
public static Blog[] FindAll()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{

InBlock.gif
InBlock.gif        
return (Blog[]) FindAll( typeof(Blog) );
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
public static Blog Find(int id)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{

InBlock.gif
InBlock.gif        
return (Blog) FindByPrimaryKey( typeof(Blog), id );
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

可以看到唯一与我们前面声明的Blog类不同的地方就在于下面这句话:

[HasMany(typeof(Post), Table=“posts”, ColumnKey=“post_blogid”,Lazy=true)]

现在我们来写一个简单的测试代码:

None.gif
[Test]
None.gif
None.gif

public
 
void
 TestLazyLoad()
None.gif
ExpandedBlockStart.gifContractedBlock.gif

dot.gif
{

InBlock.gif
InBlock.gif    
//找到Blog对象
InBlock.gif

InBlock.gif    Blog blog 
= Blog.Find(8);
InBlock.gif
InBlock.gif    
string resultName = blog.Name;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
//执行这句话的时候才载入Post对象
InBlock.gif

InBlock.gif    
int resultCount = blog.Posts.Count;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
string expectedName = Terrylee;
InBlock.gif
InBlock.gif    
int expectedCount = 2;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    Assert.IsNotNull(blog);
InBlock.gif
InBlock.gif    Assert.AreEqual(expectedName,resultName);
InBlock.gif
InBlock.gif    Assert.AreEqual(expectedCount,resultCount);
InBlock.gif
ExpandedBlockEnd.gif}

测试,红灯!?报出了下面的错误:

ARDemo.OneManyFixture.TestLazyLoad : NHibernate.LazyInitializationException : Failed to lazily initialize a collection – no session

问题出在了我们得到Blog对象后,并没有把当前的Session保存下来,ActiveRecord在实现延迟载入时找不到一个NHibernateISession。为了保存当前的Session我们必须使用new SessionScope(),重新修改我们的测试代码之后:

None.gif
[Test]
None.gif
None.gif

public
 
void
 TestLazyLoad()
None.gif
ExpandedBlockStart.gifContractedBlock.gif

dot.gif
{

InBlock.gif
InBlock.gif    
using(new SessionScope())
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{

InBlock.gif
InBlock.gif        
//找到Blog对象
InBlock.gif

InBlock.gif        Blog blog 
= Blog.Find(8);
InBlock.gif
InBlock.gif        
string resultName = blog.Name;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        
//执行这句话的时候才载入Post对象
InBlock.gif

InBlock.gif        
int resultCount = blog.Posts.Count;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        
string expectedName = Tech Space;
InBlock.gif
InBlock.gif        
int expectedCount = 2;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        Assert.IsNotNull(blog);
InBlock.gif
InBlock.gif        Assert.AreEqual(expectedName,resultName);
InBlock.gif
InBlock.gif        Assert.AreEqual(expectedCount,resultCount);
InBlock.gif
ExpandedSubBlockEnd.gif    }
   
InBlock.gif
ExpandedBlockEnd.gif}

现在测试可以正常通过了,大家在使用延迟载入的时候不要忘了new SessionScope()

 

二.使用Where子句

ActiveRecord中实现稍微复杂的一点的查询,我们就不能用使用Find(id)FindAll()这两个静态的方法了,这时就需要使用HQL语句来实现,这个在后续文章中我会专门用一篇文章来介绍。我们也可以使用ActiveRecord来实现一些简单的查询,个人认为,这种查询把条件写在了特性里面,以一种硬编码的方式来实现,灵活性变得很差,使用的情况不是很多。看一个简单的例子,比如我们要查询某人发表的Category为“Castle”的Posts,可以在Blog实体类中添加一个CastlePosts的特性:

None.gif
[HasMany(
typeof
(Post),Table
=

posts

, ColumnKey
=

post_blogid

,Where
=

post_categories=’Castle’

)]
None.gif
None.gif

public
 IList CastlePosts
None.gif
ExpandedBlockStart.gifContractedBlock.gif

dot.gif
{

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
get dot.gifreturn _posts; }
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
set dot.gif{ _posts = value; }
InBlock.gif
ExpandedBlockEnd.gif}

注意:在
Where
中写条件时所用的
Posts
表的字段名,而不是
Post
实体类对应的属性

 

编写一个简单的测试代码:

None.gif
[Test]
None.gif
None.gif

public
 
void
 TestCondWhere()
None.gif
ExpandedBlockStart.gifContractedBlock.gif

dot.gif
{

InBlock.gif
InBlock.gif    
//找到Blog对象
InBlock.gif

InBlock.gif    Blog blog 
= Blog.Find(8);
InBlock.gif
InBlock.gif    
InBlock.gif
InBlock.gif    
//获取Castle的Posts数量
InBlock.gif

InBlock.gif    
int resultCount = blog.CastlePosts.Count;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
int expectedCount = 2;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    Assert.IsNotNull(blog);
InBlock.gif
InBlock.gif    Assert.AreEqual(expectedCount,resultCount); 
InBlock.gif
ExpandedBlockEnd.gif}

 

这里我们调用CastlePosts得到的就是CategoryCastlePosts。关于延迟加载和使用Where子句就介绍到这儿了。下篇文章介绍如何在RectiveRecord中验证输入数据的有效性。

 

 

参考资料

Castle的官方网站http://www.castleproject.org

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111149.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Execute_getqueryvariable

    Execute_getqueryvariableExecuteScalar :返回第一列,第一行的数据。   第一列第一行不为空,那么ExecuteScalar就直接对应的值。   有第一行,但是第一列为空,那么返回的是 DBNull 。一行都没有,那么ExecuteScalar就返回null  ExecuteNonQuery():执行SQL,返回一个整型变量,如果SQL是对数据库的记录进行操作,那么返回操作影响的记录条数

    2022年9月11日
    2
  • 能用python开发手机软件吗_python numpy

    能用python开发手机软件吗_python numpy有许多人对如何在手机上进行python开发感到很困惑,今天我就给大家推荐几个比较好的python开发软件。一.QPythonOHQPython真的是一款好的软件,它可以支持Python库的安装。内置sl4aserver,简直是一款神器!二.Pydroid3Pydroid3是我目前见过的最好的一款python编辑器,他可以使用pip,甚至可以在手机上掉。…

    2022年8月12日
    5
  • EM算法 实例讲解「建议收藏」

    EM算法 实例讲解「建议收藏」第一次接触EM算法,是在完成半隐马尔科夫算法大作业时。我先在网上下载了两份Baum-Welch算法的代码,通过复制粘贴,修修补补,用java实现了HMM算法(应用是韦小宝掷两种骰子的问题)。然后,参考有关半隐马尔科夫算法的论文,照着论文中的公式修改隐马尔科夫算法,完成了大作业。现在回想起来,就隐隐约约记得有一大堆公式。最近,我看到一篇很好的文章,对EM算法的计算有了进一步的了解,文章链接为http

    2022年6月22日
    31
  • Windows下openssl安装及使用「建议收藏」

    配置过程中需要生成一些mak文件,这些生成代码用perl脚本生成,所以要安装一个ActivePerl.网址:http://www.activestate.com/activeperl/下载后直接安装就行了!下载openssl网址http://www.openssl.org/我用的是openssl-0.9.8g版本,解压到c盘根目录。安装步骤:(可以参照o…

    2022年4月11日
    288
  • NSGA2 算法MATLAB完整代码 中文注释详解

    NSGA2 算法MATLAB完整代码 中文注释详解2019.7.17很意外本人这篇文章受到很多人的关注,在此把源码贴出来供大家更好的理解学习。https://download.csdn.net/download/joekepler/10590751========================分割=====================================本人最近研究NSGA2算法,网上有很多示例代码,但是基本没有…

    2022年5月12日
    44
  • 解决项目中java heap space的问题[通俗易懂]

    解决项目中java heap space的问题[通俗易懂]起因 17年的一个项目出了OOM(javaheapspace)问题,眼下有个问题:法院项目,不能外网,一连接外网高院会直接定位到计算机,发出警报(档案的机密性啊)不能远程,那只能视频教他们怎么做了,全程和一个文员说代码,真的很累==! 过程 这个过程对一个不太了解内存的问题的开发无疑是艰难的,搜了一下,知道了是内存溢出导致的,于是着手解决 网上大多数都说调整运行…

    2022年7月8日
    23

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号