一个简单的ORM制作(SQL帮助类)
一个简单的ORM制作大概需要以下几个类:
- SQL执行类
- CURD操作类
- 其他酱油类
先从SQL执行类说起,可能会涉及数据库的迁移等问题,所以需要定义一个接口以方便迁移到其他数据库,
事务没提供命名,若需要命名可修改为可变参数,IHelper代码如下:
internal interface IHelper:IDisposable
{
int ExecuteQuery(string txt, IEnumerable<IDataParameter> ps, bool issp);//用于执行INSERT,UPDATE
object ExectueScalar(string tex, IEnumerable<IDataParameter> ps, bool issp);//执行COUT()
IDataReader ExectueReader(string tex, IEnumerable<IDataParameter> ps, bool issp);//执行SELECT
void BegTran();//开始事务
void RollBack();//回滚
void Commit();//提交
string CreateSql(string select, string tbname, string where, string orderby, int size, int index);//数据库的不同,产生的SQL也可能不同,所以必须提供不同的生成方案
IDataParameter Cp(string name, object value);//创建参数
string GetIdStr { get; }//获取INSERT产生ID的SQL代码,可能各个数据库不太相同
string ParStr(string name);//参数标示符,比如MSSQL:@NAME, MYSQL:?NAME,ODBC直接返回?无命名
}
以上为我个人能思考到的数据库差异和基础功能,若有其他请大家指教
通用MsSql帮助类代码如下:
class Mssql:IHelper
{
SqlCommand cmd;
SqlConnection con;
SqlTransaction tran;
internal Mssql(string constr)
{
con = new SqlConnection(constr);//test
cmd = new SqlCommand();
cmd.Connection = con;
}
void SetCmd(string str, IEnumerable<IDataParameter> ps, bool issp)
{
cmd.CommandText = str;
cmd.CommandType = issp ? CommandType.StoredProcedure : CommandType.Text;
cmd.Parameters.Clear();
foreach (var n in ps) { cmd.Parameters.Add(n); }
}
void CloseCon(){if (con.State == ConnectionState.Open) { con.Close(); }}
void OpenCon() { if (con.State == ConnectionState.Closed) { con.Open(); } }
int IHelper.ExecuteQuery(string str, IEnumerable<IDataParameter> ps, bool issp)
{
try
{
SetCmd(str, ps, issp);
OpenCon();
return cmd.ExecuteNonQuery();
}
finally{if(tran==null){CloseCon();}}
}
object IHelper.ExectueScalar(string str, IEnumerable<IDataParameter> ps, bool issp)
{
try
{
SetCmd(str, ps, issp);
OpenCon();
return cmd.ExecuteScalar();
}
finally{if(tran==null){CloseCon();}}
}
IDataReader IHelper.ExectueReader(string str, IEnumerable<IDataParameter> ps, bool issp)
{
SetCmd(str, ps, issp);
OpenCon();
return cmd.ExecuteReader(tran==null?CommandBehavior.CloseConnection:CommandBehavior.Default);
}
void IHelper.BegTran() { OpenCon(); tran = con.BeginTransaction(); cmd.Transaction = tran; }
void IHelper.Commit() { if (tran != null) { tran.Commit(); con.Close(); tran = null; } }
void IHelper.RollBack() { if (tran != null) { tran.Rollback(); con.Close(); tran = null; } }
string IHelper.CreateSql(string select, string tbname, string where, string orderby, int size, int index)
{
StringBuilder sb = new StringBuilder();//分页需要排序
sb.Append("SELECT ");
if (index == ) { sb.Append("TOP " + size + " "); }
sb.Append(select+" FROM ");
if (index > ){sb.Append("(SELECT ROW_NUMBER() OVER(" + (!string.IsNullOrEmpty(orderby)?"ORDER BY "+orderby:string.Empty) + ") AS ROWID," + select + " FROM ");}
sb.Append(tbname);
sb.Append(!string.IsNullOrEmpty(where) ? " WHERE " + where : string.Empty);
if (index > )
{
sb.Append(") AS " + tbname + " WHERE ROWID BETWEEN " + ((index - ) * size + ) + " AND " + size * index);
}
else
{
sb.Append(!string.IsNullOrEmpty(orderby) ? " ORDER BY " + orderby : string.Empty);
}
return sb.ToString();
}
IDataParameter IHelper.Cp(string name, object value) { return new SqlParameter(name, value); }
string IHelper.ParStr(string name) { return "@"+name;}
string IHelper.GetIdStr { get { return "SELECT @@IDENTITY"; } }
void IDisposable.Dispose()
{
CloseCon(); con.Dispose(); cmd.Dispose();
}
}
MsSql2005开始支持MARS,默认为关闭状态,也可以重写个支持MARS的Help,默认开启2个连接,一个用于查询一个用于无事物的执行,代码如下:
class MsMars:IHelper//自动开启mars,连接0为查询连接,连接1为执行无事务连接,事务连接为新连接
{
static SqlConnectionStringBuilder ssb;
static SqlConnection[] globalCon;
static object ck = new object();
public MsMars(string constr)
{
if (ssb == null)
{
ssb = new SqlConnectionStringBuilder(constr); ssb.MultipleActiveResultSets = true;
}
}
static SqlCommand GetCmd(int i = )
{
if (ssb == null) { throw new Exception("连接未初始化..."); }
if (i >=
) { return new SqlConnection(ssb.ConnectionString).CreateCommand(); }
if (globalCon != null) { return globalCon[i].CreateCommand(); }
lock (ck)
{
if (globalCon != null) { return globalCon[i].CreateCommand(); }
globalCon = new SqlConnection[] { new SqlConnection(ssb.ConnectionString), new SqlConnection(ssb.ConnectionString) };
globalCon[].Open(); globalCon[].Open();
}
return globalCon[i].CreateCommand();
}
SqlCommand cmd;
void SetCmd(string txt, IEnumerable<IDataParameter> ps, bool issp)
{
cmd.Parameters.Clear();
cmd.CommandText = txt;
cmd.CommandType = issp ? CommandType.StoredProcedure : CommandType.Text;
cmd.Parameters.AddRange(ps.ToArray());
}
public int ExecuteQuery(string txt, IEnumerable<IDataParameter> ps, bool issp)
{
cmd = cmd ?? GetCmd();
SetCmd(txt, ps, issp);
return cmd.ExecuteNonQuery();
}
public object ExectueScalar(string txt, IEnumerable<IDataParameter> ps, bool issp)
{
cmd = cmd ?? GetCmd();
SetCmd(txt, ps, issp);
return cmd.ExecuteScalar();
}
public IDataReader ExectueReader(string txt, IEnumerable<IDataParameter> ps, bool issp)
{
cmd =cmd??GetCmd();
SetCmd(txt, ps, issp);
return cmd.ExecuteReader();
}
public void BegTran()
{
cmd = GetCmd();
cmd.Transaction = cmd.Connection.BeginTransaction();
}
public void RollBack()
{
cmd.Transaction.Rollback();
cmd.Connection.Close();cmd.Dispose();
}
public void Commit()
{
cmd.Transaction.Commit();
cmd.Connection.Close(); cmd.Dispose();
}
public string CreateSql(string select, string tbname, string where, string orderby, int size, int index)...
public IDataParameter Cp(string name, object value)...
public string GetIdStr...
public string ParStr(string name)...
public void Dispose()...
以上代码本人测试通过,Help类只是ORM的一个起步,曾经看过EF的代码想学习下,但微软的代码实在是太高深(恶心),无从下手,所以我还是按照个人的做法来实现自己ORM,,下篇继续讲CURD操作类.读过觉得还不错请留下你的脚印,谢谢
一个简单的ORM制作(SQL帮助类)的更多相关文章
- 一个简单的ORM制作(CURD操作类)
SQL执行类 CURD操作类 其他酱油类 此篇是为上篇文章填坑的,不知道上篇砸过来的砖头够不够,不够的话请大家继续砸. CURD操作类负责将用户提供的条件转换为SQL语句,并提供给IHelper执行, ...
- Python 元类编程实现一个简单的 ORM
概述 什么是ORM? ORM全称"Object Relational Mapping",即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码 ...
- 分享一个简单的C#的通用DbHelper类(支持数据连接池)
每次新项目的时候,都要从头去找一遍数据库工具类.这里分享一个简单实用的C#的通用DbHelper工具类,支持数据连接池. 连接池配置 <connectionStrings> <add ...
- 一个简单的游标删除SQL SERVER表
use databaseName declare @tblname char(100) declare @sql char(5000) declare table_cursor cursor for ...
- Mybatis_1(认识)一个简单的HelloWorld
1. 介绍: MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索. MyBatis可以使用简单的XM ...
- 基于JUnit3.8的一个简单的测试程序
实现一个简单的计算 注:目标类和测试类要放在同一包下, JUnit单元测试基础要点 目标类:Calculator.java package com.junit3_8; public class Cal ...
- python-元类和使用元类实现简单的ORM
元类 面向对象中,对象是类的实例,即对象是通过类创建出来的,在python中,一切皆对象,同样,类也是一个对象,叫做类对象,只是这个类对象拥有创建其子对象(实例对象)的能力.既然类是对象,那么类是通过 ...
- C#-用Winform制作一个简单的密码管理工具
为什么要做? 首先是为了练习一下c#. 想必大家都有过记不起某个平台的账号密码的经历,那种感受着实令人抓狂.那这么多账号密码根本记不住!我之前用python写过一个超级简单(连账号信息都写在代码里那种 ...
- 实例学习SSIS(一)--制作一个简单的ETL包
原文:实例学习SSIS(一)--制作一个简单的ETL包 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SS ...
随机推荐
- Careercup - Facebook面试题 - 5729456584916992
2014-05-02 00:59 题目链接 原题: Given a normal binary tree, write a function to serialize the tree into a ...
- mysql存储过程出现OUT or INOUT argument 10 for routine
OUT or INOUT argument 10 for routine * is not a variable or NEW pseudo-variable 我查网上很多出现在call的时候没有添加 ...
- [转载]ASP.NET对路径"xxxxx"的访问被拒绝的解决方法小结
异常详细信息: System.UnauthorizedAccessException: 对路径“D:/temp1/MyTest.txt”的访问被拒绝 在windows 2003下,在运行web ...
- C#调用大漠插件的方法和实例
大漠插件是一个很不错的东西,在按键精灵和易语言里面用得很多,可以后台找图找字,写游戏自动脚本用得特别多.前面写一个微信的自动脚本,查了一些资料,易语言不太熟悉,按键精灵功能上可能不好实现,就找了些资料 ...
- epoll 知识总结
poll/select/epoll 对比 http://www.cnblogs.com/apprentice89/p/3234677.html ---有待继续学习 http://blog.chi ...
- 高性能网络编程1----accept建立连接
转 http://taohui.org.cn/tcpperf1.html 陶辉 taohui.org.cn 回到应用层,往往只需要调用类似于accept的API就可以建立TCP连接.建立连接的流程大 ...
- uva 10651
DP 主要是位运算的运用 因为只有12位 用一个数字代表一种装态 记忆化搜索 节约时间 /***************************************************** ...
- Test a ; vs Test a( ) ;
一. Test a(); Test a; //前提声明了Test类 前者声明一个返回值为Test,名为a的函数,后者声明了Test类的一个对象(把Test当成int) struct Test{ ...
- POJ3468 A Simple Problem With Integers 树状数组 区间更新区间询问
今天学了很多关于树状数组的技巧.一个是利用树状数组可以简单的实现段更新,点询问(二维的段更新点询问也可以),每次修改只需要修改2个角或者4个角就可以了,另外一个技巧就是这题,原本用线段树做,现在可以用 ...
- C#扩展方法入门
扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的. 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀. 仅当你使用 using 指令将命名空间显式导入到源代码 ...