当前位置: 首页 > news >正文

项目总结- 架构及代码样例

曾在公司参与过Extjs 4.2的项目开发,因为觉得在项目中学到了很多知识,特此记录一下。

首先介绍系统项目架构如下:(AAA是化名)

  • AAA.Mvc.Web:所有页面UI纯Extjs,Extjs内部又包含(controller, model, store, view)
  • AAA.Mvc.Controllers:这次包含所有的Web页面的请求,会去调用IBll中的handler (引用IBll, entities, model),返回类型为JsonResult。 所有的 try catch将只出现在这层,但是log对象可以出现在Controller/BLL/DAL中,可以记录数据访问的详细信息。

 

    public ICompanyHandler CompanyHandler { get; set; }
    Logger log = new  Logger(MethodBase.GetCurrentMethod().DeclaringType);

         [HttpGet]
        public JsonResult SearchCompany(Guid id, int CType, int limit, int start)
        {
            try
            {
                CommonTResult<Company> result = CompanyHandler.Search(id, CType, limit, start);
                List<CompanyView> viewList = new List<CompanyView>();
                if (result == null)
                {
                    return Json(new { data = viewList, total = 0, message = StringResources.NODATA, success = true },
                       JsonRequestBehavior.AllowGet);
                }
                foreach (Company entity in result.ResultList)
                {
                    viewList.Add(CompanyViewMapper.MapToView(entity));
                }

                return Json(new { data = viewList, total = result.ResultCount, success = true, message = StringResources.GETDATA_SUCCESS }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                log.ErrorLog(ex, MethodBase.GetCurrentMethod().Name);
                return Json(new { success = false, message = StringResources.GETDATA_FAILED }, JsonRequestBehavior.AllowGet);
            }
        }
Controlller

 

  • AAA.Mvc.Models: 定义前台数据操作的模型,但是这里的数据类型和Entity中有一些不一样,比如日期,在entity是datetime,但是在我们前台按照string来处理。所以此处的Models里面也存在Entity-model Mapping的逻辑。
public class CriticalField_LogViewMapper
   {
       public static CriticalField_LogView MapToView(CriticalField_Log entity)
       {
           CriticalField_LogView view = new CriticalField_LogView();
           view.LogId = entity.LogId;
           view.Operation = entity.Operation;
           view.OperationStatus = entity.OperationStatus;
           view.OperationLog = entity.OperationLog;
           view.ReferenceTable = entity.ReferenceTable;
           view.ReferenceNumber = entity.ReferenceNumber;
           view.LogXml = entity.LogXml;
           view.ProcessBy = entity.ProcessBy;
           view.ProcessDate = entity.ProcessDate;
           view.AppID = entity.AppID;
           view.AppNo = entity.AppNo;
           return view;
       }

       public static CriticalField_Log MapFromView(CriticalField_LogView view)
       {
           CriticalField_Log entity = new CriticalField_Log();
           entity.LogId = view.LogId;
           entity.Operation = view.Operation;
           entity.OperationStatus = view.OperationStatus;
           entity.OperationLog = view.OperationLog;
           entity.ReferenceTable = view.ReferenceTable;
           entity.ReferenceNumber = view.ReferenceNumber;
           entity.LogXml = view.LogXml;
           entity.ProcessBy = view.ProcessBy;
           entity.ProcessDate = view.ProcessDate;
           entity.AppID = view.AppID;
           entity.AppNo = view.AppNo;

           return entity;
       }
   }
EntityViewMapper
  • AAA.Entities:此处的entity基本和后台数据库表一一对应,也可以根据需要创建,比如有很多页面的查询条件类似,就对应建立了Query的Entity,传值到后台SP进行查询
  • AAA.Bll:定义handler,
public class CompanyHandler : ICompanyHandler
{
    public ICompanyDao CompanyDao { get; set; }
    public CommonTResult<Company> Search(Guid appID, int CType, int limit, int start)
        {
            return CompanyDao.Search(appID, CType, limit, start);
        }
}
CompanyHandler
  • AAA.IBll:定义handler接口
  • AAA.Dal:定义Dao,并包含Mapper,负责将数据从datareader转成对应的Entity,这里的数据库联接以及execute是直接使用了Spring.Data.Generic, 每个Dao类,都继承AdoDaoSupport类,并实现对应的IDao接口。
namespace Spring.Data.Generic
{
    public class AdoDaoSupport : DaoSupport
    {
        public AdoDaoSupport();

        public AdoTemplate AdoTemplate { get; set; }
        protected IDbConnection Connection { get; }
        public IDbProvider DbProvider { get; set; }
        protected IAdoExceptionTranslator ExceptionTranslator { get; }

        protected override void CheckDaoConfig();
        protected virtual AdoTemplate CreateAdoTemplate(IDbProvider dbProvider);
        protected virtual IDbParameters CreateDbParameters();
        protected virtual IDbParametersBuilder CreateDbParametersBuilder();
        protected void DisposeConnection(IDbConnection conn, IDbProvider dbProvider);
    }
}
AdoDaoSupport
public class CompanyDao : AdoDaoSupport, ICompanyDao
{
    public CommonTResult<Company> Search(Guid appID, int limit, int start)
        {
            CommonTResult<Company> result = new CommonTResult<Company>();

            IDbParameters parameters = AdoTemplate.CreateDbParameters();
            parameters.AddWithValue("AppID", appID);
            parameters.AddWithValue("Limit", limit);
            parameters.AddWithValue("Start", start);
            parameters.AddOut("Count", DbType.Int32);
            result.ResultList = AdoTemplate.QueryWithRowMapper<Company>(CommandType.StoredProcedure, GET_COMPANYLIST, new CompanyMapper<Company>(), parameters);
            result.ResultCount = (int)parameters["@Count"].Value;
            return result;
        }
}

   public class CommonTResult<T>
    {
        public IList<T> ResultList { get; set; }

        public int ResultCount { get; set; }

        public T ResultT { get; set; }

        public bool IsSuccess { get; set; }

        public string Message { get; set; }
    }
CompanyDao
    public class CriticalField_LogMapper<T> : IRowMapper<T> where T : CriticalField_Log, new()
    {
        T IRowMapper<T>.MapRow(IDataReader dataReader, int rowNum)
        {
            T view = new T();
            if (DataReaderRowFilter.RowFilter(dataReader, "LogId"))
                view.LogId = dataReader.GetValueOrDefault<Guid>("LogId");
            if (DataReaderRowFilter.RowFilter(dataReader, "AppID"))
                view.AppID = dataReader.GetValueOrDefault<Guid>("AppID");
            if (DataReaderRowFilter.RowFilter(dataReader, "Operation"))
                view.Operation = dataReader.GetValueOrDefault<string>("Operation");
            if (DataReaderRowFilter.RowFilter(dataReader, "OperationStatus"))
                view.OperationStatus = dataReader.GetValueOrDefault<string>("OperationStatus");
            if (DataReaderRowFilter.RowFilter(dataReader, "OperationLog"))
                view.OperationLog = dataReader.GetValueOrDefault<string>("OperationLog");
            if (DataReaderRowFilter.RowFilter(dataReader, "ReferenceTable"))
                view.ReferenceTable = dataReader.GetValueOrDefault<string>("ReferenceTable");
            if (DataReaderRowFilter.RowFilter(dataReader, "ReferenceNumber"))
                view.ReferenceNumber = dataReader.GetValueOrDefault<string>("ReferenceNumber");
            if (DataReaderRowFilter.RowFilter(dataReader, "LogXml"))
                view.LogXml = dataReader.GetValueOrDefault<string>("LogXml");
            if (DataReaderRowFilter.RowFilter(dataReader, "ProcessBy"))
                view.ProcessBy = dataReader.GetValueOrDefault<string>("ProcessBy");
            if (DataReaderRowFilter.RowFilter(dataReader, "ProcessDate"))
                view.ProcessDate = dataReader.GetValueOrDefault<DateTime>("ProcessDate");
            if (DataReaderRowFilter.RowFilter(dataReader, "AppNo"))
                view.AppNo = dataReader.GetValueOrDefault<string>("AppNo");
            return view;
        }
    }
DaoMapper
  • AAA.IDal:定义Dao接口
  • AAA.Framework:包含很多工具类,比如Logger,MaillSend,OpenXML,Convert等。另外,本系统以MVC来做页面交互,而页面后台则以三层架构来做数据交互,而在三层这里,我们使用Spring.net的IoC做依赖注入,控制这里的Bll,Dao,Controller的实例,对应的bll-objects.xml和dal-objects.xml也放在此处
public class Logger
    {
        public Logger(Type Class)
        {
            this.classname = Class.Name;
        }

        private string classname;

        public string ClassName
        {
            get
            {
                return this.classname;
            }
            set
            {
                this.classname = value;
            }
        }

        public void SystemLog(string Message, string Method) { WriteLogInTxtFile(1, Message, Method); }

        public void InfoLog(string Message, string Method) { WriteLogInTxtFile(2, Message, Method); }

        public void DebugLog(string Message, string Method) { WriteLogInTxtFile(3, Message, Method); }

        public void ErrorLog(string Message, string Method) { WriteLogInTxtFile(4, Message, Method); }

        public void ErrorLog(Exception Ex, string Method)
        {
            string Message = String.Format("异常信息: {0}, 异常堆栈信息: {1} ", Ex.Message, Ex.StackTrace);
            ErrorLog(Message, Method);
        }

        private void WriteLogInTxtFile(Int16 LogType, string Message, string Method)
        {
            string Path = AppDomain.CurrentDomain.BaseDirectory;

            string LogFolder = "Logs";

            if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["LogFolder"]))
            {
                LogFolder = ConfigurationManager.AppSettings["LogFolder"];
            }

            string LogPathType = String.Empty;

            switch (LogType)
            {
                case 1:
                    Path += String.Format("{0}\\System\\", LogFolder);
                    LogPathType = "System";
                    break;
                case 2:
                    Path += String.Format("{0}\\Info\\", LogFolder);
                    LogPathType = "Info";
                    break;
                case 3:
                    Path += String.Format("{0}\\Debug\\", LogFolder);
                    LogPathType = "Debug";
                    break;
                case 4:
                    Path += String.Format("{0}\\Error\\", LogFolder);
                    LogPathType = "Error";
                    break;
            }

            if (!Directory.Exists(Path))
            {
                Directory.CreateDirectory(Path);
            }

            //日志文件是以当天时间命名
            string FileName = String.Format("{0}{1}", Path, "Log" + DateTime.Now.ToString("yyyyMMdd") + ".txt");

            if (!File.Exists(FileName))
            {
                File.Create(FileName).Close();
            }

            //日志格式
            string LogFormat = String.Format("Start   时间:{0}   日志类型:{1}   类名:{2}   方法名称:{3}   日志内容:{4}   End;", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), LogPathType, ClassName, Method, Message);

            using (StreamWriter writer = File.AppendText(FileName))
            {
                writer.WriteLine(LogFormat);
            }
        }
    }
