[置顶]经典文章翻译: 弥合对象/关系之间的鸿沟(八)

该文被密码保护。
posted @ 2012-04-11 21:05 Kevin_ 阅读(17) 评论(0) 编辑

[置顶]经典文章翻译:弥合对象/关系之间的鸿沟(七)

该文被密码保护。
posted @ 2012-04-11 21:04 Kevin_ 阅读(11) 评论(0) 编辑

[置顶]经典文章翻译: 弥合对象/关系之间的鸿沟(五)

摘要: 在一个规范化后的关系模式中,如果有一个表的许多行关联另一个表的许多行的关系,通常由连接表表示...阅读全文
posted @ 2012-04-11 21:02 Kevin_ 阅读(68) 评论(0) 编辑

[置顶]经典文章翻译: 弥合对象/关系之间的鸿沟(四)

摘要: 弥合对象/关系之间的鸿沟(四)映射(一)继承。在领域对象模型中,继承是两个类之间的关系,其中一个类是另一个类的泛化。图1显示了人类的关系对象模型,这其中全职员工(FullTimeEmployee)和兼职员工(PartTimeEmployee)是员工(Employee)的泛化,员工(Employee)又是一个人(Person)的泛化。 有数种方式将这个领域对象模型映射到关系模式。其中单表继承策略将继承层次结构中所有类映射到一个表,此表中包含的列对应任何类的所有字段。在这种映射中,若表中的单元格包含空值或默认值,则表示该行对应的那个类的实例中不包含该列的字段。为了使用单表策略,数据库必须包含的信息阅读全文
posted @ 2012-04-09 18:36 Kevin_ 阅读(623) 评论(2) 编辑

[置顶]翻译: 弥合对象/关系之间的鸿沟(九)

该文被密码保护。
posted @ 2012-04-08 21:23 Kevin_ 阅读(32) 评论(0) 编辑

[置顶]经典文章翻译: 弥合对象/关系之间的鸿沟(三)

摘要: 弥合对象/关系之间的鸿沟(三)阻抗不匹配? 所谓的对象和数据库模式(schema)之间的阻抗不匹配产生了很多讨论,这当然有很好的理由。根据斯科特·安布勒3所说的,这两种技术之间具有“欺骗性的相似之处”。对这两种技术之间的差异缺乏了解可能会导致选择糟糕的设计并导致项目失败。 在对象语言中(如Java)数据模型并不是完全与关系型数据库中的相同,所以必须特别小心防止出现问题。例如,字符列的最大长度必须在关系模式中指定,然而Java字符串的最大长度基本上是无限的。 浮点数也可能会导致问题。Java实现了IEEE浮点数;但不同的关系型数据库往往有不同的表示。结果导致,并非所有Java中的浮点数阅读全文
posted @ 2012-04-08 20:51 Kevin_ 阅读(993) 评论(0) 编辑

[置顶]经典文章翻译: 弥合对象/关系之间的鸿沟(二)

