大家可能会经常遇到接口需要经常增加新的方法和实现,可是我们原则上是不建议平凡的增加修改删除接口方法,熟不知这样使用接口是不是正确的接口用法,比如我见到很多的项目分层都是IDAL,DAL,IBLL,BLL,使用了2层接口,名义上是数据隔离和业务隔离,但是会使代码难调试,难维护,有可能代码写的不好或者需求变更造成IBLL,BLL,IDAL,DAL的全部修改,这真的是代码架构之疡。

基于上述观点,我i重构DAL来废除IDAL,IBLL造成的架构臃肿

使用模板模式创建Get和GetList方法,使他具有分页和多表查询,事务查询的能力

使用命令模式创建AddWhere方法,使他具有Where族的能力,能处理复杂SQL查询的能力

通过此模式,程序员可以在BLL中自由组合Where,Order,Gounp by不需要写一个方法,再也不会在DAL中出现GetByName,GetListByType这样的方法。

如需迁移redis和mongodb,建议重新搞一套redis的Base

代码大致如下

AbsSelectBase.cs

public class AbsSelectBase<T> where T : BaseModel
{
private List<absWhere> lWhere { get; set; }
public PageModel page { get; set; }
protected string Table { get; set; }
public RBase1()
{
page = new PageModel();
lWhere = new List<absWhere>();
Init();
} protected virtual void Init()
{ }
public virtual List<T> GetList(MySqlTransaction tran = null)
{
string where;
var lpar = GetWhere(out where);
var list = new List<T>();
if (page.Order_field.IsNull())
{
page.Order_field = "Id desc";
}
if (page.Current_Page.HasValue)
{
list = GetPageList("", page.Order_field, Table, page, where, "", lpar, tran);
}
else
{
list = Query("select * from " + Table + " where " + where, page.Order_field, lpar, tran);
}
return list;
}
public void AddWhere(absWhere where)
{
lWhere.Add(where);
}
public T Get(MySqlTransaction tran = null)
{
page.Current_Page = ;
page.Page_Size = ;
var entity = GetList(tran).FirstOrDefault();
return entity;
}
public virtual DynamicParameters GetWhere(out string where)
{
DynamicParameters lpar = new DynamicParameters();
where = " IsValid=1 ";
foreach (var ewhere in lWhere)
{
where += ewhere.CreateWhere(lpar);
}
lWhere.clear();
lWhere=null;
return lpar;
}
public object GetCount(MySqlTransaction tran = null)
{
string where = "";
var lpar = GetWhere(out where);
var res = SqlConnections.Sqlconnection.Query<int>("select count(1) from " + Table + " where " + where, lpar, tran);
return res;
} protected virtual List<T> GetPageList(string Field, string Order, string Table, PageModel model, string Where, string bigOrderBy = null, object param = null,
MySqlTransaction sqlTransation = null)
{
var res = SqlConnections.Sqlconnection.GetPageList<T>(Field, Order, Table, model, Where, bigOrderBy, param, sqlTransation).ToList();
return res;
} }

ConcreteSelectA.cs

public class RScoreRecordSelect : RBase1<ScoreRecord>
{
public RScoreRecordSelect()
{
} }

ConcreteSelectB.cs,多表

/// <summary>
/// ProductBuy inner join User
/// </summary>
public class RProBuyUserSelect : RBase1<ProductBuy>
{
public override List<ProductBuy> GetList(MySql.Data.MySqlClient.MySqlTransaction tran = null)
{
string where;
var lpar = GetWhere(out where);
var list = new List<ProductBuy>();
string table = @" User inner join ProductBuy on User.ID=ProductBuy.UserID ";
if (page.Order_field.IsNull())
{
page.Order_field = "ProductBuy.Id desc";
}
if (page.Current_Page.HasValue)
{
list = GetPageList("", page.Order_field, table, page, where, "", lpar, tran);
}
else
{
list = Query("select ProductBuy.* from " + table + " where " + where, page.Order_field, lpar, tran);
}
return list;
}
public override CZCore.Data.DynamicParameters GetWhere(out string where)
{
DynamicParameters lpar = new DynamicParameters();
where = " User.IsValid=1 and ProductBuy.IsValid=1 ";
foreach (var ewhere in lWhere)
{
where += ewhere.CreateWhere(lpar);
}
return lpar;
}
public enum EnumOrder
{
/// <summary>
///
/// </summary>
[Category("UserAct.BuyCount")]
[Description("")]
_0,
/// <summary>
///
/// </summary>
[Category("UserAct.BuyMoney")]
[Description("")]
_1,
/// <summary>
///
/// </summary>
[Category("UserAct.CashScore")]
[Description("")]
_2,
/// <summary>
///
/// </summary>
[Category("DBB.Money")]
[Description("")]
_3,
/// <summary>
///
/// </summary>
[Category("DBB.Score")]
[Description("")]
_4
}
}

absWhere.cs

public abstract class absWhere
{
private string _field;
public string field
{
get
{
return _field;
}
set
{
_field = value;
}
}
public object value { get; set; }
private string _par;
public string par
{
get
{
if (_par.IsNull())
{
_par = field.Replace(".","");
}
return _par;
}
set
{
_par = value;
}
} public abstract string CreateWhere(DynamicParameters lpar);
}

WhereAndIn.cs

public class WhereAndIn : absWhere
{ public override string CreateWhere(CZCore.Data.DynamicParameters lpar)
{ string sql="";
if (value.IsNull() == false)
{
sql = " and "+field+" in @"+par+" ";
lpar.Add(par, value);
}
return sql;
}
}

WhereAndLike.cs

public class WhereAndLike : absWhere
{ public override string CreateWhere(CZCore.Data.DynamicParameters lpar)
{ string sql="";
if (value.IsNull() == false)
{
sql = " and "+field+" like @"+par+" ";
lpar.Add(par, "%"+value+"%");
}
return sql;
}
}

单表查询

多表查询

简单的处理增删改查主键,等于Entity属性的简单查询不分页功能,并在上层提供一个总的facade门面

AbsBase.cs

public class RBase<T> where T : BaseModel
{ public List<T> GetAll(MySqlTransaction tran = null)
{ var list = SqlConnections.Sqlconnection.GetAll<T>(tran);
return list; } public T GetById(object id, MySqlTransaction tran = null)
{ var res = SqlConnections.Sqlconnection.GetById<T>(id, tran);
return res; } public UInt64 Insert(T T, MySqlTransaction tran = null, MySqlConnection _conn = null, bool IsAuto = true)
{ var res = SqlConnections.Sqlconnection.Insert<T>(T, tran, IsAuto);
return res; } public void Insert(List<T> list, MySqlTransaction tran = null, MySqlConnection _conn = null)
{ SqlConnections.Sqlconnection.Insert<T>(list, tran); } public void Update(T T, MySqlTransaction tran = null, MySqlConnection _conn = null)
{ SqlConnections.Sqlconnection.Update<T>(T, tran); } public void Update(List<T> list, MySqlTransaction tran = null, MySqlConnection _conn = null)
{ SqlConnections.Sqlconnection.Update<T>(list, tran); } public List<T> Search(T t, MySqlTransaction tran = null, MySqlConnection _conn = null)
{ var res = SqlConnections.Sqlconnection.Search<T>(t, tran);
return res; } public bool Delete(object id, bool isDelete = false, MySqlTransaction tran = null, MySqlConnection _conn = null)
{ var res = SqlConnections.Sqlconnection.Delete<T>(id, tran, isDelete: isDelete);
return res; } public void DeleteBySearch(T t, bool isDelete = false, MySqlTransaction tran = null, MySqlConnection _conn = null)
{ SqlConnections.Sqlconnection.DeleteBySearch<T>(t, tran, isDelete: isDelete); } public RBase()
{
Init();
} public virtual void Init()
{ } public void TruncateTable(MySqlTransaction sqlTransation = null)
{
bool result = Execute(
string.Format(
"Truncate Table {0}",
"`" + typeof(T).Name.ToLower() + "`"
), null, sqlTransation) > ;
} }

Concrete1.cs

public class RScoreRecord:RBase<ScoreRecord>
{
}

Facade.cs

Model层封装Entity层,并懒加载Entity数据,只加载关联id一级数据

MUser.cs

public class MUser
{
private User eUser;
public MUser(User _eUser)
{
eUser=_eUser; }
private UserAct eUserAct;
public UserAct GetEUserAct(MySql.Data.MySqlClient.MySqlTransaction ts = null)
{
if (eUserAct == null)
{
eUserAct = RCommon.rUserAct.GetById(eUser.Id,ts);
}
return eUserAct;
}
private DBB eDBB;
public DBB GetDBB(MySql.Data.MySqlClient.MySqlTransaction ts=null)
{
if (eDBB == null)
{
eDBB = RCommon.rdbb.GetById(eUser.Id,ts);
}
return eDBB;
} }

使用复合设计模式扩展持久化的CURD,Select能力的更多相关文章

  1. MVC是一种用于表示层设计的复合设计模式

    它们之间的交互有以下几种:       1.当用户在视图上做任何需要调用模型的操作时,它的请求将被控制器截获.       2.控制器按照自身指定的策略,将用户行为翻译成模型操作,调用模型相应逻辑实现 ...

  2. 使用远程接口库进一步扩展Robot Framework的测试能力

    引言: Robot Framework的四层结构已经极大的提高了它的扩展性.我们可以使用它丰富的扩展库来完成大部分测试工作.可是碰到下面两种情况,仅靠四层结构就不好使了: 1.有些复杂的测试可能跨越多 ...

  3. 利用selenroid扩展uiautoamtor的webview解析能力

    uiautomator是一个非侵入式框架,但是webview解析能力很弱.为了改进webview的支持,可以考虑把webdriver或者selenroid整合进来. 具体接入可参考:http://se ...

  4. C#基础系列——委托实现简单设计模式

    前言:上一篇介绍了下多线程的相关知识:C#基础系列——多线程的常见用法详解,里面就提到了委托变量.这篇简单介绍下委托的使用.当然啦,园子里面很多介绍委托的文章都会说道:委托和事件的概念就像一道坎,过了 ...

  5. ThinkPHP查询数据与CURD

    一.创建连接 在配置文件中使用如下配置: /* 数据库设置 */ 'DB_TYPE' => 'mysql', // 数据库类型 'DB_HOST' => 'localhost', // 服 ...

  6. MySQL复合索引探究

    复合索引(又称为联合索引),是在多个列上创建的索引.创建复合索引最重要的是列顺序的选择,这关系到索引能否使用上,或者影响多少个谓词条件能使用上索引.复合索引的使用遵循最左匹配原则,只有索引左边的列匹配 ...

  7. 工作流中的数据持久化详解!Activiti框架中JPA的使用分析

    Activiti中JPA简介 可以使用JPA实体作为流程变量, 并进行操作: 基于流程变量更新已有的JPA实体,可以在用户任务的表单中填写或者由服务任务生成 重用已有的领域模型,不需要编写显示的服务获 ...

  8. 业务流程可视化-让你的流程图"Run"起来(7.运行状态持久化&轻量工作流支持)

    前言 感谢大家阅读本项目系列文章和对项目的支持.分享一下我对这个项目的新的改进. 之前项目做到了流程设计可视化和流程运行结果可视化. 本期发布的版本中实现了中间的运行过程的实时可视化,和流程状态持久化 ...

  9. SQL select 语法(转)

    SQL 里面最常用的命令是 SELECT 语句,用于检索数据.语法是: SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] * | expr ...

随机推荐

  1. FWT与High dick(划掉改成Dimensional) Fourier Transform

    我们大家都知道xor卷积有个很好的做法:FWT.FWT的变换形式是很好看的 // 说明一下Vector可以向量化运算,也可以当做数组来slice与concat Vector tf(A,2^n){ Ve ...

  2. 阿里云直播PHP SDK如何使用

    前一篇聊了聊关于阿里云直播,如何进行进行调试,ok,那这篇我们就聊一聊关于阿里云直播的SDK(当然是关于PHP的),基于下面的原因: 1.直播云没有单独的SDK,直播部分的SDK是直接封装在CDN的相 ...

  3. CentOS7 睡眠 休眠 关机 电源

    设置装有 CentOS7 的笔记本合盖后黑屏进入睡眠模式 systemd 能够处理某些电源相关的 ACPI事件,你可以通过从 /etc/systemd/logind.conf 以下选项进行配置: Ha ...

  4. Js/Jquery获取iframe中的元素

    转载: Js/Jquery获取iframe中的元素 - - ITeye技术网站http://java-my-life.iteye.com/blog/1275205 在web开发中,经常会用到ifram ...

  5. 高德地图纯js和html

    <!doctype html> <html> <head> <meta content="" charset="utf-8&qu ...

  6. acm 1002 算法设计

    最近突然想往算法方向走走,做了做航电acm的几道题 二话不说,开始 航电acm 1002 题主要是处理长数据的问题,算法原理比较简单,就是用字符数组代替int,因为int太短需要处理的数据较长 下面是 ...

  7. Position属性四个值:static、fixed、absolute和relative的区别和用法

    Position属性四个值:static.fixed.absolute和relative的区别和用法 在用CSS+DIV进行布局的时候,一直对position的四个属性值relative,absolu ...

  8. centos 7 配置iptables

    环境:阿里云ECS.centos 7 一.防火墙配置 不知道为什么,云主机没有开启firewall 或iptables,记录一下配置iptables防火墙的步骤 1.检测并关闭firewall sys ...

  9. iOS开发之如何跳到系统设置里的各种设置界面

    跳到更多设置界面 除了跳到WiFi设置界面,能不能跳到其他的设置界面呢?比如:定位服务.FaceTime.音乐等等.都是可以的,一起来看看如何实现的! 定位服务 定位服务有很多APP都有,如果用户关闭 ...

  10. 关于for循环------swift3.0

    在程序开发当中,for循环使用的频率无疑是最高的.常用的swift循环是递增式遍历.当然各种循环,swift都能办到.但其大多采用关键字形式实现,大部分开发者更喜欢直接使用C式循环代码.在swift3 ...