我一直想把EntityFramework(简称EF)的那一套搬过来,应用于HTML5 SQLite。 幸运的是,我几乎做到了,有些功能无法完成的那是因为SQLite本身不支持。至少从现在已经完成的功能来看,我们几乎可以像EF那样去操作数据库。

在我们这个框架中,所有对数据库的访问都封装在了命名空间"nova.data"下面。其下主要包括了以下类:

  • nova.data.DbContext
  • nova.data.Entity
  • nova.data.Repository
  • nova.data.Queryable

下面我将逐一详细阐述。

4.1 nova.data.DbContext

这个类相当于是数据库的定义。我们定义的数据库的类都应该继承自这个类。下面让我们先来看个例子吧。

这段代码定义了一个数据库,但实际上里面只有一张表,关于表的定义我会在下一节中详述。这里唯一的一张表就是"this.targets", 类型是"nova.data.Repository",相当于EF中的DbSet,实现的都是仓储模式。

请注意上面的第6行代码,nova.data.DbContext构造函数的第2个参数是版本号(字符串)。这个版本号的神奇之处在于,当它改变的时候,那么在初始化数据库的时候(通常在index.html),整个数据库就会重新创建。如果你希望数据库在重新创建的时候能够带一些初始数据,那么你可以覆写initData方法。

让我们把目光再次投向第10行代码。上面我说了,这一行代码是在这个数据库中定义了一张表。如果还想添加更多的表怎么办呢?对于聪明的你来讲一定不成问题。只需要在这个at.domain.AtDbContext下增加一些属性,并且这些属性的类型都是nova.data.Repository。值得一提的是,repository的第一个参数是一个构造函数,并且类型必须继承自nova.data.Entity。具体的关于repository个entity的定义,我会在后面的内容中详细阐述。这里你只需知道如何定义一个数据库,如何往数据库中添加/删除/更新表。

4.2 nova.data.Repository

这个类相当于EF中的DbSet,跟nova.data.DbContext一起实现了仓储模式。所谓仓储模式,就是说任何对repository的增加/删除/更新操作都只有在调用了DbContext.saveChanges之后才会生效。我们这个框架中提供的数据访问也是这样一种模式,如此你便可以同时提交多条数据更改了,而不是每一次更改都要调用一次数据库。

这个类相当于EF中的DbSet,主要用于定义表。其第一个参数是实体类的构造函数,实体类需继承自nova.data.Entity, 第2个参数是字符串,及数据库中表的名字。

这个类下面有很多方法,我就不一一赘述了。发个截图吧,相信从方法的定义大概看得出是做什么的:

这个类实际我一直想着改造下的,那就是让它继承自nova.data.Queryable. 不过现在这样用着也满足需求,也挺方便。

这个类有个已知的BUG,会在本章末尾阐述。

4.3 nova.data.Entity

我在设计这个类的时候,我也试着模仿EF中的CodeFirst模式的代码。就是说每一个字段的数据类型在定义这个实体类的代码中体现,幸运的是我几乎实现了这样的功能。只要你在定义实体类的时候,给每一个属性指定一个初始值,那么在创建数据库的时候,就会根据这个初始值来指定数据类型。目前支持的数据类型有:integer, decimal,string, date,boolean。如下面的代码:

在我们的框架下开发应用程序,所有的本地数据库实体类都应该继承nova.data.Entity。

这个类只有一个属性integer id,这也是SQLite数据库每一张表默认都会带的字段。因此,在你的数据库实体类的定义中,不应该再定义id这个字段了。除了这个id属性,这个基类还定义了一些方法,主要是用于处理数据类型的。

这个类的另一个强大之处在于,以Target实体类为例,当你同时往数据库插入了多条target记录,并调用了dbContext.saveChanges方法时,每一个target的id会得到更新。这个特性也是模仿EF的,因为我们在使用EF的过程中发现这个特性实在太有用了。相信你在使用我们框架的过程中也会喜欢这个特性的。

4.4 nova.data.Queryable

这个类是模仿Linq中的IQueryable的,其工作原理也是和IQueryable类似。请看下面这行代码:

db.targets.where(“price >= 10”).where(“price < 20”).orderBy(“category”).thenBy(“name”).toArray(callback).

如果你熟悉Linq,那么这行代码你一定不会陌生。是的,我们的框架就实现了这样的功能。上面这行代码,在调用toArray之前,每一个查询/排序条件都没有提交到数据库,而是放在了内存当中,只有当调用了toArray时,才会执行数据库的查询。

请注意上面这行代码的第一个where,这个where方法实际上是repository中定义的,但返回的却是queryable,而后面的where和orderBy等都是queryable的实例方法。这正是模仿Linq设计的巧妙之处。

这个类的其他方法都比较一目了然了,就贴个截图吧:

4.5 常用例子

前面我把我们框架中对于本地数据库访问的每一个成员都做了详细的介绍,但如果你对JS面相对象或者EF不那么熟悉的话,可能还是看得有些云里雾里。好吧,下面我就贴一些常用的例子,相信这些例子一定能让你领略到这个框架的独特魅力。

4.5.1 定义数据库

先上代码:

这段代码只定义了一个targets表,你当然可以增加更多的表,只需要把第3行代码复制几份,然后改改名字就可以了。

4.5.2 定义实体类

先上代码:

这里定义了一个Target类,还有很多个实例方法,看上去跟普通的类没有什么区别,唯一的区别就是继承自nova.data.Entity.

4.5.3 查询

4.5.4 插入

4.5.5 更新

4.5.6 删除

4.6 已知问题

