分享Db4o的便捷封装类源码

简介: 导言 大家好,话说真是好久好久没写文章了,哈哈。 最近在写网站,个人对传统数据库天然抵触,感觉非常繁冗,即便是Entity Framework也过于庞杂了,Db4o这种轻量级且读写、配置都极其方便的新型数据库非常适合我。

导言

大家好,话说真是好久好久没写文章了,哈哈。

最近在写网站,个人对传统数据库天然抵触,感觉非常繁冗,即便是Entity Framework也过于庞杂了,Db4o这种轻量级且读写、配置都极其方便的新型数据库非常适合我。

不过我发现Db4o这么多年发展下来,竟然仍旧没多少中文资料可寻,很奇怪为什么这么优秀的数据库国内使用率极低呢?于是我就想尝试自己来写一些心得什么的,为Db4o在国内的传播尽微薄之力吧。

此次分享的是自己写的工具类代码,封装了Db4o的一种基本使用方式,高度优化了调用体验,下面直接介绍用法,源代码在文章末尾贴出。

初始化

如果是桌面应用的话,那就在程序开始时直接初始化即可:

        /// <summary>
        /// Db4o服务器管理器
        /// </summary>
        public static Db4oServerManager Db4oServerManager=new Db4oServerManager("db.db4o");

如果是网站,建议在Global.asax里作为网站核心类的静态属性,并在网站启动时初始化:

    public class MvcApplication : System.Web.HttpApplication
    {
        /// <summary>
        /// Db4o服务器管理器
        /// </summary>
        public static Db4oServerManager Db4oServerManager;

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            Db4oServerManager = new Db4oServerManager(Server.MapPath(System.Configuration.ConfigurationManager.ConnectionStrings["db4o"].ConnectionString));
        }

        public override void Dispose()
        {
            Db4oServerManager.Dispose();
            base.Dispose();
        }
    }

然后记得在Web.config里配置数据库存放路径:

    <connectionStrings>
        <add name="db4o" connectionString="/App_Data/db.db4o"/>
    </connectionStrings>

调用方法

注:下文以网站项目为例

建议采用Lambda表达式方法调用:

                    //无返回值调用方法
                    MvcApplication.Db4oServerManager.Access(q =>
                    {
                        //查找相同ID的对象,以进行更新,否则直接存储将存储为新对象
                        var u = q.Query<ApplicationUser>(t => t.Id == user.Id).First();
                        u.用户信息.名称 = model.DisplayName;
                        //必须明确存储子对象才能得到正确更新,因为默认貌似没有开启级联更新(新建对象存储时会默认自动存储子对象,但更新对象时不会自动更新子对象)
                        q.Store(u.用户信息);
                    });
                    //有返回值调用方法
                    return MvcApplication.Db4oServerManager.AccessAndReturn(q => q.Query<WebSite.Models.ApplicationUser>(t => t.UserName == User.Identity.GetUserName()).First().用户信息.名称)

下面是传统一些的调用方式:

            using (var dbsa = MvcApplication.Db4oServerManager.CreatAccessor())
            {
                var finduser = dbsa.Query<TUser>(q => q.Id == user.Id).FirstOrDefault();
                dbsa.Delete(finduser);
            }

