一个简单的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 ...
随机推荐
- js eval()执行传参函数的写法
.cs public class Message<T> { // 数据总数 public int? Total { get; set; } // 关键数据 public List<T ...
- 在ubuntu16.04 下安装haproxy 1.5.11 做tcp负载均衡
由于haproxy需要FQ下载,所以从csdn下载了较为新版的haproxy1.5.11,安装过程如下: 1. 解压haproxy-1.5.11.tar.gz : tar xzvf haproxy-1 ...
- 2432: [Noi2011]兔农 - BZOJ
Description 农夫栋栋近年收入不景气,正在他发愁如何能多赚点钱时,他听到隔壁的小朋友在讨论兔子繁殖的问题. 问题是这样的:第一个月初有一对刚出生的小兔子,经过两个月长大后,这对兔子从第三个月 ...
- PE文件结构详解(三)PE导出表
上篇文章 PE文件结构详解(二)可执行文件头 的结尾出现了一个大数组,这个数组中的每一项都是一个特定的结构,通过函数获取数组中的项可以用RtlImageDirectoryEntryToData函数,D ...
- PHP之set_error_handler()函数讲解
定义和用法 set_error_handler() 函数设置用户自定义的错误处理函数. 该函数用于创建运行时期间的用户自己的错误处理方法. 该函数会返回旧的错误处理程序,若失败,则返回 null. 语 ...
- JsRender系列demo(9)自定义函数
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- Android 一个Activity保存它自己的实例
一个Activity保存他自己的实例的作用是,在其他Activity中可以方便的调用该Activity里的方法. 我们可以使用一个静态的变量保存当前Activity的实例,并将其标志为private访 ...
- Eclipse 编译错误 Access restriction:The type *** is not accessible due to restriction on... 解决方案
报错: Access restriction:The type JPEGCodec is not accessible due to restriction on required library C ...
- hdu1022 Train Problem I
http://acm.hdu.edu.cn/showproblem.php?pid=1022 #include<iostream> #include<stdio.h> #inc ...
- 表单验证插件——validate
表单验证插件——validate 该插件自带包含必填.数字.URL在内容的验证规则,即时显示异常信息,此外,还允许自定义验证规则,插件调用方法如下: $(form).validate({options ...