CastleActiveRecord 二级缓存心得
在使用CaslteActiveRecord开启二级缓存时
1、如果一个实体标记了 缓存属性,则无论该类是 通过ID查询还是其它方式的查询得到的结果,都会自动缓存,标记如下:
所以,不必再担心结果是否能够按照预期的需要缓存。
[ActiveRecord("T_GeographicBoundary",Cache=CacheEnum.NonStrictReadWrite)]
public class DALGeographicBoundary : ActiveRecordBase<DALGeographicBoundary>
{
}
{
}
2、查询缓存如何使用? 在CastleActiveRecord中的查询类没有提供对查询缓存的支持,只能使用NHibernate的查询才可以,例子如下:
public static DALGeographicBoundary[] Find(string name)
{
string queryString = @"select distinct c from DALGeographicBoundary as c ";
if (!string.IsNullOrEmpty(name))
{
queryString += " where c.Name like :Name or c.Code like :Name or c.EnglishName like :Name or c.PinYin like :Name or c.FullPinYin like :Name ";
}
queryString += " order by c.Name asc ";
ISessionFactoryHolder sessionFactory = ActiveRecordMediator.GetSessionFactoryHolder();
ISession session = sessionFactory.CreateSession(typeof(DALGeographicBoundary));
IQuery query = session.CreateQuery(queryString);
if (!string.IsNullOrEmpty(name))
{
query.SetParameter<string>("Name", string.Format("%{0}%", name));
}
query.SetCacheable(true);
IList<DALGeographicBoundary> userlist = query.List<DALGeographicBoundary>();
if (userlist != null && userlist.Count > 0)
{
DALGeographicBoundary[] temp = new DALGeographicBoundary[userlist.Count];
userlist.CopyTo(temp, 0);
return temp;
}
else
{
return null;
}
}
string queryString = @"select distinct c from DALGeographicBoundary as c ";
if (!string.IsNullOrEmpty(name))
{
queryString += " where c.Name like :Name or c.Code like :Name or c.EnglishName like :Name or c.PinYin like :Name or c.FullPinYin like :Name ";
}
queryString += " order by c.Name asc ";
ISessionFactoryHolder sessionFactory = ActiveRecordMediator.GetSessionFactoryHolder();
ISession session = sessionFactory.CreateSession(typeof(DALGeographicBoundary));
IQuery query = session.CreateQuery(queryString);
if (!string.IsNullOrEmpty(name))
{
query.SetParameter<string>("Name", string.Format("%{0}%", name));
}
query.SetCacheable(true);
IList<DALGeographicBoundary> userlist = query.List<DALGeographicBoundary>();
if (userlist != null && userlist.Count > 0)
{
DALGeographicBoundary[] temp = new DALGeographicBoundary[userlist.Count];
userlist.CopyTo(temp, 0);
return temp;
}
else
{
return null;
}
}
3、缓存的性能,缓存在一定程度上可以提高应用的性能,但需要正确认使用,如果使用不慎,缓存反而成为负担,比如,在应用中如果使用NHibernate.Caches.Prevalence 做为缓存提供程序,如果数据量大,它要在指定目录下写入缓存文件,IO消耗相当大,虽然数据库访问少了,但是应用的IO却增长,还不如不使用缓存。因此,使用缓存时应尽量避免使用文件型缓存,应使用内存型缓存。
4、如何使用缓存,缓存的策略。
查询缓存应只对只读性数据进行缓存,如果是经常读写的数据,可能造成数据不一致。
5、使用缓存的几种方法
public static DALDictionaries[] FindByCategory(int ownerID, string category)
{
//string queryString = @"select distinct dics from DALDictionaries as dics where dics.OwnerID=:OwnerID and dics.Category=:Category order by dics.SortIndex";
//SimpleQuery<DALDictionaries> sq = new SimpleQuery<DALDictionaries>(queryString);
//sq.SetParameter("OwnerID", ownerID);
//sq.SetParameter("Category", category);
//return sq.Execute();
string queryString = @"select distinct dics from DALDictionaries as dics where dics.OwnerID=:OwnerID and dics.Category=:Category order by dics.SortIndex ";
ISessionFactoryHolder sessionFactory = ActiveRecordMediator.GetSessionFactoryHolder();
ISession session = sessionFactory.CreateSession(typeof(DALDictionaries));
IQuery query = session.CreateQuery(queryString);
query.SetParameter("OwnerID", ownerID);
query.SetParameter("Category", category);
query.SetCacheable(true);
IList<DALDictionaries> list = query.List<DALDictionaries>();
return list.ToArray<DALDictionaries>();
//string queryString = @"select distinct dics.ID from DALDictionaries as dics where dics.OwnerID=:OwnerID and dics.Category=:Category ";
//SimpleQuery<int> sq = new SimpleQuery<int>(typeof(DALDictionaries), queryString);
//sq.SetParameter("OwnerID", ownerID);
//sq.SetParameter("Category", category);
//int[] ids = sq.Execute();
//if (ids != null && ids.Length > 0)
//{
// List<DALDictionaries> temp = new List<DALDictionaries>();
// foreach (int id in ids)
// {
// temp.Add(DALDictionaries.Find(id));
// }
// temp.Sort<DALDictionaries>(new string[] { "SortIndex" });
// return temp.ToArray();
//}
//else
//{
// return null;
//}
}
{
//string queryString = @"select distinct dics from DALDictionaries as dics where dics.OwnerID=:OwnerID and dics.Category=:Category order by dics.SortIndex";
//SimpleQuery<DALDictionaries> sq = new SimpleQuery<DALDictionaries>(queryString);
//sq.SetParameter("OwnerID", ownerID);
//sq.SetParameter("Category", category);
//return sq.Execute();
string queryString = @"select distinct dics from DALDictionaries as dics where dics.OwnerID=:OwnerID and dics.Category=:Category order by dics.SortIndex ";
ISessionFactoryHolder sessionFactory = ActiveRecordMediator.GetSessionFactoryHolder();
ISession session = sessionFactory.CreateSession(typeof(DALDictionaries));
IQuery query = session.CreateQuery(queryString);
query.SetParameter("OwnerID", ownerID);
query.SetParameter("Category", category);
query.SetCacheable(true);
IList<DALDictionaries> list = query.List<DALDictionaries>();
return list.ToArray<DALDictionaries>();
//string queryString = @"select distinct dics.ID from DALDictionaries as dics where dics.OwnerID=:OwnerID and dics.Category=:Category ";
//SimpleQuery<int> sq = new SimpleQuery<int>(typeof(DALDictionaries), queryString);
//sq.SetParameter("OwnerID", ownerID);
//sq.SetParameter("Category", category);
//int[] ids = sq.Execute();
//if (ids != null && ids.Length > 0)
//{
// List<DALDictionaries> temp = new List<DALDictionaries>();
// foreach (int id in ids)
// {
// temp.Add(DALDictionaries.Find(id));
// }
// temp.Sort<DALDictionaries>(new string[] { "SortIndex" });
// return temp.ToArray();
//}
//else
//{
// return null;
//}
}
6、如果实体有继承关系,必须在被继承的类上也标记使用 缓存,否则,子类的缓存无效。
7、如果对查询进行缓存,必须实体也要标记缓存,否则查询缓存无效。