PetaPoco对数据库的操作直接使用SQL语句,在代码中进行调用既可以直接传递SQL语句,也可以使用提供的SQL类来获取到SQL语句进行操作,直接传递SQL语句在内部实现中也是封装成Sql类传递到底层来操作的。Sql类实际上就是对SQL语句的一种封装,使你能够向操作类的方法一样来使用SQL语句。比如,

 var sql=Sql.Builder.Select(“*”).From(“person”).Where(“ID=@”,””)
var sqlStr=sql.SQL;//select * from person where ID=’1345’;

  Sql类采用函数式编程的思想,对SQL语句进行了抽象。当然,如果觉得这种表达方式不好,也可以直接传递SQL语句。

备注:使用Sql类时,如果传递参数,则在sql语句中@X进行占位,每次调用一个方法都从0开始,依次增加。

以下是对Sql类的详细描述:

 /// <summary>
/// SQL语句类
/// </summary>
public class Sql
{
/// <summary>
/// 初始SQL语句
/// </summary>
private string mInitialSQL; /// <summary>
/// 初始SQL参数
/// </summary>
private object[] mInitialArgs; /// <summary>
/// 最终SQL语句
/// </summary>
private string mFinalSQL; /// <summary>
/// 最终SQL参数
/// </summary>
private object[] mFinalArgs; /// <summary>
/// right-hand-side 引用,理解为后继
/// </summary>
private Sql mRHS; /// <summary>
/// 获取实例
/// </summary>
public static Sql Builder
{
get { return new Sql(); }
} /// <summary>
/// 获取SQL语句
/// </summary>
public string SQL
{
get
{
Build();
return mFinalSQL;
}
} /// <summary>
/// 获取构建SQL语句的参数
/// </summary>
public object[] Arguments
{
get
{
Build();
return mFinalArgs;
}
} /// <summary>
/// 默认构造器
/// </summary>
public Sql()
{
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="args">SQL语句对应的参数</param>
public Sql(string sql, params object[] args)
{
mInitialSQL = sql;
mInitialArgs = args;
} private void Build()
{
//只需要构建一次即可
if (mFinalSQL != null)
return;
//根据SQL语句和参数构建最终语句
var sb = new StringBuilder();
var args = new List<object>();
Build(sb, args, null);
mFinalSQL = sb.ToString();
mFinalArgs = args.ToArray();
} /// <summary>
/// 向当前SQL实例添加后继SQL实例 Append another SQL builder instance to the right-hand-side of this SQL builder
/// </summary>
/// <param name="sql">后继SQL实例</param>
/// <returns>返回对象自身</returns>
public Sql Append(Sql sql)
{
//若当前对象包括后继对象,则向其后继对象添加后继对象
if (mRHS != null)
mRHS.Append(sql);
else
mRHS = sql;
mFinalSQL = null;
return this;
} /// <summary>
/// 向当前SQL实例添加SQL语句和对应参数
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="args">对应参数</param>
/// <returns>返回对象自身</returns>
public Sql Append(string sql, params object[] args)
{
return Append(new Sql(sql, args));
} /// <summary>
/// 判断SQL语句是否与参数表示类型相同
/// </summary>
/// <param name="sql">SQL帮助类</param>
/// <param name="sqltype">SQL类型</param>
/// <returns></returns>
private static bool Is(Sql sql, string sqltype)
{
return sql != null && sql.mInitialSQL != null && sql.mInitialSQL.StartsWith(sqltype, StringComparison.InvariantCultureIgnoreCase);
} /// <summary>
/// 构建SQL语句
/// </summary>
/// <param name="sb">StringBuilder保存Sql语句</param>
/// <param name="args">SQL参数</param>
/// <param name="lhs">SQL实例</param>
private void Build(StringBuilder sb, List<object> args, Sql lhs)
{
if (!string.IsNullOrEmpty(mInitialSQL))
{
if (sb.Length > )
{
sb.Append("\n");
}
var sql = ParametersHelper.ProcessParams(mInitialSQL, mInitialArgs, args);
//累加where条件
if (Is(lhs, "WHERE ") && Is(this, "WHERE "))
sql = "AND " + sql.Substring();
//累加Order by 条件
if (Is(lhs, "ORDER BY ") && Is(this, "ORDER BY "))
sql = ", " + sql.Substring();
//累加set语句
if (Is(lhs, "SET ") && Is(this, "SET "))
sql = ", " + sql.Substring(); sb.Append(sql);
}
//处理当前实例的后继实例(递归)
if (mRHS != null)
mRHS.Build(sb, args, this);
} /// <summary>
/// 向SQL实例添加set语句
/// </summary>
/// <param name="sql">update中的set语句,形如"{field} = {value}" </param>
/// <param name="args">可选参数</param>
/// <returns>当前SQL实例</returns>
public Sql Set(string sql, params object[] args)
{
return Append(new Sql("SET " + sql, args));
} /// <summary>
/// 向SQL实例添加where语句
/// </summary>
/// <param name="sql">where语句</param>
/// <param name="args">可选参数</param>
/// <returns>当前SQL实例</returns>
public Sql Where(string sql, params object[] args)
{
return Append(new Sql("WHERE (" + sql + ")", args));
} /// <summary>
/// 向SQL实例添加order by语句
/// </summary>
/// <param name="columns">待排序的列名称</param>
/// <returns>当前SQL实例</returns>
public Sql OrderBy(params object[] columns)
{
return Append(new Sql("ORDER BY " + string.Join(", ", (from x in columns select x.ToString()).ToArray())));
} /// <summary>
/// 向SQL实例添加select语句
/// </summary>
/// <param name="columns">查询的结果列名称</param>
/// <returns>当前SQL实例</returns>
public Sql Select(params object[] columns)
{
return Append(new Sql("SELECT " + string.Join(", ", (from x in columns select x.ToString()).ToArray())));
} /// <summary>
/// 向SQL实例添加查询表(多个表相互连接,数量指数级增长)
/// </summary>
/// <param name="tables">查询的表名称</param>
/// <returns>当前SQL实例</returns>
public Sql From(params object[] tables)
{
return Append(new Sql("FROM " + string.Join(", ", (from x in tables select x.ToString()).ToArray())));
} /// <summary>
/// 向SQL实例添加group by语句
/// </summary>
/// <param name="columns">待分组列名称</param>
/// <returns>当前SQL实例</returns>
public Sql GroupBy(params object[] columns)
{
return Append(new Sql("GROUP BY " + string.Join(", ", (from x in columns select x.ToString()).ToArray())));
} /// <summary>
/// 数据表连接
/// </summary>
/// <param name="joinType">连接类型</param>
/// <param name="table">待连接表名称</param>
/// <returns>SqlJoinClause实例</returns>
private SqlJoinClause Join(string joinType, string table)
{
return new SqlJoinClause(Append(new Sql(joinType + table)));
} /// <summary>
/// 数据表内连接
/// </summary>
/// <param name="table">待连接表名称</param>
/// <returns>SqlJoinClause实例</returns>
public SqlJoinClause InnerJoin(string table)
{
return Join("INNER JOIN ", table);
} /// <summary>
/// 数据表外连接
/// </summary>
/// <param name="table">待连接表名称</param>
/// <returns>SqlJoinClause实例</returns>
public SqlJoinClause LeftJoin(string table)
{
return Join("LEFT JOIN ", table);
} /// <summary>
/// 获取最终的SQL语句
/// </summary>
public override string ToString()
{
return SQL;
}
} /// <summary>
/// SQL连接语句
/// </summary>
public class SqlJoinClause
{
/// <summary>
/// 待连接的SQL对象
/// </summary>
private readonly Sql _sql; /// <summary>
/// 构造函数
/// </summary>
/// <param name="sql"></param>
public SqlJoinClause(Sql sql)
{
_sql = sql;
} /// <summary>
/// 向SQL对象添加表连接条件
/// </summary>
/// <param name="onClause">表连接条件</param>
/// <param name="args">可选参数</param>
/// <returns>SQL对象</returns>
public Sql On(string onClause, params object[] args)
{
return _sql.Append("ON " + onClause, args);
}
}

PetaPoco源代码学习--3.Sql类的更多相关文章

