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 ...
随机推荐
- IIS日志存入数据库之一:ODBC
园内@Fish Li的文章<IIS日志-网站运维的好帮手>中介绍将IIS的文本格式的文件导入数据库的方法.在实践中,我们发现导数据的速度很慢,一个200M的日志文件居然要近100分钟.我们 ...
- Canvas教程
一.Canvas基本用法 canvas对应中文是“画布”,<canvas>是HTML5的新元素,IE9+支持 canvas元素的默认大小是300px * 150px,最简单的代码将生成一个 ...
- 【CF995F】 Cowmpany Cowmpensation
CF995F Cowmpany Cowmpensation Solution 这道题目可以看出我的代码能力是有多渣(代码能力严重退化) 我们先考虑dp,很容易写出方程: 设\(f_{i,j}\)表示以 ...
- 2019/4/23 todolist
近期的任务单子大概是这样吧 bjoi2019改完,写题解 hnoi2019改一些,写题解 找3道网络流写写 写一场agc,写题解 找2道简单计算几何写写
- 【多线程】:Synchronized和ReentrantLock的对比
相同点: 两者都是可重入锁,同一个线程每进入一次,锁的计数器都自增1,等到锁的计数器下降为0时才能释放锁. 底层实现对比: Synchronized是依赖于JVM实现的,而ReentrantLock是 ...
- mybatis---属性和字段映射
1. 查询时使用别名,别名和属性名保持一致 <select id="getUser" parameterType="int" resultType=&qu ...
- odoo 默认显示字段
@api.multi def generate_customs_declaration(self): # if len(self.mapped('cus_goods_list_ids')) != 1: ...
- redhat_6.5下载地址
redhat官方下载(需要注册帐号+订阅/申请试用方可下载) https://access.redhat.com/downloads/ 网络资源:附RHEL 6.5安装文件MD5及SHA-256:一. ...
- MethodImplOptions.Synchronized的一点讨论
Review代码发现有一个方法加了[MethodImpl(MethodImplOptions.Synchronized)] 属性,这个属性的目的,从名字上就可以看出,是要对所有线程进行同步执行. 对方 ...
- 匿名类、包、权限修饰符_DAY10
1:内部类(理解) (1)把类定义在一个类的内部. (2)特点: A:内部类可以直接使用外部类的成员,包括私有. B:外部类要使用内部类成员,必须创建对象使用. 例子: public c ...