PetaPoco源代码学习--2.TableInfo、ColumnInfo类和Cache类
发布日期:2025-05-02 00:54:13 浏览次数:2 分类:技术文章

本文共 7073 字,大约阅读时间需要 23 分钟。

  当把常用的特性填写到POCO实体类时,执行数据库操作时,需要根据实体类上的特性信息进行相应的操作,PetaPoco中的TableInfo和ColumnInfo类就是用来保存实体类上的特性信息。

TableInfo用来保存数据库表的信息,包括TableName,PrimaryKey,主键是否自增字段,使用Oracle数据库时的Sequence名称。

ColumnInfo用来保存数据库表的列信息,包括ColumnName,是否结果列(不用更新数据库),数据库列类型是否转换为UTC时间、更新模板和插入模板。

  通过POCO实体类获取到其对应的数据库表和数据库列的信息,就可以使用这些信息对数据库表执行增删改查的操作。

TableInfo包括一个静态方法,参数为POCO实体类的Type对象,从该对象上获取自定义特性信息来初始化TableInfo实例。

1     ///  2     /// POCO实体类对应的数据库表信息 3     ///  4     public class TableInfo 5     { 6         ///  7         ///  数据库表名 8         ///  9         public string TableName { get; set; }10 11         /// 12         /// 数据库表主键13         /// 14         public string PrimaryKey { get; set; }15 16         /// 17         /// 主键是否自增18         /// 19         public bool AutoIncrement { get; set; }20 21         /// 22         /// Oracle数据自增主键对应的Sequence名称23         /// 24         public string SequenceName { get; set; }25         26         /// 27         /// 从POCO实体类的特性上初始化TableInfo实例28         /// 29         public static TableInfo FromPoco(Type t)30         {31             TableInfo ti = new TableInfo();32             //从TableNameAttribute上获取数据表名称,若不存在则使用POCO实体类的名称33             var a = t.GetCustomAttributes(typeof(TableNameAttribute), true);34             ti.TableName = a.Length == 0 ? t.Name : (a[0] as TableNameAttribute).Value;35 36             //从PrimaryKeyAttribute上获取数据库表主键名称37             a = t.GetCustomAttributes(typeof(PrimaryKeyAttribute), true);38             ti.PrimaryKey = a.Length == 0 ? null : (a[0] as PrimaryKeyAttribute).Value;39             ti.SequenceName = a.Length == 0 ? null : (a[0] as PrimaryKeyAttribute).SequenceName;40             ti.AutoIncrement = a.Length == 0 ? false : (a[0] as PrimaryKeyAttribute).AutoIncrement;41             //若不存在PrimaryKeyAttribute,则查找实体类属性中名称为“id"或者实体类名称+“id"或者“_id"的类属性。42             if (string.IsNullOrEmpty(ti.PrimaryKey))43             {44                 var prop = t.GetProperties().FirstOrDefault(p =>45                 {46                     if (p.Name.Equals("id", StringComparison.OrdinalIgnoreCase))47                         return true;48                     if (p.Name.Equals(t.Name + "id", StringComparison.OrdinalIgnoreCase))49                         return true;50                     if (p.Name.Equals(t.Name + "_id", StringComparison.OrdinalIgnoreCase))51                         return true;52                     return false;53                 });54                 if (prop != null)55                 {56                     ti.PrimaryKey = prop.Name;57                     ti.AutoIncrement = prop.PropertyType.IsValueType;58                 }59             }60             return ti;61         }62     }

 

ColumnInfo包括一个静态方法,参数为POCO实体类的属性对象,从对象上获取自定义特性信息来初始化ColumnInfo实例