摘要: 弥合对象/关系之间的鸿沟(二)O/RM的架构 从应用程序的视角看,O/RM有两个主要部分:持久性API和领域类。在Java中,API通常是Java社区流程的标准之一 ---Java持久性API,企业JavaBeans或Java数据对象——或尚未成为标准的流行API,例如TopLink或Hibernate。 使用标准的持久性API的一个优点是它允许项目作出晚部署项目数据库和持久性提供程序的决定。在项目开始时往往持久性提供程序所需要的功能并不明显,因此在许多项目中,允许作出晚部署的决定可以是一个选择使用它的重要的因素。 持久性API允许应用程序的程序员对数据库执行所有标准的CRUD(创建,...阅读全文
posted @ 2012-04-08 18:35 Kevin_ 阅读(101) 评论(0) 编辑

[置顶]经典文章翻译: 弥合对象/关系之间的鸿沟(一)

摘要: 中文翻译:弥合对象/关系之间的鸿沟O/RM技术可以简化数据访问,但也需要注意到引入这个新的抽象层来的挑战。克雷格·罗素发表于:Queue杂志 ——对象-关系映射第6卷 第3期, 五月/六月 2008 现代的应用程序使用两种截然不同的技术构建而成:面向对象编程用于业务逻辑部分; 关系型数据库用于数据存储。面向对象编程是实现复杂的系统的一个关键技术,它提供的好处包括可重用性,健壮性和可维护性。关系型数据库是保存数据的仓库。O/RM(对象关系映射)是两者之间的桥梁,它允许应用程序以面向对象的方式访问关系数据。 O/RM是对象持久化的一个专业化的一般概念。IBM研究员格雷迪·布赫在阅读全文
posted @ 2012-04-08 10:52 Kevin_ 阅读(987) 评论(0) 编辑

javascript 调用 IndexedDb示例

一个简单的Todolist

html

todo.html

<!DOCTYPE html>
<html>
  <head>
      <title>candyDatabase sample</title>
    <script type="text/javascript" src="todo.js"></script>

    </head>
  <body>
    <ul id="todolist"></ul>
    <input type="text" id="tbx_todo" name="todo" placeholder="pls enter a todo-item here" />
    <input type="submit" value="添加待办项" onclick="addTodo(); return false;"/>
  </body>
</html>

 

javascript代码

todo.js
/**
 * @author Scott
 *
 */
var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;

if ('webkitIndexedDB' in window) {
    window.IDBTransaction = window.webkitIDBTransaction;
    window.IDBKeyRange = window.webkitIDBKeyRange;
}

candyDb = {};
candyDb.db = null;

candyDb.onerror = function(e) {
    console.log(e);
};

candyDb.open = function() {
    var request = indexedDB.open("candyDb", '202');

    request.onsuccess = function(e) {
        candyDb.db = this.result;
        candyDb.getAllTodoItems();
    };

    request.onupgradeneeded = function(evt) {
        candyDb.db = this.result;
        if (candyDb.db.objectStoreNames.contains("todo")) {
            candyDb.db.deleteObjectStore("todo");
        }
        var store = candyDb.db.createObjectStore("todo", {
            keyPath : "id"
        });
        console.log("upgraded...")
    };

    request.onerror = candyDb.onerror;
}

candyDb.addTodo = function(todoText) {
    var db = candyDb.db;
    var trans = db.transaction(["todo"], "readwrite");
    var store = trans.objectStore("todo");

    var data = {
        "text" : todoText,
        "priority" : 0,
        "id" : new Date().getTime()
    };

    var request = store.put(data);

    request.onsuccess = function(e) {
        candyDb.getAllTodoItems();
    };

    request.onerror = function(e) {
        console.log("Error Adding: ", e);
    };
};

candyDb.deleteTodo = function(id) {
    var db = candyDb.db;
    var trans = db.transaction(["todo"], "readwrite");
    var store = trans.objectStore("todo");

    var request = store.delete(id);

    request.onsuccess = function(e) {
        candyDb.getAllTodoItems();
    };

    request.onerror = function(e) {
        console.log("Error Adding: ", e);
    };
};

candyDb.getAllTodoItems = function() {
    var todos = document.getElementById("todoItems");
    todos.innerHTML = "";

    var db = candyDb.db;
    var trans = db.transaction(["todo"], "readwrite");
    var store = trans.objectStore("todo");

    var keyRange = IDBKeyRange.lowerBound(0);
    var cursorRequest = store.openCursor(keyRange);

    cursorRequest.onsuccess = function(e) {
        var result = e.target.result;
        if (!!result == false)
            return;

        renderTodo(result.value);
        result.continue();
    };

    cursorRequest.onerror = candyDb.onerror;
};

function renderTodo(row) {
    var todos = document.getElementById("todolist");
    var li = document.createElement("li");
    var a_del = document.createElement("a");
    var txt = document.createTextNode(row.text);

    a_del.addEventListener("click", function() {
        candyDb.deleteTodo(row.id);
    }, false);

    a_del.textContent = " [delete]";
    li.appendChild(txt);
    li.appendChild(a_del);
    todos.appendChild(li)
}

function addTodo() {
    var todo = document.getElementById("tbx_todo");
    candyDb.addTodo(todo.value);
    todo.value = "";
}

function init() {
    candyDb.open();
}

window.addEventListener("DOMContentLoaded", init, false);

 

 

 

 

 

 

 

posted @ 2013-05-19 22:44 Kevin_ 阅读(10) 评论(0) 编辑

如何查看MS-Acccess中主键的名字

 

原文链接: 如何查看acccess中主键的名字

 

创建access主键的时候有两种方式,一种是在access中手动创建的,另一种是在用代码创建的(不管是在access中执行的还是在外部程序)。

方式不同主键名称也不同,第一种创建方式的主键名字都是primarykey,注意中间没有空格;第二种主键的名字需要借助VBA代码才能查出来:

Public   Sub   fnGetPrimaryKeyName() 
        
        Dim   v_DB   As   New   ADOX.Catalog 
        Dim   v_Table   As   ADOX.Table 
        Dim   v_Key   As   ADOX.Key 
        
        Dim   objTable   As   New   ADOX.Table 
        
        Dim   strKey   As   String 
        Dim   strKeyName   As   String

        
        v_DB.ActiveConnection   =   CurrentProject.Connection 
        
        objTable.ParentCatalog   =   v_DB 
        
        Set   objTable   =   v_DB.Tables( "你的表名 ") 
        
        For   Each   v_Key   In   objTable.Keys 
                Select   Case   v_Key.Type 
                        Case   adKeyPrimary 
                                strKey   =   "Primary   KEY   " 
                                strKeyName   =   v_Key.Name 
                                
                End   Select 
        Next 
        
        Debug.Print   "主键约束名: "   &   strKeyName

End   Sub

 

上述代码需要引用ADOX。

1--> 打开VBA代码窗口 
2--> 工具菜单,引用菜单项 
3--> 选择“Microsoft   ADO   Ext.   2.X   for   DLL   and   Security”

 

有一点要注意的是,同一个数据库文件放到不同的地方用代码创建的主键的名字是不同的,这一点要记住。

posted @ 2012-06-29 18:20 Kevin_ 阅读(31) 评论(0) 编辑

[翻译] 编写全面的单元测试

编写全面的单元测试

乔纳森·艾伦 发表于2012 5 24
 
              版块:开发
 
主题:.net, 单元测试,编程,测试驱动开发,测试
 
     在那些声称熟悉单元测试“最佳实践”的人们中有一种常见的观点:在一个测试中你应该只写1个断言,最多2个。那些宣称这个理论的人几乎很少展示他们的单元测试并且那些单元测试确实只有一个断言。显然,如果你采纳了他们的建议,一个不重要的小方法也会需要一打儿的断言来保证质量。本文意在通过实例证明每个测试多个断言不仅是必须的而且是有益的。
 
让我们来考虑下一个非常典型的在数据绑定场景中很常见的Person对象:

测试FirstName 属性

 
我们想要测试的第一件事是设置对象的FirstName属性,一开始:
 
[TestMethod]
public void Person_FirstName_Set()
{
      varperson = new Person("Adam", "Smith");
      person.FirstName = "Bob";
      Assert.AreEqual("Bob", person.FirstName);
}
 
然后我们想测试FirstName 属性的更改通知。
 
[TestMethod]
public void Person_FirstName_Set_PropertyChanged()
{
      var person = new Person("Adam", "Smith");
      var eventAssert = new Granite.Testing.PropertyChangedEventAssert(person);
      person.FirstName = "Bob";
      eventAssert.Expect("FirstName");
}

当我们运行这个测试方法时,我们将受到一条失败信息“期望属性名是‘FirstName’,但是却收到了‘IsChanged’”。显然,设置‘FirstName’属性改变了‘IsChanged’标志属性,所以我们需要考虑到这点,因此我们添加一些代码混合到这段代码中:

[TestMethod] public void Person_FirstName_Set_PropertyChanged() { var person = new Person("Adam", "Smith"); var eventAssert = new Granite.Testing.PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.SkipEvent(); //this was IsChanged//这里是IsChanged eventAssert.Expect("FirstName"); }
 
以上两个测试通过后,我们开始考虑当‘FirstName’改变后其他还有哪里需要改变。仔细检查API,两个属性‘IsChanged’和‘FullName’是需要改变的。

[TestMethod] public void Person_FullName_Changed_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); person.FirstName = "Bob"; Assert.AreEqual("Bob Smith", person.FullName); } [TestMethod] public void Person_IsChanged_Changed_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); person.FirstName = "Bob"; Assert.IsTrue(person.IsChanged); }
 
