博文

我需要什么样的ORM(对象持久层)(2006-07-24 14:32:00)

摘要:首先声明,标题中是“我”,不是“我们”,别人希望如何我不太能够帮着下结论。

一个可以打动我的持久化层(Persistence Layer)或者说OR/M(Object Relateion Mapping)应该具备哪些特征呢?

1、简单,尽可能地简单
没必要为了我偶尔用到的功能花费太多的精力,CRUD满足之后,关于Relation如何处理的问题,我觉得尽可以不必那么讲究,一定要那么OO吗? 一定要 order.items这样去访问order的明细吗? 我觉得太可不必,为了实现这种功能,一是我必须再设计Entity类,以决定有哪些OnetoOne、OnetoMany, ManytoMany的关系,然后会定义一个类似这样的很OO的class出来:
class order
{
.....
customer _customer;
entitylist _items;
}

看上去真的很帅,但是我必须去维护它,因为不是所有的关系都需要这样定义,lazy loading并不能让人就可以放肆地定义一个很“胖”的类出来。

如果有人说我可以先class,再使用schema工具生成数据库,那么很不幸,我们没有共同语言了,起码我现在对这种方式不感兴趣,而且我也从来不这样做,像如何让union all构造出来的view利用到索引里所说的一样,我会因为数据库增加一些不相关的列,也会因为性能而再增设冗余,用class的方式去思考的话,我很难知道最终的数据库要做多少修改。如果仍然用“表”的方式去先构建“类”,那么我觉得这是一种掩耳盗铃的行为。顺便说一句,我暂时对domain object还不是很感兴趣。entity就是用来存储数据的,其它的事千万别让它去承担。

那么我希望如何处理relation呢? 非常简单:
entitylist items = pl.getList(order, typeof(orderline));

那么如何生成filter呢? 命名规则+代码生成,用order的主键id的值,以及用orderline的order_id列,构造select ... from orderline where order_id = order.id

2、......

阅读全文(5016) | 评论:2

Refactoring Patterns: 第二部分(2006-07-24 14:21:00)

摘要:为什么要去改变已经可以正确运行的软件?这样的改变是否影响到我们的设计,从而进一步改变我们对于面向对象系统进行设计的方法和思路?本部分试图回答这些问题。 Refactoring虽然需要更多的"额外工作",但是它给我们带来的各种好处显然值得我们做出这样的努力: 简化测试 一个好的Refactoring实现能够减少对新设计的测试量.因为Refactoring的每一步都保持可观察的行为,也就是保持系统的所有单元测试都能顺利通过。所以只有发生改变的代码需要测试.这种增量测试使得所有的后续测试都建立在坚实的基础之上,整个系统测试的复杂性大大降低。



回页首

更简单的设计 Refactoring降低初始设计的复杂程度.Gamma指出复杂设计模式的一个陷阱是过度狂热:"模式有其成本(间接性、复杂化),因此设计应该达到需求所要求的灵活性,而不是越灵活越好"。如果设计试图介入太多以后可能需要的灵活性,就会产生不必要的复杂和错误。Refactoring能够以多种方式扩展设计。他鼓励为手头的任务建立刚刚合适的解决方案,当新的需求来到时,可以通过Refactoring扩展设计。



回页首

Refactoring增进软件可理解性 程序的最终目的是为了指引计算机完成人们需要完成的事情。但是,要完成这个目标并非想象的那么容易。 程序编写是人的活动,人首先要理解才能行动。所以,源代码的另一个作用就是用于交流的工具。其他人可能会在几个月之后修改你的代码,如果连理解你的代码都做不到,他又如何完成所需的修改呢?我们通常会忘掉源代码的这种用处,尽管它可能是源代码更重要的用处。不然,我们为什么发展高级语言、面向对象语言,为什么我们不直接使用汇编语言甚至是机器语言来编写程序?难道我们真的在意计算机多花了几个CPU周期去完成一件事? 如果一个人能够理解我们的代码,他可能只需要一天的时间完成一个增加功能的任务,而如果他不理解我们的代码,可能需要花上一个礼拜或更长的时间。这里的问题是,我们在编写代码的时候不但需要考虑计算机CPU的想法,更要把以后的开发者放在心上。除非,你写代码的唯一目的就是把它丢掉。你不想让......