源代码

    /// <summary>
    /// Db4o服务器访问器。注意,对数据进行修改后必须释放此对象才能真正的将更改提交到服务器。建议配合using(var dbsa=new Db4oServerAccessor(...)){...}语句使用
    /// </summary>
    // ReSharper disable once InconsistentNaming
    public class Db4oServerAccessor : IDisposable
    {
        // ReSharper disable once InconsistentNaming
        private IObjectContainer DBContainer { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="serverManager">Db4o服务器管理器</param>
        public Db4oServerAccessor(Db4oServerManager serverManager)
        {
            DBContainer = serverManager.OpenClient();
        }

        public void Store(object o)
        {
            DBContainer.Store(o);
        }

        public IDb4oLinqQuery<T> Query<T>(Predicate<T> p)
        {
            return from T q in DBContainer where p(q) select q;
        }

        public IDb4oLinqQuery<T> QueryAll<T>()
        {
            return from T q in DBContainer select q;
        }

        public int Count<T>(IDb4oLinqQuery<T> collection)
        {
            return collection.Count();
        }

        public int CountAll<T>()
        {
            return QueryAll<T>().Count();
        }

        public int Count<T>(Predicate<T> p)
        {
            return Query(p).Count();
        }

        public int CountAllByExt<T>()
        {
            foreach (var storedClass in DBContainer.Ext().StoredClasses())
            {
                if (storedClass.GetName() == typeof(T).FullName) return storedClass.InstanceCount();
            }
            return 0;
        }

        public void Delete(object o)
        {
            DBContainer.Delete(o);
        }

        public void Delete<T>(Predicate<T> p)
        {
            foreach (var f in Query<T>(p))
            {
                Delete(f);
            }
        }

        #region IDisposable 成员

        public void Dispose()
        {
            DBContainer.Dispose();
        }

        #endregion
    }
    /// <summary>
    /// Db4o服务器管理器
    /// </summary>
    // ReSharper disable once InconsistentNaming
    public class Db4oServerManager : IDisposable
    {
        private IObjectServer _db4OServer;
        private readonly string _dbFilePath;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbFilePath">数据库文件路径,通常使用Server.MapPath("/xxxx/xx.xx")函数获取到。</param>
        public Db4oServerManager(string dbFilePath)
        {
            _dbFilePath = dbFilePath;
            OpenServer();
        }

        private void OpenServer()
        {
            IServerConfiguration serverConfig = Db4oClientServer.NewServerConfiguration();
            _db4OServer = Db4oClientServer.OpenServer(serverConfig, _dbFilePath, 0);
        }

        /// <summary>
        /// 开启一个客户端实例
        /// </summary>
        /// <returns>客户端实例</returns>
        public IObjectContainer OpenClient()
        {
        Begin:
            try
            {
                return _db4OServer.OpenClient();
            }
            catch
            {
                OpenServer();
                goto Begin;
            }
        }

        /// <summary>
        /// 创建一个服务器访问器对象。注意,对数据进行修改后必须释放此对象才能真正的将更改提交到服务器。
        /// </summary>
        /// <returns>一个服务器访问器对象</returns>
        public Db4oServerAccessor CreatAccessor()
        {
            return new Db4oServerAccessor(this);
        }

        /// <summary>
        /// 创建并访问一个服务器访问器对象。
        /// </summary>
        /// <param name="action">对服务器访问器对象的操作行为</param>
        public void Access(Action<Db4oServerAccessor> action)
        {
            using (var dba = CreatAccessor())
            {
                action(dba);
            }
        }

        /// <summary>
        /// 创建并访问一个服务器访问器对象,继而获得返回值。
        /// </summary>
        /// <param name="action">对服务器访问器对象的操作行为</param>
        /// <typeparam name="T">返回值类型</typeparam>
        public T AccessAndReturn<T>(Func<Db4oServerAccessor,T> action)
        {
            T v = default(T);
            using (var dba = CreatAccessor())
            {
                v= action(dba);
                //System.Diagnostics.Debug.WriteLine(v.ToString());
            }
            return v;
        }

        #region IDisposable 成员

        public void Dispose()
        {
            _db4OServer.Dispose();
        }

        #endregion
    }

结语

最后容我再郑重向大家强力推荐一下Db4o,真心的,桌面、网站、移动无往不利,你值得拥有。


本文转自斯克迪亚博客园博客,原文链接:http://www.cnblogs.com/SkyD/p/3574651.html,如需转载请自行联系原作者


相关文章
|
分布式计算 API Linux
通义千问API:找出两篇文章的不同
本章我们将介绍如何利用大模型开发一个文档比对小工具,我们将用这个工具来给互联网上两篇内容相近但版本不同的文档找找茬,并且我们提供了一种批处理文档比对的方案
|
7月前
|
Python
课时20:集合的运算
本内容介绍集合的运算,涵盖交集、并集、差集、异或集及子集等概念。通过Python代码示例详细说明各运算符(如 &、|、-、^、&lt;=、&lt;、&gt;=、&gt;)的使用方法,并解释其在实际编程中的应用。重点在于理解集合运算的基本原理及其在编程中的实现,帮助读者掌握集合运算的基础知识。
|
11月前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
217 8
|
SQL 存储 分布式计算
Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别(三)
Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别(三)
383 0
Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别(三)
|
存储 机器学习/深度学习 人工智能
Data topic details | Data
数据结构结构教程 李春葆(第五版)习题
286 0
Data topic details | Data
|
算法 对象存储 Python
python|面向对象-2|探讨继承和多态
python|面向对象-2|探讨继承和多态
224 0
如何对集成树进行解释?(中)
如何对集成树进行解释?(中)
399 0
如何对集成树进行解释?(中)
|
监控 安全 网络安全
APP安全防护防黑客攻击的手法介绍
在当今数字时代,移动应用的数量呈爆炸性增长,涵盖金融、电子商务、社区、医疗、房地产、工业等各行各业。在给人类带来便利的同时,也给黑客带来了可乘之机,移动黑产也越来越强大,他们的重点是从传统的PC网站转移到移动互联网的战场。尽管国内近五年互联网安全行业发展迅速,优秀的安全防护产品层出不穷,但黑客攻击手段也日益变化,想从根本上解决互联网安全问题,目前无从下手。
531 0
APP安全防护防黑客攻击的手法介绍
BrokenPipeError: [Errno 32] Broken pipe解决方法
BrokenPipeError: [Errno 32] Broken pipe解决方法
1722 0
|
5天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