并且当这些属性被改变时,我们也理所应当能捕获到他们的属性更改通知:
 

[TestMethod] public void Person_IsChanged_Property_Change_Notification_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.Expect("IsChanged"); } [TestMethod] public void Person_FullName_Property_Change_Notification_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.SkipEvent(); //this was IsChanged eventAssert.SkipEvent(); //this was FirstName eventAssert.Expect("FullName"); }
 
我们下面的两个测试将检测‘HasError’属性和‘ErrorsChanged’事件。
 

[TestMethod] public void Person_FirstName_Set_HasErrorsIsFalse() { var person = new Person("Adam", "Smith"); person.FirstName = "Bob"; Assert.IsFalse(person.HasErrors); } [TestMethod] public void Person_FirstName_Set_ErrorsChanged_Did_Not_Fire() { var person = new Person("Adam", "Smith"); var errorsChangedAssert = new ErrorsChangedEventAssert(person); person.FirstName = "Bob"; errorsChangedAssert.ExpectNothing(); }
 
到目前为止我们已经有了8个测试方法,这意味着我们已对所有‘FirstName’属性改变后应该改变的地方担负起了责任。但这并不意味着我们现在已经全部搞定了。我们也需要确保其他任何东西没有被意外的改变。
posted @ 2012-06-06 00:05 Kevin_ 阅读(998) 评论(8) 编辑

Bring Transactions to the Common Type

摘要: Volatile Resource Managers in .NET Bring Transactions to the Common TypeJuval LowyThis article discusses:Overview of transactional processingTransactions in the .NET FrameworkVolatile Resource ManagersTransactional classes and collectionsThis article uses the following technologies:.NET Framework 2.阅读全文
posted @ 2012-05-30 11:54 Kevin_ 阅读(39) 评论(0) 编辑

经典文章翻译: 弥合对象/关系之间的鸿沟(八)

该文被密码保护。
posted @ 2012-04-11 21:05 Kevin_ 阅读(17) 评论(0) 编辑

经典文章翻译:弥合对象/关系之间的鸿沟(七)

该文被密码保护。
posted @ 2012-04-11 21:04 Kevin_ 阅读(11) 评论(0) 编辑

经典文章翻译: 弥合对象/关系之间的鸿沟(六)

 

弥合对象/关系之间的鸿沟(六)

持久性API

  O/RM  API提供的接口代表运行时环境。API的主要接口封装了到数据库的连接查询生成器已经被应用程序引用的领域实例的缓存。在这篇文章中,这个界面被称为会话(Session)。(在不同的API中,这个接口被称为实体管理程序持久性管理程序,但不管什么名字,都有异曲同工之妙) 

  在一个多用户环境中,使用多个会话实例让用户相互隔离。每个会话都有其自己的数据库连接和它自己的领域实例缓存。会话高速缓存实现了唯一性保持(uniquing)。如果一个API支持多个线程运行于同一会话中,所有这些线程在会话管理下共享领域对象的改变。

  应用程序从一个会话工厂(SessionFactory)获得一个会话,它封装了数据源(连接工厂)和O/RM模型。在会话工厂(SessionFactory)中通常也包括连接池和二级或全局领域对象缓存,它处理与容器的交互。会话工厂(SessionFactory)是引导程序实例,它通常是从系统服务查找,例如JNDI(Java名称和目录接口)或通过XML或属性配置。

  数据库事务由事务类(Transaction)表示,应用程序从会话实例获取一个事务实例。一个会话只有一个活动的事务实例(一个会话可以顺序开始并完成多个事务),不同的接口使得关注点得以分离,那么也就是,访问领域实例的应用程序组件和开始和完成事务的应用程序组件是分开的。 

  数据库查询由查询类(Query)表示,该类的实例由应用程序从会话获得。一个查询实例封装了一个特定的查询,并实现了一个执行的方法,它允许应用程序根据参数从不同的数据库获取不同的数据集。

  在一个单元操作正在进行时,应用程序可能对多个领域实例做出很多改变,并在单元操作结束时,由持久性提供程序根据领域实例的更改将变化应用到数据库。

  由于数据库模式(schema)中存在外键约束,在领域模型中的改变对应的数据库操作顺序是很重要的。例如,必须先插入一行数据到数据库中,之后另一个新行才能被插入或更改现有的行使其指向新行。同样,若现有行中有一列指向的是一个要被删除的行,必须在该行被删除之前将此列值设置为空。

  O/RM的自动确定数据库中的操作顺序的技术,是基于数据库约束实现的,这是O/RM技术相较于其他技术在可用性方面的一个重要特性,因为程序员必须以正确的顺序执行操作。 

 

  查询。O/RM带来的主要好处之一是,查询由领域对象模型的方式表示而不是用关系模式的方式。如果领域模型或查询很复杂,这将会很重要。

在设计O/RM的查询语言的挑战之一是使其足够丰富,足以让大多数应用程序查询,但要作出限制,不允许所有对象领域的查询直接映射到SQL。 

  例如,若要找到Employee类中周薪大于某个参数的所有实例,对应的SQL查询是:

SELECT * FROM EMPLOYEE WHERE WEEKLY_SALARY>?
 
相应的使用领域对象模型的查询将是:
 
SELECT FROM FullTimeEmployee 
WHERE weeklySalary > :salary
 
提供程序从领域模型和映射生成SQL。“:”是一个参数标记,它允许应用程序通过名称绑定查询的参数。
 
在SQL查询中所涉及的所有表都在FROM子句中声明且连接条件都在WHERE子句中显式包含。若要在Employee类的实例中找到一些周薪大于一个参数且在某单位工作的,此SQL会比较复杂:
 
SELECT E.* FROM EMPLOYEE E, DEPARTMENT D 
WHERE E.WEEKLY_SALARY > ? AND D.NAME = ? 
AND E.DEPARTMENT = D.ID
 
相应的使用领域对象模型的查询将是:
 
SELECT FROM FullTimeEmployee 
WHERE weeklySalary > :salary && dept.name = :dept


下一篇 查询中的关系导航
posted @ 2012-04-11 21:03 Kevin_ 阅读(319) 评论(0) 编辑

经典文章翻译: 弥合对象/关系之间的鸿沟(五)

摘要: 在一个规范化后的关系模式中,如果有一个表的许多行关联另一个表的许多行的关系,通常由连接表表示...阅读全文
posted @ 2012-04-11 21:02 Kevin_ 阅读(68) 评论(0) 编辑

经典文章翻译: 弥合对象/关系之间的鸿沟(四)

摘要: 弥合对象/关系之间的鸿沟(四)映射(一)继承。在领域对象模型中,继承是两个类之间的关系,其中一个类是另一个类的泛化。图1显示了人类的关系对象模型,这其中全职员工(FullTimeEmployee)和兼职员工(PartTimeEmployee)是员工(Employee)的泛化,员工(Employee)又是一个人(Person)的泛化。 有数种方式将这个领域对象模型映射到关系模式。其中单表继承策略将继承层次结构中所有类映射到一个表,此表中包含的列对应任何类的所有字段。在这种映射中,若表中的单元格包含空值或默认值,则表示该行对应的那个类的实例中不包含该列的字段。为了使用单表策略,数据库必须包含的信息阅读全文
posted @ 2012-04-09 18:36 Kevin_ 阅读(623) 评论(2) 编辑

翻译: 弥合对象/关系之间的鸿沟(九)

该文被密码保护。
posted @ 2012-04-08 21:23 Kevin_ 阅读(32) 评论(0) 编辑
仅列出标题  下一页

公告

统计