SPL讲解(3)--实体操作篇

  • 格式:doc
  • 大小:59.50 KB
  • 文档页数:6

SmartPersistenceLayer 2.0之实体操作篇通过上一篇的”设置篇”后,在我们的系统中就可以开始使用SPL的强大功能了,这一节我主要是介绍SPL的实体(Entity)操作。

原理SPL中的实体可能与其他PL的实体有所区别,一般如果从理论上讲的话,实体仅仅是数据的属性描述,不应该带有操作方法,这种方式也存在一种缺点,就是实体没有了操作,只能借助”辅助类”进行实体的操作,而这种操作势必不能是强类型的,而且开发员可能无法彻底站在面向对象的角度开发系统,因此,SPL中采用了实体中集成部分常用操作,即Insert,Update,Delete,Retrieve操作,这样当我们要对实体进行操作时,可以直接调用实体的这些方法,实现强类型的操作控制。

为了让SPL能自动实现这种功能,实体(Entity)要继承SPL中的EntityObject抽象类,如:Public class StudentEntity : EntityObject这样,这个实体就自动具有了Save(),Retreve(),Delete()的功能。

实体操作实体的常用操作为新增(Insert)、更新(Update)、删除(Delete) 、获取(Retrieve),在SPL 中体现为Save(),Delete(),Retrieve()这三个方法,Save()会自动判断实体是否已经持久化(IsPersistence)来进行Insert和Update区分。