  1. PetaPoco源代码学习--0.目录贴

    2017年3季度后,以人力外包的形式派驻到甲方单位进行项目救急时,接触到了甲方单位的ASP.NET MVC项目的ORM框架,它以PetaPoco(2012年的老版本)进行改造升级的,当初就想学习一下这 ...

  2. PetaPoco源代码学习--2.TableInfo、ColumnInfo类和Cache类

    当把常用的特性填写到POCO实体类时,执行数据库操作时,需要根据实体类上的特性信息进行相应的操作,PetaPoco中的TableInfo和ColumnInfo类就是用来保存实体类上的特性信息. Tab ...

  3. PetaPoco源代码学习--1.使用的Attribute介绍

    新版本的PetaPoco使用特性进行注解的形式来代替的老版本的映射类的形式.新版本中使用的特性主要包括以下几种: 名称   用途 TableNameAttribute Class 指定POCO实体类对 ...

  4. Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 博客园主页:http://www.cnblogs.com/mcxiaobing ...

  5. struts2源代码学习之初始化(一)

    看struts2源代码已有一段时日,从今天開始,就做一个总结吧. 首先,先看看怎么调试struts2源代码吧,主要是下面步骤: 使用Myeclipse创建一个webproject 导入struts2须 ...

  6. 开源中国安卓client源代码学习(一) 渐变启动界面

