PetaPoco源代码学习--3.Sql类
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类的更多相关文章
- PetaPoco源代码学习--0.目录贴
2017年3季度后,以人力外包的形式派驻到甲方单位进行项目救急时,接触到了甲方单位的ASP.NET MVC项目的ORM框架,它以PetaPoco(2012年的老版本)进行改造升级的,当初就想学习一下这 ...
- PetaPoco源代码学习--2.TableInfo、ColumnInfo类和Cache类
当把常用的特性填写到POCO实体类时,执行数据库操作时,需要根据实体类上的特性信息进行相应的操作,PetaPoco中的TableInfo和ColumnInfo类就是用来保存实体类上的特性信息. Tab ...
- PetaPoco源代码学习--1.使用的Attribute介绍
新版本的PetaPoco使用特性进行注解的形式来代替的老版本的映射类的形式.新版本中使用的特性主要包括以下几种: 名称 用途 TableNameAttribute Class 指定POCO实体类对 ...
- Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 博客园主页:http://www.cnblogs.com/mcxiaobing ...
- struts2源代码学习之初始化(一)
看struts2源代码已有一段时日,从今天開始,就做一个总结吧. 首先,先看看怎么调试struts2源代码吧,主要是下面步骤: 使用Myeclipse创建一个webproject 导入struts2须 ...
- 开源中国安卓client源代码学习(一) 渐变启动界面
开源中国安卓client源代码学习(一) 渐变启动界面 准备学习安卓开发, 看到网上有人推荐开源中国安卓client的源代码, 说里面包括了大部分技术, 于是准备好好研究研究. 特开通此系列博客来记录 ...
- 读Flask源代码学习Python--config原理
读Flask源代码学习Python--config原理 个人学习笔记,水平有限.如果理解错误的地方,请大家指出来,谢谢!第一次写文章,发现好累--!. 起因 莫名其妙在第一份工作中使用了从来没有接 ...
- nginx源代码学习资源(不断更新)
nginx源代码学习是一个痛苦又快乐的过程,以下列出了一些nginx的学习资源. 首先要做的当然是下载一份nginx源代码,能够从nginx官方站点下载一份最新的. 看了nginx源代码,发现这是一份 ...
- djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习
Django REST framework JWT djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习 SECRET_KEY = '1)q(f8jrz^edwtr2 ...
随机推荐
- sqlserver 自动创建作业执行备份数据库
declare @name varchar(250)set @name='I:\dydb_n\dydb_n'+convert(varchar(50),getdate(),112)+ left(righ ...
- Asp.Net Mvc异步上传文件的方式
今天试了下mvc自带的ajax,发现上传文件时后端action接收不到文件, Request.Files和HttpPostedFileBase都接收不到.....后来搜索了下才知道mvc自带的Ajax ...
- [leetcode.com]算法题目 - Maximum Subarray
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- 使用Python请求http/https时设置失败重试次数
设置请求时的重试规则 import requests from requests.adapters import HTTPAdapter s = requests.Session() a = HTTP ...
- MariaDB 存储过程与函数(10)
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...
- joi库 学习笔记
零.背景 node.js 应用中,req.query / req.body 传来的参数需要做 valication( 合法性验证 ) 一.安装 https://github.com/hapijs/jo ...
- Office 2010激活 NO KMS products detected问题
今天用office2010激活工具Office 2010 Toolkit激活安装的office2010时悲剧的遇到了这个问题,如下图: (这张图是从网上找的,不过和我遇到的问题是一样的). 然后上网搜 ...
- Stack&&Queue
特殊的容器:容器适配器 stack queue priority_queue:vector+堆算法---->优先级队列 stack: 1.栈的概念:特殊的线性结构,只允许 ...
- WebDriver高级应用实例(8)
8.1使用Log4j在测试过程中打印日志 目的:在测试过程中,使用Log4j打印日志,用于监控和后续调试测试脚本 被测网页的网址: http://www.baidu.com 环境准备: (1)访问ht ...
- 常用处理数据用法es6 语法糖总结
一 循环(数组 ,集合) 1 forEach-----------可以遍历得到vaue和index const arr = ['red', 'green', 'blue'];arr.forEa ...