阅读全文(1644) | 评论:0

Refactoring Patterns: 第三部分(2006-07-24 14:20:00)

摘要:任何一种技术都可能有它自己的麻烦。但是往往在我们使用一种新技术的时候,可能还不能深入到发现它带来的问题,正如Martin Fowler所说:
在学习一种能够极大提高生产力的新技术时,你很难看到它不能应用的场合。 他把Refactoring的情景和面向对象出现使得情景相比较:
情况恰如10年前的对象。不是我不考虑对象有限制。只是因为我不知道那些限制是什么,虽然我知道他带来的好处。 但是Martin Fowler和其他人确实观察到了Refactoring可能引发的某些问题,我们可以来看一下: 数据库 很多应用程序的代码可能与数据库结构绑定得非常严密。如果要修改这些代码,需要改变还有数据库结构和原先已经存在的数据。 O/R mapping可以用来解决这个问题。使用专业的O/R mapping工具能够实现关系数据库的迁移。但是,就算这样,迁移也需要付出额外的代价。 如果你使用的并非关系数据库,而是直接采用OO数据库,这一点的影响可能会变得更小。 所以,我建议每一个使用数据库的应用程序都应该采用O/R mapping或者OO数据库。目前出现的各种企业级应用解决方案如J2EE本身就提供这样的构架。 如果你的代码没有这样一个隔离层,那么你必须手工或编写专用的代码来实现这些迁移功能。



回页首

接口改变和Published Interface 有很多Refactoring操作(如rename method name)确实改变了接口。面向对象承诺在接口不变的情况下给你以实现变化的自由。但如果接口发生改变,那么你就不得不非常小心了。 为了保证系统的可观察行为不变,你必须保证这些接口的改变不会影响到你无法取得的代码。如果你拥有了所有使用该接口的类的源代码,你只要把这些地方同时也改变即可。 但是,如果你没有办法得到所有这些使用的代码,那么你就不得不采取额外的途径。事实上,如果你的代码是一个代码库(如Sun JDK的集合框架)或者是一个Framework,那么这一点几乎是不可避免的。 要使得这些依赖于你老接口的代码能够继续工作,你必须保留老接口。现在你有两套接口,一套是老的,一套是经过Refactoring的新接口。你必须把对老接口的调用分派到新接口......

阅读全文(1616) | 评论:0

 Hibernate --什么是ORM(对像/关系映射)(2006-07-24 14:13:00)

摘要:也许你听说过Hibernate的大名,但可能一直不了解它,也许你一直渴望使用它进行开发,那么本文正是你所需要的!在本文中,我向大家重点介绍Hibernate的核心API调用库,并讲解一下它的基本配置。

  看完本文后,我相信你对什么是ORM(对像/关系映射)以及它的优点会有一个深刻的认识,我们先通过一个简单的例子开始来展现它的威力。

  正如一些传统的经典计算机文章大都会通过一个“hello,world”的例子开始讲解一样,我们也不例外,我们也将从一个相对简单的例子来阐述Hibernate的开发方法,但如果要真正阐述Hibernate的一些重要思想,仅仅靠在屏幕上打印一些字符是远远不够的,在我们的示例程序中,我们将创建一些对象,并将其保存在数据库中,然后对它们进行更新和查询。   “Hello World”

  Hibernate应用程序定义了一些持久类,并且定义了这些类与数据库表格的映射关系。在我们这个“Hello world”示例程序中包含了一个类和一个映射文件。让我们看看这个简单的持久类包含有一些什么?映射文件是怎样定义的?另外,我们该怎样用Hibernate来操作这个持久类。

  我们这个简单示例程序的目的是将一些持久类存储在数据库中,然后从数据库取出来,并将其信息正文显示给用户。其中Message正是一个简单的持久类:,它包含我们要显示的信息,其源代码如下:

  列表1 Message.Java 一个简单的持久类

