PetaPoco源代码学习--3.Sql类

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

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

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

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

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

  1 /// <summary>
  2     /// SQL语句类
  3     /// </summary>
  4     public class Sql
  5     {
  6         /// <summary>
  7         /// 初始SQL语句
  8         /// </summary>
  9         private string mInitialSQL;
 10 
 11         /// <summary>
 12         /// 初始SQL参数
 13         /// </summary>
 14         private object[] mInitialArgs;
 15 
 16         /// <summary>
 17         /// 最终SQL语句
 18         /// </summary>
 19         private string mFinalSQL;
 20 
 21         /// <summary>
 22         /// 最终SQL参数
 23         /// </summary>
 24         private object[] mFinalArgs;
 25 
 26         /// <summary>
 27         /// right-hand-side 引用,理解为后继
 28         /// </summary>
 29         private Sql mRHS;
 30 
 31         /// <summary>
 32         ///  获取实例
 33         /// </summary>
 34         public static Sql Builder
 35         {
 36             get { return new Sql(); }
 37         }
 38 
 39         /// <summary>
 40         ///  获取SQL语句
 41         /// </summary>
 42         public string SQL
 43         {
 44             get
 45             {
 46                 Build();
 47                 return mFinalSQL;
 48             }
 49         }
 50 
 51         /// <summary>
 52         /// 获取构建SQL语句的参数
 53         /// </summary>
 54         public object[] Arguments
 55         {
 56             get
 57             {
 58                 Build();
 59                 return mFinalArgs;
 60             }
 61         }
 62 
 63         /// <summary>
 64         /// 默认构造器
 65         /// </summary>
 66         public Sql()
 67         {
 68         }
 69 
 70         /// <summary>
 71         /// 构造函数
 72         /// </summary>
 73         /// <param name="sql">SQL语句</param>
 74         /// <param name="args">SQL语句对应的参数</param>
 75         public Sql(string sql, params object[] args)
 76         {
 77             mInitialSQL = sql;
 78             mInitialArgs = args;
 79         }
 80 
 81         private void Build()
 82         {
 83             //只需要构建一次即可
 84             if (mFinalSQL != null)
 85                 return;
 86             //根据SQL语句和参数构建最终语句
 87             var sb = new StringBuilder();
 88             var args = new List<object>();
 89             Build(sb, args, null);
 90             mFinalSQL = sb.ToString();
 91             mFinalArgs = args.ToArray();
 92         }
 93 
 94         /// <summary>
 95         ///  向当前SQL实例添加后继SQL实例   Append another SQL builder instance to the right-hand-side of this SQL builder
 96         /// </summary>
 97         /// <param name="sql">后继SQL实例</param>
 98         /// <returns>返回对象自身</returns>
 99         public Sql Append(Sql sql)
100         {
101             //若当前对象包括后继对象,则向其后继对象添加后继对象
102             if (mRHS != null)
103                 mRHS.Append(sql);
104             else
105                 mRHS = sql;
106             mFinalSQL = null;
107             return this;
108         }
109 
110         /// <summary>
111         ///  向当前SQL实例添加SQL语句和对应参数
112         /// </summary>
113         /// <param name="sql">SQL语句</param>
114         /// <param name="args">对应参数</param>
115         /// <returns>返回对象自身</returns>
116         public Sql Append(string sql, params object[] args)
117         {
118             return Append(new Sql(sql, args));
119         }
120 
121         /// <summary>
122         /// 判断SQL语句是否与参数表示类型相同
123         /// </summary>
124         /// <param name="sql">SQL帮助类</param>
125         /// <param name="sqltype">SQL类型</param>
126         /// <returns></returns>
127         private static bool Is(Sql sql, string sqltype)
128         {
129             return sql != null && sql.mInitialSQL != null && sql.mInitialSQL.StartsWith(sqltype, StringComparison.InvariantCultureIgnoreCase);
130         }
131 
132         /// <summary>
133         /// 构建SQL语句
134         /// </summary>
135         /// <param name="sb">StringBuilder保存Sql语句</param>
136         /// <param name="args">SQL参数</param>
137         /// <param name="lhs">SQL实例</param>
138         private void Build(StringBuilder sb, List<object> args, Sql lhs)
139         {
140             if (!string.IsNullOrEmpty(mInitialSQL))
141             {
142                 if (sb.Length > 0)
143                 {
144                     sb.Append("
");
145                 }
146                 var sql = ParametersHelper.ProcessParams(mInitialSQL, mInitialArgs, args);
147                 //累加where条件
148                 if (Is(lhs, "WHERE ") && Is(this, "WHERE "))
149                     sql = "AND " + sql.Substring(6);
150                 //累加Order by 条件
151                 if (Is(lhs, "ORDER BY ") && Is(this, "ORDER BY "))
152                     sql = ", " + sql.Substring(9);
153                 //累加set语句
154                 if (Is(lhs, "SET ") && Is(this, "SET "))
155                     sql = ", " + sql.Substring(4);
156 
157                 sb.Append(sql);
158             }
159             //处理当前实例的后继实例(递归)
160             if (mRHS != null)
161                 mRHS.Build(sb, args, this);
162         }
163 
164         /// <summary>
165         /// 向SQL实例添加set语句
166         /// </summary>
167         /// <param name="sql">update中的set语句,形如"{field} = {value}" </param>
168         /// <param name="args">可选参数</param>
169         /// <returns>当前SQL实例</returns>
170         public Sql Set(string sql, params object[] args)
171         {
172             return Append(new Sql("SET " + sql, args));
173         }
174 
175         /// <summary>
176         /// 向SQL实例添加where语句
177         /// </summary>
178         /// <param name="sql">where语句</param>
179         /// <param name="args">可选参数</param>
180         /// <returns>当前SQL实例</returns>
181         public Sql Where(string sql, params object[] args)
182         {
183             return Append(new Sql("WHERE (" + sql + ")", args));
184         }
185 
186         /// <summary>
187         /// 向SQL实例添加order by语句
188         /// </summary>
189         /// <param name="columns">待排序的列名称</param>
190         /// <returns>当前SQL实例</returns>
191         public Sql OrderBy(params object[] columns)
192         {
193             return Append(new Sql("ORDER BY " + string.Join(", ", (from x in columns select x.ToString()).ToArray())));
194         }
195 
196         /// <summary>
197         /// 向SQL实例添加select语句
198         /// </summary>
199         /// <param name="columns">查询的结果列名称</param>
200         /// <returns>当前SQL实例</returns>
201         public Sql Select(params object[] columns)
202         {
203             return Append(new Sql("SELECT " + string.Join(", ", (from x in columns select x.ToString()).ToArray())));
204         }
205 
206         /// <summary>
207         /// 向SQL实例添加查询表(多个表相互连接,数量指数级增长)
208         /// </summary>
209         /// <param name="tables">查询的表名称</param>
210         /// <returns>当前SQL实例</returns>
211         public Sql From(params object[] tables)
212         {
213             return Append(new Sql("FROM " + string.Join(", ", (from x in tables select x.ToString()).ToArray())));
214         }
215 
216         /// <summary>
217         /// 向SQL实例添加group by语句
218         /// </summary>
219         /// <param name="columns">待分组列名称</param>
220         /// <returns>当前SQL实例</returns>
221         public Sql GroupBy(params object[] columns)
222         {
223             return Append(new Sql("GROUP BY " + string.Join(", ", (from x in columns select x.ToString()).ToArray())));
224         }
225 
226         /// <summary>
227         /// 数据表连接
228         /// </summary>
229         /// <param name="joinType">连接类型</param>
230         /// <param name="table">待连接表名称</param>
231         /// <returns>SqlJoinClause实例</returns>
232         private SqlJoinClause Join(string joinType, string table)
233         {
234             return new SqlJoinClause(Append(new Sql(joinType + table)));
235         }
236 
237         /// <summary>
238         /// 数据表内连接
239         /// </summary>
240         /// <param name="table">待连接表名称</param>
241         /// <returns>SqlJoinClause实例</returns>
242         public SqlJoinClause InnerJoin(string table)
243         {
244             return Join("INNER JOIN ", table);
245         }
246 
247         /// <summary>
248         /// 数据表外连接
249         /// </summary>
250         /// <param name="table">待连接表名称</param>
251         /// <returns>SqlJoinClause实例</returns>
252         public SqlJoinClause LeftJoin(string table)
253         {
254             return Join("LEFT JOIN ", table);
255         }
256 
257         /// <summary>
258         /// 获取最终的SQL语句
259         /// </summary>
260         public override string ToString()
261         {
262             return SQL;
263         }
264     }
265 
266     /// <summary>
267     ///  SQL连接语句
268     /// </summary>
269     public class SqlJoinClause
270     {
271         /// <summary>
272         /// 待连接的SQL对象
273         /// </summary>
274         private readonly Sql _sql;
275 
276         /// <summary>
277         /// 构造函数
278         /// </summary>
279         /// <param name="sql"></param>
280         public SqlJoinClause(Sql sql)
281         {
282             _sql = sql;
283         }
284 
285         /// <summary>
286         /// 向SQL对象添加表连接条件
287         /// </summary>
288         /// <param name="onClause">表连接条件</param>
289         /// <param name="args">可选参数</param>
290         /// <returns>SQL对象</returns>
291         public Sql On(string onClause, params object[] args)
292         {
293             return _sql.Append("ON " + onClause, args);
294         }
295     }
原文地址:https://www.cnblogs.com/DreamOfLife/p/9155209.html