下面我还是以上一篇”基础设置篇”中的例子来演示:实体的XML定义如下:<class name="StudentEntity"table="Student"database="MyDB"><attribute name="Id"column="Id"type="Integer" increment="true"key="primary"/><attribute name="No"column="No"type="String"key="primary"/><attribute name="Name"column= StudentEntity "Name"type="String"/><attribute name="Birthday"column="Birthday"type="Date"/><attribute name="Grade"column="Grade"type="Integer"/><attribute name="Score"column="Score"type="Decimal"/></class>实体类如下:内容略,请参照”基础设置篇”namespace BusinessEntity{using System;using System.Collections;using System.Data;using PersistenceLayer;public class StudentEntity : EntityObject{//常量定义部分…//局部变量定义部分…//属性定义部分…}}实体新增:以往的编程模式中,要往数据库的某表中插入一条记录,有人采用SQL语句执行,这要注意SQL语句的正确性,单引号问题(要使用string.replace(“’”,”’’”)进行替换);还有可以采用Command的Parameter的方式,这样就可以避免单引号问题;还有人为了提高性能会采用存储过程,那么这些过程都会影响开发的速度,在SPL中我们的过程变的相当简单了:StudentEntity student=new StudentEntity(); //实体化一个学生对象//以下进行属性赋值//student.Id=1; //此为自动增长,SPL会自动获取student.No=”200401”;=”张三”;student.Birthday=DateTime.Parse(“1979-01-22”);student.Grade=2;student.Score=580;try{ student.Save(); //实体保存}catch(PlException exp) //抛出异常{if(exp.ErrorType==ErrorTypes.NotUnique) //如果是主键冲突{Response.Write(“主键冲突”);}elsethrow exp;}步骤分析:1.直接New一个实体对象,给对象属性赋值2.然后Save(),如果发生主键冲突,则可以通过catch PersistenLayer.PlException异常来处理,判断是否为PersistenceLayer.ErrorTypes.NotUnique,这样就可以完成新增记录。

自动增长:如上面的Id是自动增长列,所以在赋值时不需要赋值,在进行Save()后,自动生成的主键值会自动赋给实体Student的Id属性,这样马上可以使用此生成值。

实体获取:数据插入后,我们会进行更新,删除等操作,当然,在进行这些操作前,我们肯定会很找到这条记录,那先介绍获取Retrieve()。

在我的设计理念中,每个表都会设置一个主键,这会方便查询,SPL中也实出主键功能,实体的Retrieve()就是根据实体的主键,去获取唯一的一条记录,结果要么是一条,要是就是没有。

举例我们要获取学生ID=5的记录:StudentEntity student=new StudentEntity(); //实例化student.Id=5; //给主键赋值student.Retrieve(); //进行Retrieve()操作if(student.IsPersistence) //如果获取到{//给界面上的控件进行赋值txtName.Text=;……}步骤分析:1.给主键赋值,例子中是单主键,当然我是一直提供单主键的,不过,SPL也是支持多主键的,只要在XML文件中定义为primary=true的例,那么在进行Retrieve()之前就要进行先赋值。

2.进行Retrieve()操作,这个操作就是从XML文件中读取为主键的字段值,然后从数据库中读取,如果存在,则把值都赋给实体属性;如果不存在,则不进行操作3.对实体进行IsPersistence判断,如果获取到,此值为true,如果未获取到为false,因此可以根据此值进行不同的处理。

因此在获取后要使用值时,一定要进行IsPersistence的判断,这是比较好的编程习惯哦。

实体更新:当我们获取实体后并赋值给界面上的控件后,在客户进行修改后就要进行更新操作。

StudentEntity student=new StudentEntity(); //实例化student.Id=5; //赋主键值student.Retrieve(); //获取实体if(student.IsPersistence) //如果存在{=txtName.Text; //获取新值…….try{student.Save() //进行更新}cartch(PlException exp) //捕捉异常{if(exp.ErrorType==ErrorTypes.RestrictError) //如果是级联更新异常{Response.Write(“有级联更新约束错误”);Response.End(); //友好提示}else{throw exp;}}}步骤分析:1.先根据主键值获取实体,我是非常建议这样做的,因为系统是多人进行操作的,在每次更新前先从数据库获取一下,这样可以避免实体被删除的并发性错误,当然如果要彻底避免这种并发性,我们可以设定时间戳字段,在获取后进行时间戳比较即可,关于时间戳在SPL中的实现我将在以后的文章中讲述。

2.使用Save()方法进行更新,这与新增时使用同一个方法,这是因为Save()的方法会根据实体的IsPersistence值进行不同的操作:如直接New一个实体,进行Save(),默认是新增的,而通过Retrieve()后,此值为true的情况下,会自动以Update操作。

这种机制非常好用,因为有时候,我们可以让SPL自己决定操作。

我们也可以在更新前不进行Retrieve(),而直接把IsPersistence值赋为true,也可以进行更新操作。

3.级联异常处理,在进行更新时我们经常会遇到级联约束异常,你可以捕捉到ErrorTypes.RestrictError进行友好信息提示。

实体删除:删除操作跟前面的类似,也是非常简单的。

StudentEntity student=new StudentEntity();student.Id=5;student.Retrieve();if(student.IsPersistence){try{student.Delete();}catch(PlException exp){if(exp.ErrorType==ErrorTypes.RestrictError) //如果是级联删除异常{Response.Write(“有级联删除约束错误”);Response.End(); //友好提示}else{throw exp;}}}步骤分析:1.跟实体更新一样,先要通过主键,获取实体,在进行IsPersistence的判断后再进行删除,这可以删除并发性错误。

2.在删除时我们可以捕捉级联删除错误异常,进行友好信息的提示。

扩展功能动态赋值有时候我们会遇到这种情况:实体的字段比较多,有些字段的名称是可以循环的定义的,如12个的金额,可以定义为“Price1,Price2…”,象这种为了在赋值与取值时减少输入量,我们通常会采用动态组装属性名,SPL提供了SetAttributeValue(“属性名”,”属性值”)方法来支持这种赋值方式,如:StudentEntity student=new StudentEntity();for(int i=1;i<=12;i++){student. SetAttributeValue(“Price”+i.ToString(),i.ToString());}当然,要注意的就是,不要出现不存在的属性名。