分享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 ;
} 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, );
} /// <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,真心的,桌面、网站、移动无往不利,你值得拥有。
分享Db4o的便捷封装类源码的更多相关文章
- 分享45个android实例源码,很好很强大
分享45个android实例源码,很好很强大 http://www.apkbus.com/android-20978-1-1.html 分享45个android实例源码,很好很强大http://www ...
- 分享45个android实例源码,很好很强大.收藏吧!!!
andriod闹钟源代码 http://www.apkbus.com/android-20974-1-1.html android源码分享之指南针程序 http://www.apkbus.com/an ...
- Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码)
Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码) 转 https://blog.csdn.net/lhl1124281072/article/details/800 ...
- 【腾讯Bugly干货分享】微信iOS SQLite源码优化实践
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b58022433221be01499480 作者:张三华 前言 随着微信iO ...
- 【分享】Maven插件的源码下载(SVN)
偶然的情况下找到了Maven插件源码的网址,现分享下 http://svn.apache.org/repos/asf/maven/plugins/ 可以使用SVN下载,在添加新的资源路径时,把上面的网 ...
- 阿里P7分享如何面对枯燥的源码
一个软件开发人员,工作到了一定的年限(一般是3.4年左右),如果他还没学会阅读源码,那么他就会遇到瓶颈.因为到了这个时候的开发,他应该不仅仅只会做那些 CURD 的业务逻辑,而应该会根据公司的实际情况 ...
- 分享一套主流框架源码资料,征服阿里 P7 面试必备!
2019年已经过完一半了, 我在这里为大家准备了一份资料,征服阿里 P7 面试必备! 希望这些资料可以帮助到大家,从一个码农进阶为一个优秀的程序员,也可以帮大家提升系统实战能力. 这些资料包括: 讲解 ...
- Webfunny知识分享:webpack sourceMap解析源码
前端的业务越来越庞大,导致我们需要引入的js等静态资源文件的体积也越来越大,不得不使用压缩js文件的方式来提高加载的效率. 编译工具的诞生,极大地方便了我们处理js文件的这一过程,但压缩后的js文件极 ...
- 【源码分享】仿网易客户端源码效果 apkbus的~
http://www.apkbus.com/forum.php?mod=viewthread&tid=184867 内容我就不说了,直接点开看吧.
随机推荐
- 网络转载——java接口的概念
为什么会出现接口? 接口的出现是为了扩展java中的类继承的单调性.这样使得功能更加丰富. 接口关键字? 定义接口interface,实现一个接口 implements 什么接口呢? 接口是一种特殊 ...
- wordpress stratus模板使用 产品显示问题
产品不显示,只显示展示产品代码. 1.研究原站demo,思考产品展示调用自woocommerce. 2.查看woocommerce文档,更新展示代码. 3.修改后产品出现,但是多余的关联推荐也展示出来 ...
- Ubuntu更改鼠标灵敏度
需要命令:xinput 清自行用 man xinput 查询 xinput 帮助文档 1.插入鼠标,打开终端,输入命令:xinput 查询当前已挂在设备 2.拔出鼠标,打开终端,再输入命令:xinpu ...
- Sublim Text3快捷键大全
Ctrl+Shift+P:打开命令面板Ctrl+P:搜索项目中的文件Ctrl+G:跳转到第几行Ctrl+W:关闭当前打开文件Ctrl+Shift+W:关闭所有打开文件Ctrl+Shift+V:粘贴并格 ...
- Objective - C 值对象 NSNumber和NSValue
在进行数据处理的时候,因为对象类型的不同, 并不能进行相应的数据处理,所以必须要进行数据类型的转换,这也就是NSNumber,NSValue这两类值对象出现的原因. 简而言之,NSNumber就是实现 ...
- 第六百一十七天 how can I 坚持
没什么特长,唯一有的仅是妄想,哈哈,真逗. 明天就去新项目组了,会接触些新东西吧,啊,挺好,一开始压力大点很正常,但不要放弃啊. 搞不懂我自己啊,貌似不上火了呢. 睡觉了.忘不掉.做不到.
- VUE 入门基础(6)
六,条件渲染 v-if 添加一个条件块 <h1 v-if="ok">Yes</h1> 也可以用v-else 添加else 块 <template> ...
- paramiko与MySQL数据库
一.paramiko 1.利用paramiko连接远端服务器 import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_p ...
- openvpn配置教程
openvpn配置教程 本文是为解决本地服器能从外网访问web页,从新改写(临摹) 烂泥:ubuntu 14.04搭建OpenVPN服务器这篇文章 腾讯云为服务器,本地服务器为客户端 一.服务器安装o ...
- iOS常用第三方框架大全
常用第三方 今天就给大家总结一下,我们在项目中用到最多的第三方,免去了大家花时间去搜索,在这里大家进行了全面的总结. 1. 编程框架 1:基于响应式编程思想的oc 地址:https://github. ...