    开源中国安卓client源代码学习(一) 渐变启动界面 准备学习安卓开发, 看到网上有人推荐开源中国安卓client的源代码, 说里面包括了大部分技术, 于是准备好好研究研究. 特开通此系列博客来记录 ...

  7. 读Flask源代码学习Python--config原理

    读Flask源代码学习Python--config原理 个人学习笔记,水平有限.如果理解错误的地方,请大家指出来,谢谢!第一次写文章,发现好累--!. 起因   莫名其妙在第一份工作中使用了从来没有接 ...

  8. nginx源代码学习资源(不断更新)

    nginx源代码学习是一个痛苦又快乐的过程,以下列出了一些nginx的学习资源. 首先要做的当然是下载一份nginx源代码,能够从nginx官方站点下载一份最新的. 看了nginx源代码,发现这是一份 ...

  9. djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习

    Django REST framework JWT djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习 SECRET_KEY = '1)q(f8jrz^edwtr2 ...

随机推荐

  1. Rabbit MQ 入门指南

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.他遵循Mozilla Public License开源协议.采用 Erlang 实现的工业级的消息队列(MQ)服务器. Ra ...

  2. 58VIP账号发贴器

    因公司有招聘大量普工需求,需要大量简历资源,直接从58买一份简历动辄几块到几十块,如果做精准少则1块以上的点击.而且收到的简历不太精准,应公司需求写了一款自动发贴器.完全模拟人工发贴,经过一个月的测试 ...

  3. webpack安装整理

    早上有点时间大概安装一下webpack,操作一下顺便把步骤记一下,乱乱的,还是记录一下吧! webpack安装步骤:1. 2. 3.一直回车,出现如下图: 4.创建src和dist文件 5.需要在np ...

  4. 【文文殿下】[APIO2010]特别行动队 题解

    基本上是一个斜率优化裸题了 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int max ...

  5. 网络基础、ftp任务(进度条、计算文件大小、断点续传、搭建框架示例)

    一.网络基础 1.端口,是什么?为什么要有端口? 端口是为了将同一个电脑上的不同程序进行隔离. IP是找电脑:端口是找电脑上的应用程序: 端口范围:1 – 65535 :    1 - 1024 不要 ...

  6. SpringBoot入门之内嵌Tomcat配置

    spring boot默认web程序启用tomcat内嵌容器tomcat,监听8080端口,servletPath默认为 / .需要用到的就是端口.上下文路径的修改,在spring boot中其修改方 ...

  7. 设计模式《JAVA与模式》之调停者模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述调停者(Mediator)模式的: 调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从 ...

  8. iOS开发-带Placeholder的UITextView实现

    iOS中UITextField带有PlaceHolder属性,可以方便用于提示输入.但是同样可以进行文本输入的UITextView控件则没有PlaceHolder属性,还是有些不方便的,尤其是对于略带 ...

  9. (转)Linux 系统监控、诊断工具之 top命令详解

    原文:https://www.linuxidc.com/Linux/2014-12/110563.htm 目录 (1)系统.任务统计信息:(2)进程. cpu 统计信息:(3)最后两行为内存信息:3. ...

  10. webgl之五彩光源

    一.Three.js中有哪些光源? 在Three.js中,光源有一个基类THREE.Light(hex),这个hex接受16进制颜色作为参数而初始化光源的颜色,比如我们要定义一种绿色的光源,可以这样来 ...