Logger
private static void SendMailBySMTP(string smtpServer, string from, string to, string subject, string message, string emailCC, string emailBcc)
        {
            try
            {
                System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
                if (to.Contains(";"))
                {
                    string[] mails = to.Split(';');
                    foreach (string v in mails)
                    {
                        if (!String.IsNullOrEmpty(v.Trim()))
                            msg.To.Add(v);
                    }
                }
                else
                {
                    msg.To.Add(to.Trim());
                }
                if (emailCC.Contains(";"))
                {
                    if (emailCC.Substring(emailCC.Length - 1, 1) == ";")
                        emailCC = emailCC.Substring(0, emailCC.Length - 1);
                    emailCC = emailCC.Replace(';', ',');
                    msg.CC.Add(emailCC);
                }
                else
                {
                    if (!String.IsNullOrEmpty(emailCC))
                    {
                        msg.CC.Add(emailCC.Trim());
                    }
                }
                if (emailBcc.Contains(";"))
                {
                    if (emailBcc.Substring(emailBcc.Length - 1, 1) == ";")
                        emailBcc = emailBcc.Substring(0, emailBcc.Length - 1);
                    emailBcc = emailBcc.Replace(';', ',');
                    msg.Bcc.Add(emailBcc);
                }
                else
                {
                    if (!String.IsNullOrEmpty(emailBcc))
                    {
                        msg.Bcc.Add(emailBcc.Trim());
                    }
                }
                msg.From = new System.Net.Mail.MailAddress(from);
                msg.Subject = subject;
                msg.SubjectEncoding = System.Text.Encoding.UTF8;
                msg.Body = message;
                msg.BodyEncoding = System.Text.Encoding.UTF8;
                msg.IsBodyHtml = true;
                msg.Priority = System.Net.Mail.MailPriority.High;
                System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
                client.Host = smtpServer;

                Log.DebugLog(" msg.To:" + msg.To, MethodBase.GetCurrentMethod().Name);
                Log.DebugLog(" msg.CC:" + msg.CC, MethodBase.GetCurrentMethod().Name);
                Log.DebugLog(" msg.Bcc:" + msg.Bcc, MethodBase.GetCurrentMethod().Name);
                Log.DebugLog(" smtpServer:" + smtpServer, MethodBase.GetCurrentMethod().Name);
                client.Send(msg);
            }
            catch (Exception ex)
            {
                Log.ErrorLog(ex, MethodBase.GetCurrentMethod().Name);
            }
        }