///     /// POCO实体类属性对应的数据库列信息    ///     public class ColumnInfo    {        ///         /// 数据库列名称        ///         public string ColumnName { get; set; }        ///         /// 是否结果值列,是的话,插入和更新操作不使用该属性        ///         public bool ResultColumn { get; set; }        ///         /// 若对应的数据库类类型是DateTime,是否强制转换为UTC时间        ///         public bool ForceToUtc { get; set; }        ///         /// 插入模板(暂未理解使用)        ///         public string InsertTemplate { get; set; }        ///         /// 更新模板(暂未理解使用)        ///         public string UpdateTemplate { get; set; }        ///         /// 从POCO实体类属性的特性初始化ColumnInfo        ///         public static ColumnInfo FromProperty(PropertyInfo propertyInfo)        {            // 获取属性所属的类实例上是否包括明确表示列信息的标志            var explicitColumns = propertyInfo.DeclaringType.GetCustomAttributes(typeof(ExplicitColumnsAttribute), true).Length > 0;            // Check for [Column]/[Ignore] Attributes            var colAttrs = propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), true);            //属性明确指定列信息时,但是该属性没有列特性,返回null            if (explicitColumns)            {                if (colAttrs.Length == 0)                    return null;            }            else            {                //没有明确指定时,该属性没有映射到数据库列,返回null                if (propertyInfo.GetCustomAttributes(typeof(IgnoreAttribute), true).Length != 0)                    return null;            }            //类具有明确映射信息,则从列特性获取对应的数据信息或者没有明确信息时,则使用属性名称初始化。            var ci = new ColumnInfo();            // Read attribute            if (colAttrs.Length > 0)            {                var colattr = (ColumnAttribute) colAttrs[0];                ci.InsertTemplate = colattr.InsertTemplate;                ci.UpdateTemplate = colattr.UpdateTemplate;                ci.ColumnName = colattr.Name == null ? propertyInfo.Name : colattr.Name;                ci.ForceToUtc = colattr.ForceToUtc;                if ((colattr as ResultColumnAttribute) != null)                    ci.ResultColumn = true;            }            else            {                ci.ColumnName = propertyInfo.Name;                ci.ForceToUtc = false;                ci.ResultColumn = false;            }            return ci;        }    }   PetaPoco中定义了一个缓存类,内部使用ReaderWriterLockSlim读写锁来控制读取和写入(ReaderWriterLockSlim支持多线程读取和单线程写入), 其公共方法Get的参数为缓存Key和创建函数,当缓存中没有对应的信息时,则使用创建函数创建信息并缓存起来。 方法内部先获取读取锁获取缓存信息,若没有则获取写入锁,获取后再次确认是否存在缓存信息,主要原因:获取写入锁需要释放之前所有的读写锁,防止在时间差创建了缓存信息。 
1     ///  2     /// 缓存信息类 3     ///  4     internal class Cache
5 { 6 ///
7 /// 读写锁 8 /// 9 private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();10 11 ///
12 /// 存储数据的字典13 /// 14 private Dictionary
_map = new Dictionary
();15 16 ///
17 /// 缓存数据的数目18 /// 19 public int Count20 {21 get { return _map.Count; }22 }23 24 ///
25 /// 根据Key获取对应的数据,若没有数据,则创建它并缓存起来26 /// 27 public TValue Get(TKey key, Func
factory)28 {29 _lock.EnterReadLock();//设置读锁30 TValue val;31 try32 {33 if (_map.TryGetValue(key, out val))34 return val;35 }36 finally37 {38 _lock.ExitReadLock();//释放读锁39 }40 _lock.EnterWriteLock();//没有找到,设置写锁41 try42 {43 //再次检测,避免等待获取写锁的时间差中已创建信息44 if (_map.TryGetValue(key, out val))45 return val;46 //使用传入的创建方法创建信息并缓存起来47 val = factory();48 _map.Add(key, val);49 return val;50 }51 finally52 {53 _lock.ExitWriteLock();//释放写锁54 }55 }56 57 //清空缓存信息58 public void Flush()59 {60 _lock.EnterWriteLock();61 try62 {63 _map.Clear();64 }65 finally66 {67 _lock.ExitWriteLock();68 }69 }70 }
 

转载于:https://www.cnblogs.com/DreamOfLife/p/9119098.html

上一篇:PE启动盘和U启动盘(第三十六课)
下一篇:petalinux环境安装和基本编译

发表评论

最新留言

不错!
[***.144.177.141]2025年04月20日 05时05分32秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章