package hello;
public class Message {
 private Long id;
 private String text;
 private Message nextMessage;
 private Message() {}
 public Message(String text) {
  this.text = text;
 }
 public Long getId() {
  return id;
 }
 private void setId(Long id) {
  this.id = id;
 }

阅读全文(5845) | 评论:1

什么是持久化和对象关系映射ORM技术(2006-07-24 13:45:00)

摘要:何谓“持久化”
持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。 何谓“持久层”
持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联。 何谓“对象数据映射(ORM)”
ORM-Object/Relational Mapper,即“对象-关系型数据映射组件”。对于O/R,即 Object(对象)和 Relational(关系型数据),表示必须同时使用面向对象和关系型数据进行开发。 备注:建模领域中的 ORM 为 Object/Role Modeling(对象角色建模)。另外这里是“O/R Mapper”而非“O/R Mapping”。相对来讲,O/R Mapping 描述的是一种设计思想或者实现机制,而 O/R Mapper指以O/R原理设计的持久化框架(Framework),包括 O/R机制还有 SQL自生成,事务处理,Cache管理等。
除了 ORM 技术,还有以下几种持久化技术 主动域对象模式
它是在实现中封装了关系数据模型和数据访问细节的一种形式。在 J2EE 架构中,EJB 组件分为会话 EJB 和实体 EJB。会话 EJB 通常实现业务逻辑,而实体 EJB 表示业务实体。实体 EJB 又分为两种:由 EJB 本身管理持久化,即 BMP(Bean-Managed Persistence);有 EJB 容器管理持久化,即 CMP(Container-Managed Persistence)。BM P就是主动域对象模式的一个例子,BMP 表示由实体 EJB 自身管理数据访问细节。
主动域对象本身位于业务逻辑层,因此采用主动域对象模式时,整个应用仍然是三层应用结构,并没有从业务逻辑层分离出独立的持久化层。 JDO 模式
Java Data Objects(JDO)是 SUN 公司制定的描述对象持久化语义的标准API。严格的说,JDO 并不是对象-关系映射接口,因为它支持把对象持久化到任意一种存储系统中,包括 关系数据库、面向对象的数据库、基于 XML 的数据库,以及其他专......

阅读全文(7126) | 评论:0

慎用const关键字(2006-07-24 13:39:00)

摘要: 我们在coding的时候,经常会做一个Config类,里面定义一些系统的公用变量。
      可能里面会出现这样的代码:  public const string PBD_Sys = @"……";      也有可能会有人写成这样的样子:
public static readonly string TempUnZipFilePath = "NewVersion";      那么,这两种方式究竟有哪些不同呢?一个是采用的const,一个采用static readonly。
      
      这个涉及到一点编译器的工作方式。比如说,上面的代码出现在类config中,config所在的project,我们命名为A。我们在projectB中调用projectA,这个时候,const和static readonly就会有一些小小的区别,有的时候,这个小小的区别,就会造成一个重大的bug
      代码如下(Project A中):
       public class Config
    {
        public const string PBDSys = "PDB";

        public static readonly string&nbs......

阅读全文(3057) | 评论:0

装箱,拆箱以及反射(2006-07-24 13:35:00)

摘要:    今天看到了一个很easy的帖子,如下:自定义一个类,然后定义一个与这个类结构一样的结构体,如何将这个类的实例的各种属性赋给与该类结构相同的结构体的对象.(不想用逐个属性赋值的方法)。
         一看之下,反射不是轻松搞定吗。后来自己做了个测试,发现对于值类型来说,好像有点小问题。代码如下: struct test1
    {
        private int i;
        public int I
        {
            get{return this.i;}
            set{this.i = value;}
        }
        private int j;
        float k;
    }

