手把手教你写ORM(七)

恕我卖个关子,如何得到Attribute的问题先放一放,肯定通过反射,有兴趣的也可以自己研究研究
今天先来说缓存的问题,对于数据缓存就我自己来说经历过很多次的反复,不过在.NET社区很多人都支持按需读取的原则,不过我觉的这是个误区,在单击程序的时候由于个人电脑的内存比较小和多用途性,很多程序都强调尽量少占用内存。不过在写服务程序的时候就是一个误区了,把常用数据缓存起来,在需要的时候快速调用才是提高性能的法宝,现在个人电脑的内存都按G算的年代,如何合理充分利用内存才是正途。
所以我们决定要在我们的demo orm中实现一个缓存,缓存什么呢?,insert语句的执行结果显然是不用了,我们只需要缓存每一次select的结果。并且由于.NET的Cache对象的局限性(只能在Web用),我们只有自己来实现一个。
其实设计上并不困难,我们之前在对配置的处理上其实已经用到了缓存的,我们只需要对其作一下修改,首先基础结构还是静态的HashTable,不过需要先确定以下用什么做Key,value好说,HashTable的Value就是个object,所以存个IList也行,int也行,一个对象也行,所以对于Select的结果来说还是很合适的。
主要就是确定Key的问题
我们这里确定一个前提就是,数据如果不变的情况下,那么如果Sql语句一样的话,select的结果应该都是一样的,那么我们直接用Sql语句来做Key。但是有的SQl是带变量的,比如select XX from TT where ID=@ID,
这个时候我们把Sql处理处理,用值把@ID Replace掉就行了:}

但是还有一个问题,如果有表被Insert了数据,或者update了数据,或者Delete了数据,那么之后Select出来的不就变了?确实,所以我们在做了这些操作后就要判断哪些缓存项是需要刷新的了。这个时候我们需要Key里面包含表的信息,虽然可以直接分析Sql获取,不过加大了成本,所以我们在生成Key的时候就把这条SQL涉及的表用[Tablename]的方式加在Key的最前面。

最后我们来看看代码:
namespace Alexander.Xbase.Xcache
{
    
public class ObjCache
    
{
        
private static SortedList<stringobject> data = new SortedList<stringobject>();

        
public static void Insert(string Key, object dat)
        
{
            data.Add(Key, dat);
        }

        
public static SortedList<stringobject> GetObject
        
{
            
get
            
{
                
return data;
            }

        }

        
public static void Flash(string Classname)
        
{
            ArrayList removelist 
= new ArrayList();
            
for (int i = 0; i < data.Count; i++)
            
{
                
if (data.Keys[i].StartsWith(Classname))
                
{
                    removelist.Add(data.Keys[i]);
                }

            }

            
foreach (object o in removelist)
            
{
                data.Remove(o.ToString());
            }

        }

    }

}

说了半天其实代码也不多,有的时候觉得很复杂的其实就这么简单。
不过这种Cache比较局限的就是可能Cache冗余的数据

to be continue......

posted on 2007-01-25 10:39 亚历山大同志 阅读(2146) 评论(10)  编辑 收藏 网摘 所属分类: 手把手系列

评论

#1楼 2007-01-25 11:39 anikin      

Flash? 是flush吧   回复  引用  查看    

#2楼[楼主] 2007-01-25 11:52 亚历山大同志      

@anikin
笔误,我写代码的时候常写错单词,不过谢谢纠正
  回复  引用  查看    

#3楼 2007-01-25 12:05 henry      

既然有点无聊就再回一次吧,看来任何问题在楼主脑子里都会变得简单:)
内存多得用不完,缓存200W条数据?然后在这200W再作一个匹配查询,如果不在内存建立相关字段索引那这200W缓存变得毫无用处(就凭.NET内部提供基础算法的对象操作是远远不够的)!
在没有相关索引的情况下,即使在内存匹配某些数据操作不见得比直接查询数据库快.

还有即使写例子也最好严紧一点,处理这些东西线程同步是必须的.
  回复  引用  查看    

#4楼[楼主] 2007-01-25 12:42 亚历山大同志      

@henry
["内存多得用不完,缓存200W条数据?"]请不要把前面的关于内存数据库的东西带入这里,这里缓存SQL执行的结果,而这些结果都是有限集合,因为是支持分页的,所以这里也可以对每个单独页进行处理。
希望你看了完整源代码再作评论,草率的下结论是不负责任的,这里我只是Cache而已,遇到相同的Sql就直接到缓存取数据而不用去数据库了,至于缓存的规模是可以控制的,因为可以配置那一些Sql可以被缓存,ibaites也是这样子的。所以你所谓的内存建立地段索引之类的在这里是没有意义的。

关于线程得问题,作为demo来说越简单越好,也比较直观容易懂。.NET的线程同步不复杂,加个Attribute就行了

最后十分感谢给我挑刺
  回复  引用  查看    

#5楼 2007-01-31 15:06 jyk[未注册用户]

我关心的不是如何缓存数据,因为SQL2000已经为我们做了。

我最想知道的是能不能缓存html代码,就是加了数据之后的那些html。

举个例子吧,假设用DataGird来显示表里的一些记录,用户看到的是一个table,你说的这些是缓存数据记录,我想问的是能不能直接缓存 这个 table。

  回复  引用    

#6楼 2007-01-31 22:29 ColdDog      

@jyk
当然可以了
缓存页面嘛
可以用页面缓存,或者用有点和页面缓存相反的片段缓存,可能描述的不是很明确,我blog上有相关文章介绍:)

另外,我问下亚力大哥,你写的ORM这个教程,在SQL语句方面是怎么处理的?是即时生成的还是写好的呢?
  回复  引用  查看    

#7楼[楼主] 2007-02-01 08:22 亚历山大同志      

@ColdDog
Sql方面类似ibaties,对每个类有个Xml的配置文件,用来设置这个类所涉及的Sql语句,这样子有个好处是可以人工优化Sql提高效率,特别是在查询时指定索引对效率的提高尤为明显,还有就是这里对查询的缓存也是在这里设置,对设置了要缓存的Sql的查询结果缓存起来,当下一次调用的时候就直接从缓存获取,基本上没有开销,对分页的SQL是把每一个页的查询当作一次单独的查询缓存,每个页都可以缓存.当这次查询所涉及的表被更新(update,insert,delete了的时候,这个缓存项就会作废,但是不会马上去刷新它,当下一次再次被请求的时候才会被重新加载)
  回复  引用  查看    

#8楼 2007-02-01 14:05 ColdDog      

谢谢!   回复  引用  查看    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 629985




相关文章:

相关链接:

导航

公告

鉴于很多TX投诉黑色背景杀伤眼球,遂换个容易阅读的
PS:背景音乐是电影《斯密斯夫妇》的主题乐 Mondo Bango
!!八强八强!!!!!!!
<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

统计

与我联系

搜索

 

常用链接

留言簿

我参加的小组

我的标签

随笔分类(86)

随笔档案(85)

相册

朋友的Blog

同事的Blog

最新随笔

积分与排名

最新评论

阅读排行榜

评论排行榜