MailSend
public string MailMerge(string docFileName, string dataFileName, string outFileName)
        {
            object oFileName = docFileName;
            object oOutFileName = outFileName;
            //Word.Application wordApp = new Word.Application();
            object missing = System.Reflection.Missing.Value;
            object oTrue = true;
            object oFalse = false;
            object password = string.Format("MLES_{0}", DateTime.Now.ToString("yyyyMMdd"));
            Application app = new Application();

            try
            {
                app.Documents.Open(ref oFileName, ref oFalse, ref oTrue,
ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
app.ActiveDocument.MailMerge.OpenDataSource(dataFileName, ref missing, ref oFalse, ref oTrue, ref oTrue, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
                app.ActiveDocument.MailMerge.SuppressBlankLines = false;
                app.ActiveDocument.MailMerge.Destination = WdMailMergeDestination.wdSendToNewDocument;
                app.ActiveDocument.MailMerge.Execute(ref oFalse);
                app.ActiveDocument.SaveAs(ref oOutFileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,  ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
                app.ActiveDocument.Saved = true;

                return "Created Document: " + outFileName;
            }
            catch (Exception ex)
            {
                return "";
            }

            finally
            {
                app.ActiveDocument.Close(ref oFalse, ref missing, ref missing);
                app.Quit(ref missing, ref missing, ref missing);

            }
        }
MailMerge
public DataTable PriovetTableData(DataTable dt)
        {
            DataTable dtNew = new DataTable();
            dtNew.Columns.Add("ColumnName", typeof(string));
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                dtNew.Columns.Add("Value" + i.ToString(), typeof(string));
            }

            foreach (DataColumn dc in dt.Columns)
            {
                DataRow drNew = dtNew.NewRow();
                drNew["ColumnName"] = dc.ColumnName;
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    drNew[i + 1] = dt.Rows[i][dc].ToString();
                }
                dtNew.Rows.Add(drNew);
            }
            return dtNew;
        }
PriovetTableData

在DAL配置中,我们加入了Transaction 和 AOP

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
         xmlns:db="http://www.springframework.net/database"
         xmlns:tx="http://www.springframework.net/tx">

    <object id="dbProvider" type="Spring.Data.Common.UserCredentialsDbProvider, Spring.Data">
        <property name="TargetDbProvider" ref="targetDbProvider"/>
    </object>

    <db:provider id="targetDbProvider" provider="System.Data.SqlClient"
        connectionString=""/>

    <object id="adoTemplateT" type="Spring.Data.Generic.AdoTemplate, Spring.Data">
        <property name="DbProvider" ref="dbProvider"/>
        <property name="DataReaderWrapperType" value="Spring.Data.Support.NullMappingDataReader, Spring.Data"/>
    </object>

    <object id="companyDao" type="AAA.Dal.application.CompanyDao, AAA.Dal">
        <property name="AdoTemplate" ref="adoTemplateT"/>
    </object>

.......

<!--事务管理器-->
<!--
  <object id="transactionManager"
         type="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data">
    <property name="DbProvider" ref="DbProvider"/>
  </object> 
-->
<!--事务切面-->
<!--<tx:attribute-driven/>-->
  <object id="transactionManager"
        type="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data">
    <property name="DbProvider" ref="dbProvider"/>
  </object>

  <object id="proxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
    <property name="ObjectNames">
      <list>
        <value>*Handler</value>
        <!--<value>*Controller</value>-->
        <!--<value>loanApprovalLetterHandler</value>-->
      </list>
    </property>
    <property name="InterceptorNames" >
      <list>
        <value>throwsAdvice</value>
        <!--<value>transactionInterceptor</value>-->
        <!--<value>aroundAdvisor</value>-->
      </list>
    </property>
  </object>

  <!-- Transaction Interceptor -->
  <object id="transactionInterceptor"
          type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
    <property name="TransactionManager" ref="transactionManager"/>
    <property name="transactionAttributes">
      <name-values>
        <add key="Save*" value="PROPAGATION_NESTED"/>
        <add key="Add*" value="PROPAGATION_REQUIRED,timeout_1"/>
        <add key="Delete*" value="PROPAGATION_REQUIRED"/>
        <add key="Update*" value="PROPAGATION_REQUIRED"/>
        <add key="Get*" value="PROPAGATION_REQUIRED,readOnly"/>
        <!--<add key="Load*" value="PROPAGATION_REQUIRED,readOnly"/>
        <add key="Query*" value="PROPAGATION_REQUIRED,readOnly"/>
        <add key="Search*" value="PROPAGATION_REQUIRED,readOnly"/>-->
      </name-values>
    </property>
  </object>
  <!-- Throws Advice to log exception-->
  <object id="throwsAdvice"  type="AAA.Framework.ThrowsAdvice, AAA.Framework" />

  <!--Around Advisor -->
  <object id="aroundAdvisor" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop">
    <property name="Advice" ref="aroundAdvice"/>
    <property name="MappedNames">
      <list>
        <value>*</value>
      </list>
    </property>
  </object>
  <object id="aroundAdvice" type="AAA.Framework.AroundAdvice,AAA.Framework"/>

</objects>
dal-objects
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">

    <object id="CompanyController" singleton="false"  type="AAA.Mvc.Controllers.CompanyController,AAA.Mvc.Controllers">
        <property name="CompanyHandler" ref="companyHandler"/>
    </object>
    <object id="companyHandler" singleton="false"  type="AAA.BLL.CompanyHandler,AAA.BLL">
        <property name="CompanyDao" ref="companyDao"/>
    </object>
.......
</objects>
bll-objects
public class AroundAdvice : IMethodInterceptor
    {
        public object Invoke(IMethodInvocation invocation)
        {
            Logger log = new Logger(MethodBase.GetCurrentMethod().DeclaringType);

            log.DebugLog(string.Format("Before: invocation=[{0}]", invocation), "Invoke");
            object result = invocation.Proceed();
            log.DebugLog(string.Format("After : invocation=[{0}]", invocation), "Invoke");
            return result;
        }
    }

public class ThrowsAdvice : IThrowsAdvice
    {
        public void AfterThrowing(Exception ex)
        {
            Logger log = new Logger(MethodBase.GetCurrentMethod().DeclaringType);
            log.DebugLog(ex.ToString(), "AfterThrowing");
        }
    }
AOP

此处将每个部分的摘录部分代码供参考。

 

转载于:https://www.cnblogs.com/Ying150318/p/4648890.html

相关文章:

  • 关于Flash Player详细说明
  • android 网络交互
  • 指定索引
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • 这个世界并不亏欠我们什么——Leo网上答疑52
  • 《python核心编程》笔记——文件的创建、读取和显示
  • 详解TCC89x的LCD数值设置
  • gentoo系统安装
  • 你为什么不写注释?
  • GO语言练习:网络编程 TCP 示例
  • “梳子”的用途很大
  • Linux监控本机当前状态命令
  • eclipse中svn的各种状态图标详解
  • 201507221403_《backbone之一——新建模型和集合、实例化模型、模型上监听事件的方法、模型设置和获取后台数据、配置理由方法、视图绑定事件的方法、绑定模型等》...
  • Android HAL实例解析
  • JS 中的深拷贝与浅拷贝
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • javascript数组去重/查找/插入/删除
  • python3 使用 asyncio 代替线程
  • Python学习笔记 字符串拼接
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Sass 快速入门教程
  • SpringBoot 实战 (三) | 配置文件详解
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • Vue.js源码(2):初探List Rendering
  • 从输入URL到页面加载发生了什么
  • 大型网站性能监测、分析与优化常见问题QA
  • 关于使用markdown的方法(引自CSDN教程)
  • 缓存与缓冲
  • 聊一聊前端的监控
  • 码农张的Bug人生 - 初来乍到
  • 那些年我们用过的显示性能指标
  • 区块链技术特点之去中心化特性
  • 微信小程序:实现悬浮返回和分享按钮
  • 微信小程序开发问题汇总
  • 用jQuery怎么做到前后端分离
  • 白色的风信子
  • 阿里云API、SDK和CLI应用实践方案
  • ​VRRP 虚拟路由冗余协议(华为)
  • #stm32驱动外设模块总结w5500模块
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (6)添加vue-cookie
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (十三)Maven插件解析运行机制
  • (一)基于IDEA的JAVA基础10
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .java 9 找不到符号_java找不到符号
  • .NET的数据绑定