    class class2
    {
   &nb......

阅读全文(2991) | 评论:0

通过避免下列 10 个常见 ASP.NET 缺陷使网站平稳运行(转) (2006-07-21 10:33:00)

摘要:本文将讨论: • 缓存和 Forms 身份验证
 
• 视图状态和会话状态
 
• 配置文件属性序列化
 
• 线程池饱和
 
• 模拟和设置配置文件
  本文使用了下列技术: .NET Framework、ASP.NET、Windows Server 2003   本页内容
 LoadControl 和输出缓存
 会话和输出缓存
 Forms 身份验证票证生存期
 视图状态:无声的性能杀手
 SQL Server 会话状态:另一个性能杀手
 未缓存的角色
 配置文件属性序列化
 线程池饱和
 模拟和 ACL 授权
 不要完全信赖它 — 请设置数据库的配置文件!
 结论 ASP.NET 成功的其中一个原因在于它降低了 Web 开发人员的门槛。即便您不是计算机科学博士也可以编写 ASP.NET 代码。我在工作中遇到的许多 ASP.NET 开发人员都是自学成材的,他们在编写 C# 或 Visual Basic® 之前都在编写 Microsoft® Excel® 电子表格。现在,他们在编写 Web 应用程序,总的来说,他们所做的工作值得表扬。 但是与能力随之而来的还有责任,即使是经验丰富的 ASP.NET 开发人员也难免会出错。在多年的 ASP.NET 项目咨询工作中,我发现某些错误特别容易导致缺陷不断发生。其中某些错误会影响性能。其他错误会抑制可伸缩性。有些错误还会使开发团队耗费宝贵的时间来跟踪错误和意外的行为。 下面是会导致 ASP.NET 生产应用程序的发布过程中出现问题的 10 个缺陷以及可避免它们的方法。所有示例均来自我对真实的公司构建真实的 Web 应用程序的亲身体验,在某些情况下,我会通过介绍 ASP.NET 开发团队在开发过程中遇到的一些问题来提供相关的背景。 LoadControl 和输出缓存
极少有不使用用户控件的 ASP.NET......

阅读全文(1491) | 评论:0

自己收集整理琢磨的一些好的算法(2006-07-18 15:49:00)

摘要://byte[] sby = System.Text.Encoding.Unicode.GetBytes("宁绍");
        //string str = "";
        //for (int i = 0; i < sby.Length; i++)
        //{
        //    str += sby[i].ToString() + ",";
        //}
        //Label1.Text = str;
       // String a = "159343536267578990074874";
       //  String  a1="";
       //  char temp;
       //int b = a.Length;
       //char[] c = a.ToCharArray();
       //for(int i=0;i<b;i++)
       // for (int j=0;j<b-i-1 ; j++)
      ......

阅读全文(1862) | 评论:0

ASP.NET Web 服务器控件事件模型 (2006-06-07 14:41:00)

摘要:ASP.NET 中有一个重要功能,允许您通过与客户端应用程序中类似的、基于事件的模型来对网页进行编程。举一个简单的例子,例如,可以向 ASP.NET 网页中添加一个按钮,然后为该按钮的 Click 事件编写事件处理程序。尽管这种情况在仅使用客户端脚本(在动态 HTML 中处理按钮的 onclick 事件)的网页中很常见,但 ASP.NET 将此模型引入到了基于服务器的处理中。 与传统 HTML 页或基于客户端的 Web 应用程序中的事件相比,由 ASP.NET 服务器控件引发的事件的工作方式稍有不同。导致差异的主要原因在于事件本身与处理该事件的位置的分离。在基于客户端的应用程序中,在客户端引发和处理事件。但是,在 ASP.NET 网页中,与服务器控件关联的事件在客户端(浏览器)上引发,但由 ASP.NET 页在 Web 服务器上处理。 对于在客户端引发的事件,ASP.NET Web 控件事件模型要求在客户端捕获事件信息,并通过 HTTP POST 将事件消息传输到服务器。页必须解释该 POST 以确定所发生的事件,然后在要处理该事件的服务器上调用代码中的相应方法。有关更多信息,请参见 ASP.NET Web 服务器控件事件模型。 ASP.NET 处理捕获、传输和解释事件等任务。当您在 ASP.NET 网页中创建事件处理程序时,通常无需考虑捕获事件信息并使其可用于您的代码的方式。创建事件处理程序的方式与您在传统的客户端窗体上的创建方式大体相同。尽管如此,ASP.NET 网页中的事件处理仍有一些您应该注意的地方。 服务器控件和页的事件组 由于大多数 ASP.NET 服务器控件事件要求到服务器的往返行程才能进行处理,因此这些事件可能会影响页的性能。因此,服务器控件仅提供有限的一组事件,通常仅限于 Click 类型事件。一些服务器控件支持 Change 事件。例如,CheckBox Web 服务器控件在用户单击该框时引发服务器代码中的 CheckedChanged 事件。一些服务器控件支持更抽象的事件。例如,Calendar Web 服务器控件引发 SelectionChanged 事件,该事件是 Click 事件的更抽象版本。 对于服务器控件,不支持经常发生(并且是在用户不知道的情况下引发)的事件,如 onmouseover 事件。ASP.NET 服务器......

阅读全文(3079) | 评论:0