• 模式与架构系列之二:分层、反射与OR映射


    对软件进行分层可以达到结构清晰、易于重用的目的。软件的分层类似于社会的分工,有了分工,人们就可以专司其职,搞IT的就不用边写.NET程序边种庄稼了。

    在软件结构中,分层结构是一种最易于理解的结构。下面介绍的是一个简单的分层结构,它可以用在一些简单的项目上(实际上它正在被使用),如进销存系统这类主要和数据库打交道的系统。

    1、数据访问层
    (1)使用工厂模式实现的通用数据访问功能。关于如何用工厂模式实现此功能,网上很多,实现起来也比较容易,可以使用IdbConnectionIdbCommandIdbTransaction等接口。这里就不再说了。

    (2)基于反射,实现“实体类<——>Sql语句”。包含BuildCreateObjSql(生成Insert语句)、BuildUpdateObjSql(生成Update语句)、BuildSelectObjSql(生成Select语句)、BuildObj(由IdataReade创建实体类对象,并为成员变量赋值)、BuildObjs(由DataTable生成实体类对象数组)等方法,方法实现过程类似如下(省略部分代码,要求实体类名=数据库表名,实体属性名=数据库表字段名):

    public static string BuildCreateObjSql(object pObj)
    {
        …………
        Type t
    = pObj.GetType();
        PropertyInfo[] pis
    =t.GetProperties();
        
    for(int i=0;i<pis.Length;i++)
        
    {
            
    switch(pis[i].PropertyType.ToString())
            
    {
                
    case"System.Int32":
                    fieldString
    +=pis[i].Name;
                    valueString
    +=pis[i].GetValue(pObj,null).ToString();
                    
    break;
                
    case"System.String":
                    …………
            }

            
    if(i<pis.Length-1)
            
    {
                fieldString
    +=",";
                valueString
    +=",";
            }

        }

        result
    ="insert into "+t.Name+"("+fieldString+") values("+valueString+")"+";";
        
    return result;
    }



    public static object BuildObj(string pClassName,IDataReader pReader)
    {
        Type t
    =Type.GetType(namespace+ pClassName);
        PropertyInfo[] pis
    =t.GetProperties();
        
    object obj=Activator.CreateInstance(t);
        BindValue (obj,pis,pReader); 
    //为各字段赋值
        return obj;
    }



    private static void BindValue (object pObj,PropertyInfo[] pPis,IDataReader pReader)
    {
        
    for(int i=0;i<pPis.Length;i++)
        
    {
            
    for(int j=0;j<pReader.FieldCount;j++)
            
    {
                
    switch(pPis[i].PropertyType.ToString())
                
    {
                    
    case"System.Int32":
                        pPis[i].SetValue(pObj,
    int.Parse(pReader[pPis[i].Name].ToString()),null);
                        
    break;
                    
    case"System.String":
                        …………;
                        
    break;
                }

            }

        }

    }

    2

    、实体层
    该层包含所有的实体类。假设数据库中存在一表叫Book的表,包括id,bookname,price,authorid字段,那么对应的实体类类似如下(当数据库表数量较多时,编写实体类的工作会显示枯燥无味,好像现在有不少工具可以完成由数据库表生成实体类文件的工作):

    public class Book : EntityHome
    {
        
    private string m_BookName;
        
    private decimal m_Price;
        
    private int m_AuthorID;

        
    public Book()
        
    {
        }

        
        
    public Book(int ID,string BookName, decimal Price, int AuthorID)
        
    {
            
    this.ID=ID;
            
    this.BookName=BookName;
            
    this.Price=Price;
            
    this.AuthorID=AuthorID;
        }


        
    public string BookName
        
    {
            
    get
            
    {
                
    return this.m_BookName;
            }

            
    set
            
    {
                
    this.m_BookName=value;
            }

        }


        
    public decimal Price
        
    {
            …………
        }


        
    public int AuthorID
        
    {
            …………
        }

    }

    3、业务层:
    在业务层中,包含了所有的控制类,它们与上面的实体类一一对应,主要的继承链始于:SingleHomeCtr(处理单个实体类的控制类基类);MultiHomeCtr(处理多个实体类的控制类),类似如下:

    public class BookCtr:SingleHomeCtr
    {
        
    public BookCtr()
        
    {
        }


        
    public void CreateObj(Book obj)
        
    {
            
    //通过数据访问层中的反射方法,生成sql语句,并最终持久化成数据库表中的一条记录。
            …………
        }


        
    public Book RetrieveObj(int id)
        
    {
            
    //通过数据访问层中的方法,生成sql语句,并最终返回一个Book对象。
            …………
        }


        
    public void UpdateObj(Book obj)
        
    {
            
    //通过数据访问层中的反射方法,生成sql语句,并最终持久化成数据库表中的一条记录。
            …………
        }

    }

    4UI
    有了以上的准备工作,在界面上对数据库的操作,就可以“对象化”了,例如根据数据库表的一条记录创建一个Book对象:
    Book b = null;
    BookCtr bctr = new BookCtr();
    b = bctr.RetrieveObj(id);
    或者持久化一条数据到数据库(对象的CreateObj方法)、或者更新一条数据库记录(对象的UpdateObj方法)

    5、最后
    在这个结构中包含了OR映射的概念。OR映射主要解决对象与关系数据之间的映射以及对象的持久化问题,翻译成白话就是怎么样把对数据库的操作归结到对对象的操作。这个工作有许多复杂的地方,不是凭借一己之力以完成的。所以在上面的示例中,实际情况是只能完成一些简单的映射,对于一些所谓的“粗粒度对象”(即一个对象需要关联多个数据库表)的映射,实现起来比较困难。

  • 相关阅读:
    JQuery的学习笔记
    Ajax的学习笔记
    软件项目的托管平台gitHub
    滚动事件:document.body.scrollTop总是0的原因
    Less/Sass编译工具,koala使用指南
    CSS中的浮动和清除浮动,梳理一下
    PHP_GET数据获取
    php中header()
    服务端web开发:PHP简介以及常见语法
    C/S架构和B/S架构
  • 原文地址:https://www.cnblogs.com/morvenhuang/p/971775.html
Copyright © 2020-2023  润新知