目前有1个问题无法解决。

当同时执行批量插入、批量更新、批量删除的时候会报错。因此,如果你想同时执行这些批量操作的话,那么应该让一种批量操作完成之后再执行另一个批量操作。

Nova PhoneGap框架 第四章 本地数据库的更多相关文章

  1. Nova PhoneGap框架 第五章 文件结构

    一个好的项目架构必然有着合理的文件结构,如果一个项目的文件组织混乱,那么可以断言一定是项目架构有问题. 合理的文件结构能够帮你更清晰的管理你的文件,并且当需要添加新的文件的时候,你的程序员很清楚应该加 ...

  2. Nova PhoneGap框架 第七章 设备事件处理

    我们的框架包含了几种设备事件的处理,目的是为了让我们的程序员更容易的完成代码.这些事件包括:回退键(Android)和横竖屏切换事件. 7.1 Android回退键 首先来说说回退键的事件处理.当用户 ...

  3. Nova PhoneGap框架 第三章 页面

    页面在项目架构中是一个很重要的概念,它让我们能够将一个功能复杂的项目拆分成一个一个功能比较独立的小区域,这极大的提高了代码的可读性和可维护性. 在我们这个框架中,一个页面由JS和HTML两部分组成,首 ...

  4. Nova PhoneGap框架 第六章 使用Mock

    在我们的框架中引入了一个很重要的设计,那就是使用Mock. 这里的mock是指cordova.mock.js文件,它模拟了PhoneGap(Cordova)的API,从而可以在浏览器中运行测试我们的程 ...

  5. Nova PhoneGap框架 第一章 前言

    Nova PhoneGap Framework诞生于2012年11月,从第一个版本的发布到现在,这个框架经历了多个项目的考验.一直以来我们也持续更新这个框架,使其不断完善.到现在,这个框架已比较稳定了 ...

  6. Nova PhoneGap框架 第二章 理解index.html

    跟绝大多数PhoneGap程序一样,Index.html是程序的入口.这个页面应该完成应用程序的初始化工作. 首先,让我们来看看这个页面通常都长什么样子: 下面我将一一解释这个页面都做了哪些初始化工作 ...

  7. Nova PhoneGap框架 总结

    Nova PhoneGap Framework 是完全针对PhoneGap应用程序量身定做的,在这个框架下开发的应用程序很容易实现高质量的代码,很容易让程序拥有很好的性能和用户体验. 在经历了多个项目 ...

  8. Nova PhoneGap框架 第八章 滚动条

    你可能会疑惑为什么滚动条这么常见的功能会在这里单独列出,但如果你有过PhoneGap开发经验的话,你就会发现要在Android 2.3 里面实现滚动条那真不是一件容易的事. 8.1 概述 目前主流的P ...

  9. Nova PhoneGap框架 第九章 控件

    我们的框架中也提供了一些常用的控件,这些控件大多都依赖于我们的框架,也正是在我们的框架下才使得实现这些控件的变得更简单.但是我们的框架是不依赖与这些控件的,如果你用不上这些控件,你完全可以把相关的代码 ...

随机推荐

  1. Win7 U盘安装Ubuntu16.04 双系统详细教程

    Win7 U盘安装Ubuntu16.04 双系统详细教程 安装主要分为以下几步: 一. 下载Ubuntu 16.04镜像软件: 二. 制作U盘启动盘使用ultraISO: 三. 安装Ubuntu系统: ...

  2. 从ord()中对Unicode编码的理解

    刚开始学习编程的时候,老对字符串编码的理解模模糊糊.也一直看这方便的资料,今天在看Dive in python时,突然有了新的理解(不知道是否正确). Python有个built-in函数ord(), ...

  3. 转:IT公司的十大内耗,别说你公司没有!

    这篇文章是以前看到的,觉得写得非常好,转载在自己BLOG作为记录.原文:http://www.pmtoo.com/news/2015/0108/7260.html. 当企业发展到一定时期时,会不可避免 ...

  4. oracle普通表转分区表(在线重定义方式)

    1.1.TAB_TAOBAO_BILL 1.1.1检查下这张表是否可以在线重定义,无报错表示可以,报错会给出错误信息: exec dbms_redefinition.can_redef_table(' ...

  5. jq size()与length的区别

    size()跟length同样的功能,都是取元素的个数,那么他们的区别是什么呢,一个是方法一个是属性? 从图中可以看到size()方法比length慢38%,原因何在? size: function ...

  6. linux中redis安装

    一.登录redis官网下载redis-3.0.7.tar.gz 二.通过ftp工具上传至自己的服务器中 三.tar -zxvf redis-3.0.7.tar.gz解压 四.cd redis-3.0. ...

  7. TMS320F28027/26/23/22/21/20芯片解密单片机破解原理!

    TMS320F28027/26/23/22/21/20芯片解密单片机破解 TMS320F2802系列芯片解密型号: TMS320F28027F.TMS320F280270.TMS320F28027.T ...

  8. Http、Https请求工具类

    最近在做微信开发,使用http调用第三方服务API,有些是需要https协议,通过资料和自己编码,写了个支持http和https的工具类,经验证可用,现贴出来保留,也供需要的人使用(有不足的地方,也请 ...

  9. 1208PHP基础

    PHP是一种创建动态交互性站点的强有力的服务器端脚本语言(后端.弱类型) 从地址栏直接寻找:localhost/路径/路径PHP语法:PHP脚本以<?php 开始,以?>结束; PHP文件 ...

  10. 图解修改mysql的默认数据库存放目录

    按照下图三步完成: