一个通用数据库操作组件DBUtil(c#)、支持SqlServer、Oracle、Mysql、postgres、SQLITE

这是一个.net下操作数据库(结构数据库)的工具类,支持sqlserver、oracle、mysql、postgres、sqlite、access等常见数据库。

注意:它并不是一个orm工具(常见的orm框架如:EF、Dapper等)。

2.1 引入DBUtil依赖

1. 首先打开vs(推荐vs2019),新建控制台应用程序(.net framework)

2. 添加依赖方法1:打开工具>NuGet包管理器>程序包管理器控制台,输入:

Install-Package DBUtil -Version 1.0.0

3. 添加依赖方法2:使用可视化的nuget管理窗口搜索“DBUtil”,选择安装即可!

2.2 准备数据库

自行准备吧。

2.3 增删改查代码

        DBUtil.IDbAccess iDb = DBUtil.IDBFactory.CreateIDB("Data Source=.;Initial Catalog=JACKOA;User ID=sa;Password=xx;","SQLSERVER");        Console.WriteLine(iDb.GetFirstColumnString("select Name from SysUser"));        Console.WriteLine(iDb.ExecuteSql("updatetest set CaseNo=CaseNo+'e'"));        Console.WriteLine(iDb.ExecuteSql("update test set CaseNo=@case",newIDataParameter[] { iDb.CreatePara("case","123") }));          Hashtable ht = newSystem.Collections.Hashtable();     ht.Add("CaseNo", "456");     ht.Add("Name", "ji");     Console.WriteLine(iDb.AddData("test",ht));          Hashtable ht2 = newSystem.Collections.Hashtable();     ht2.Add("Name", "jiko");     Console.WriteLine(iDb.UpdateData("test",ht2," and CaseNo='123'"));          Console.WriteLine(iDb.DeleteTableRow("test"," and id=11"));            Console.WriteLine(iDb.GetDataSet("select * from sysuser").Tables[0].Rows.Count);

    在这个组件设计中,所有的数据库操作方法都被集成在了一个对象上:IDbAccess。它是一个接口,定义了公共的数据库访问方法,如:增删改查、事务控制等。具体的实现由SqlServerIDbAccess、MySqlIDbAccess、PostgreSqlIDbAccess、OracleIDbAccess、AccessIDbAccess、SQLiteIDbAccess等实现,它们分别对应着一种数据库。

    在所有的数据库操作之前,都必须先创建IDbAccess对象,创建的方法如下:

DBUtil.IDbAccess iDb = DBUtil.IDBFactory.CreateIDB("Data Source=.;Initial Catalog=JACKOA;User ID=sa;Password=xx;","SQLSERVER");

你所需的参数有两个:

1. 数据库的类型字符串

    SQLSERVER、ORACLE、MYSQL、POSTGRESQL、ACCESS、SQLITE

2. 数据库连接字符串

参考以下示例:

SQLSERVER: Data Source=.;Initial Catalog=JACKOA;User ID=sa;Password=xx;
ORACLE: Data Source=ORCLmyvm2;Password=sys123;User ID=sys;DBA Privilege=SYSDBA;
MYSQL: Data Source=localhost;Initial Catalog=test;User ID=root;Password=xxxx;
POSTGRESQL: Server=localhost;Port=5432;UserId=postgres;Password=xxxx;Database=test
ACCESS: Provider=Microsoft.Jet.OLEDB.4.0;Data Source=G:\work\Multiplan.mdb;
ACCESS: Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Administrator\Desktop\demo.accdb;
 SQLITE: Data Source=f:\demo.db;

3. sqlite数据库

sqlite数据库存储是单个文件存储的,所以在访问之前你需要先创建它,参照如下代码:

DBUtil.IDBFactory.CreateSQLiteDB("d:\\demo.db");string str = DBUtil.IDBFactory.GetSQLiteConnectionString("d:\\demo.db");DBUtil.IDbAccess iDb = DBUtil.IDBFactory.CreateIDB(str, "SQLITE");iDb.ExecuteSql(@"create table test(id int primary key,name varchar(50));insert into test values(1,'张三');insert into test values(2,'李四');");string name = iDb.GetFirstColumnString("select name from test");Console.WriteLine(name);

四、增删改查方法

4.1 增加数据(AddData)

DBUtil.IDbAccess iDb = DBUtil.IDBFactory.CreateIDB(@"Data Source=d:\demo.db;", "SQLITE");iDb.ExecuteSql(@"create table test2(id int primary key,name varchar(50),createtime timestamp,largefield blob)");Hashtable ht = new Hashtable(); ht.Add("id", 1);ht.Add("name", "李四"); ht.Add("createtime", DateTime.Now);ht.Add("largefield", System.Text.Encoding.UTF8.GetBytes("我的密码是:xxxxxx"));iDb.AddData("test2", ht);Console.WriteLine(iDb.GetFirstColumnString("select name from test2"));Console.WriteLine(iDb.GetFirstColumnString("select createtime from test2"));            Console.WriteLine(System.Text.Encoding.UTF8.GetString(iDb.GetFirstColumn("select largefield from test2") as byte[]));Console.WriteLine("ok");Console.ReadLine();

4.2 删除数据(DeleteTableRow)

iDb.DeleteTableRow("test2", "and id=1");

4.3 更新数据(UpdateData)

Hashtable ht = new Hashtable();ht.Add("name", "王五");iDb.UpdateData("test2", ht, "and id=1");

4.4 更新或添加数据(UpdateOrAdd)

Hashtable ht = new Hashtable();ht.Add("id", 1);ht.Add("name", "王五");iDb.UpdateOrAdd("test2", ht, "and id=1");

4.5 查询数据

4.5.1 获取第一个值

string str=iDb.GetFirstColumnString("select name from test2");object obj= iDb.GetFirstColumnString("select largefield  from test2");

4.5.2 获取表

DataTable dt = iDb.GetDataTable("select * from test2");DataSet ds = iDb.GetDataSet("select * from test2;select * from test2;");

4.6 参数化sql语句

iDbAccess的大部分方法都是直接参数化查询的,参照如下代码:

DataTable dt = iDb.GetDataTable(string.Format("select * from test2 where name like {0}", iDb.paraPrefix + "name"), new IDbDataParameter[] {      iDb.CreatePara("name","%小%") });

每个数据库的分页方法不同,比如:

sqlserver:top分页、row_number() over()分页、fetch分页

mysql:limit分页

等等。。。

在这个组件中设计为:根据指定的查询语句和分页参数生成分页的查询语句,参照以下代码:

DBUtil.IDbAccess iDb = DBUtil.IDBFactory.CreateIDB(@"Data Source=localhost;Initial Catalog=imgserver2;User ID=root;Password=123456;", "MYSQL");string selectSql = "select * from test2";string orderSql = "order by id desc";int pageSize = 10;int pageIndex = 1;string sqlFinal = iDb.GetSqlForPageSize(selectSql, orderSql, pageSize, pageIndex);Console.WriteLine(sqlFinal);
iDb.BeginTrans();IDbTransaction tran= iDb.tran;iDb.Commit();iDb.Rollback();bool b = iDb.IsTran;
DBUtil.IDbAccess iDb = DBUtil.IDBFactory.CreateIDB(@"Data Source=localhost;Initial Catalog=imgserver2;User ID=root;Password=1234567;", "MYSQL");DBUtil.Result res = iDb.OpenTest();if (res.Success){    Console.WriteLine("连接成功!");}else{    Console.WriteLine("连接失败:" + res.Data);}Console.WriteLine("ok");Console.ReadLine();

默认情况下,每进行一次数据库的操作都会打开和关闭数据库。在密集的操作下这种方法并不推荐。

可以通过IsKeepConnect 属性使数据的链接一直保持

iDb.IsKeepConnect = true;
string filter=iDb.GetDateFilter("end", "2016-12-1", "2017-01-01", true, false);
bool b=iDb.JudgeTableOrViewExist("test");bool b2 = iDb.JudgeColumnExist("test", "id");

11.1 说明

数据库表的ID的生成是一个常见的问题,常见的有表字段设置为自增、设为序列、程序控制ID生成。下面分别说说这三种模式:

1)  表字段自增:在sqlserver中有个致命的缺陷就是一旦遇到数据迁移,那么这些ID都将重新生成,如果其他的表引用了这个 ID,后果可想而知。在mysql中有办法解决这个问题,但是这种办法最根本的缺陷在于:“不能在数据插入到表之前获取对应的ID”,试想一下:如果你在插入数据之前还要用到这个ID做其他的工作该怎么办?

2) 序列法:在oracle中可以新建一个序列控制ID的生成(sqlserver中好像也开始支持了),这种方法其实已经解决了绝大部分问题了,但是在每次生成ID之前你还是需要访问一遍数据库,如果需要批量生成的时候性能肯定受影响(不知道序列支不支持批量生成)。

3) 程序控制ID生成法:这个组件是用的这种方法生成ID的,它可以解决上述提到的问题。它的原理是:

    你在程序中通过指定表名和字段名来获取ID,程序中进行判断当前内存中是否缓存了这个ID,如果缓存了ID的话就直接自增并返回,如果没有缓存ID的话就通过表名和字段名去数据库里面去查找最大的ID,然后自增并返回。

    优点:

        1. ID可以随时生成,不用非得向表中插入数据。

        2. 在批量生成ID时,性能很高(完全碾压从数据库生成的)

        3. 可以针对一个表的多个字段进行生成(一般用不到)

        4. 兼容各种数据库,你不用再为ID配置各种生成策略

    缺点:

        1. 因为ID的生成缓存到了程序中,所以针对一张表必须保证只有一个服务器会进行ID的生成,否则会出现重复的ID

    注意:

        有人可能已经注意到问题,分布式的ID是怎么生成(1个数据库,多个服务器)?这里我提供一个思路,但是这个组件中并没有实现:针对不同的服务器预先设置ID的前缀,比如服务器A的ID 生成从1开始,服务器B的ID 生成从100 0000开始,这样就不会重叠了。如果担心数据量太大,那么你就不能在用int类型的ID了,你应该使用字符串唯一编号。这个组件中也实现了唯一编号的生成控制,原理和ID一样的都是在程序中缓存,只不过使用的时候要配置编号生成的规则...

11.2 扩展说明

    这个组件默认使用的生成控制器是SimpleIDSNOManager,如果需要扩展(比如使用redis控制生成等)可以自定义实现IDSNOManager,并在应用程序启动时书写:IDBFactory. IDSNOManage= new 自定义实现();

11.3 使用方法

  11.3.1 ID操作

          int id = iDb.IDSNOManager.NewID(iDb, "test", "id");          int id2 = iDb.IDSNOManager.NewIDForce(iDb, "test", "id");          iDb.IDSNOManager.ResetID("test", "id", 1);          iDb.IDSNOManager.ShowCurrentIDs(null,null);

  11.3.2 自动编号操作

         iDb.IDSNOManager.NewSNO(iDb, "test", "caseno", new List<SerialChunk>(){           new SerialChunk("prefix_GWFW","Text[GWFW][4]"),           new SerialChunk("RiQiCtr","DateTime[yyyyMMdd][8][incycle]"),           new SerialChunk("SerialNo","SerialNo[1,1,5,,day]")      });       List<string[]> li = iDb.IDSNOManager.ShowCurrentSNOs(null, null, null);       List<SerialChunk> li = new List<SerialChunk>();    li.Add(new SerialChunk(“prefix_GWFW”,null));    li.Add(new SerialChunk(“RiQiCtr”,null));    li.Add(new SerialChunk(“SerialNo”,null));    iDb.IDSNOManager.ResetSNO(tableName, colName, li, null);    iDb.IDSNOManager.NewSNO(iDb, "test", "caseno", new List<SerialChunk>(){    new SerialChunk("prefix_GWFW","Text[GWFW][4]"),    new SerialChunk("RiQiCtr","DateTime[yyyyMMdd][8][incycle]"),    new SerialChunk("SerialNo","SerialNo[1,1,5,,day]")    });       List<string[]> li = iDb.IDSNOManager.ShowCurrentSNOs(null, null, null);       List<SerialChunk> li = new List<SerialChunk>();    li.Add(new SerialChunk(“prefix_GWFW”,null));    li.Add(new SerialChunk(“RiQiCtr”,null));    li.Add(new SerialChunk(“SerialNo”,null));    iDb.IDSNOManager.ResetSNO(tableName, colName, li, null);

640?wx_fmt=png


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Educational Codeforces Round 37 (Rated for Div. 2) E. Connected Components? 暴力 + 补图的遍历

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; n≤2e5,m≤2e5n\le2e5,m\le2e5n≤2e5,m≤2e5。 思路&#xff1a; 这是题是我上个题的一部分&#xff0c;算是个小知识点&#xff0c;暴力能过。 直接维护一个setsetset&#xff0c;让后遍历所有点&#xff…

初探System.Threading.Channels

。System.Threading.Channels是.Net Core基础类库中实现的一个多线程相关的库&#xff0c;专门处理数据流相关的操作&#xff0c;用来在生产者和订阅者之间传递数据&#xff08;不知道可不可以理解为线程间传递数据&#xff0c;我把它类比成了Go语言中的Channel&#xff09;&am…

Codeforces Round #715 (Div. 1) B. Almost Sorted 找规律

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 找规律yydsyydsyyds。 一看没什么想法&#xff0c;所以打了个表&#xff0c;好家伙&#xff0c;不打不知道&#xff0c;一打不得了&#xff0c;下面是n6n6n6的符合要求的情况&#xff1a; …

SQL Server之索引解析(二)

、堆表堆表通过IAM连接一起&#xff0c;查询时全表扫描。1、1 非聚集索引结构叶子节点数据结构&#xff1a;行数据结构Rid&#xff08;8字节&#xff09;中间节点数据结构&#xff1a; &#xff08;非聚集非唯一索引&#xff09;行数据结构Page&#xff08;4&#xff09;2 Rid&…

纠正一个错误,分布式系统关注点第17篇

这里是Z哥的个人公众号每周五早8点 按时送达当然了&#xff0c;也会时不时加个餐&#xff5e;我的第「78」篇原创敬上今天来加个餐&#xff0c;紧急纠正一个错误。先和大家说一声抱歉&#xff1a;D昨晚睡觉前&#xff0c;惯例打开「订阅号助手」回复一些留言。有一位小伙伴提了…

【NOI2016】国王饮水记【贪心】【斜率优化】【决策单调性】

传送门 首先比h1h_1h1​小的肯定没用&#xff0c;直接无视 然后考虑合并的顺序 ①在无限制的情况下&#xff0c;合并多个不如一个一个合并 a<b<ca<b<ca<b<c时&#xff0c;ab2c2>abc3{{ab \over 2}c\over 2}>{{abc}\over 3}22ab​c​>3abc​ ②先…

CF946D Timetable 背包dp + 思维转换

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; n,m,k≤500n,m,k\le500n,m,k≤500 思路&#xff1a; 将其转换成背包的模型&#xff0c;就可以想出来一个很明显的dpdpdp状态&#xff1a;f[i][j]f[i][j]f[i][j]表示前iii行花费了jjj的最小代价&#xff0c;…

.NET开发框架(三)-高可用服务器端设计

我们对框架功能作了简述&#xff0c;演示视频请点击 这里查看 &#xff0c;本章节&#xff0c;我们专门讲解一下&#xff0c;如何在Window服务器下&#xff0c;设计高可用的框架。我们的框架设计采用的是Window版本的服务端设计&#xff1a;整体框架图如下&#xff0c;为什么我…

P1537 弹珠 背包可行性dp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 疯狂水文章。 这个很明显是个背包&#xff0c;我们开一个布尔数组&#xff0c;之后枚举每组的个数&#xff0c;让后枚举1−61-61−6&#xff0c;再枚举容量kkk&#xff0c;注意顺序不能错了…

.NET Core 3.0中的WinForms创建集中式拉取请求中心

Windows 窗体&#xff08;或简称 WinForms&#xff09;&#xff0c;多年来被用于开发具有丰富和交互式界面的基于 Windows 的强大应用程序。各类企业对这些桌面应用程序的投入量非常巨大&#xff0c;每月有大约 240 万开发人员使用 Visual Studio 创建桌面式应用。利用和扩展现…

CF296B dp\容斥

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; n≤1e5n\le1e5n≤1e5 思路&#xff1a; 求方案数基本就是考虑dpdpdp了&#xff0c;看到nnn这么大可以考虑一下分情况讨论的dpdpdp状态。 设f[i][j]f[i][j]f[i][j]表示到了第iii个&#xff0c;状态为jjj的方…

asp.net core 自定义异常处理中间件

Intro在 asp.net core 中全局异常处理&#xff0c;有时候可能不能满足我们的需要&#xff0c;可能就需要自己自定义一个中间件处理了&#xff0c;最近遇到一个问题&#xff0c;有一些异常&#xff0c;不希望记录错误日志&#xff0c;目前主要是用户请求取消导致的 TaskCanceled…

CF786B Legacy 线段树优化建图

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 实现如下连边后跑最短路。 思路&#xff1a; 优化建图板子题&#xff0c;优化思路就是将区间分割成若干个线段树上的线段&#xff0c;与线段树分治有点类似&#xff0c;由于有点向区间也有区间向点的边&a…

【ZJOI2015】幻想乡 Wi-Fi 搭建计划【几何】【贪心】【dp】

传送门 题意&#xff1a;一个x∈(−∞,∞),y∈[0,R]x\in(-\infin,\infin),y\in[0,R]x∈(−∞,∞),y∈[0,R]的矩形中有nnn个点&#xff0c;矩形外有mmm个半径均为RRR的圆&#xff0c;有独立的代价cic_ici​。求覆盖最多的点所需的最小代价。 n,m≤100n,m\leq100n,m≤100 显然先…

.NET架构开发应知应会

.NET程序是基于.NET framework、.NET Core、Mono、UWP【.NET实现】开发和运行的 &#xff0c;定义以上【.NET实现】的标准规范称为.NET StandardL1&#xff1a;.NET Standard.NET标准是一组API集合&#xff0c;由上层三种【.NET实现】的Basic Class Library实现&#xff0c;更正…

几个冷门字符串算法的学习笔记(最小表示法,exKMP,Lyndon Word)

所有下标均从1开始 最小表示法 给定一个串&#xff0c;求字典序最小的循环同构。 我们把串复制一遍接在后面&#xff0c;然后求出[1,N][1,N][1,N]开始的长为NNN的子串中最小的 先设i1,j2i1,j2i1,j2 然后暴力找出iii和jjj往后匹配的第一个不同的位置&#xff0c;记为ikikik…

.NET Core IdentityServer4实战 第Ⅴ章-单点登录

OiDc可以说是OAuth的改造版&#xff0c;在最初的OAuth中&#xff0c;我们需要先请求一下认证服务器获取下Access_token&#xff0c;然后根据Access_token去Get资源服务器, 况且OAuth1 和 2 完全不兼容&#xff0c;易用性差&#xff0c;而OIDC可以在登陆的时候就把信息返回给你&…

【CF594E】Cutting the Line 【贪心】【Lyndon Word】【扩展kmp】

传送门 题意&#xff1a;给一个字符串SSS和正整数kkk&#xff0c;将SSS分成最多kkk段&#xff0c;每段不变或翻转&#xff0c;使得最后的字典序最小。 ∣S∣≤5106|S|\leq5\times10^6∣S∣≤5106 发现不翻转可以看成拆成若干单字符分别翻转&#xff0c;所以先分析一下必须翻转…

一份好的工作总结才能帮你升职加薪

这里是Z哥的个人公众号每周五早8点 按时送达当然了&#xff0c;也会时不时加个餐&#xff5e;我的第「79」篇原创敬上最近有点忙&#xff0c;搬出之前攒的一篇文章来应急一下。一篇能助你挣更多钱的文章。好了&#xff0c;下面开始。我的读者们大部分是互联网行业的&#xff0c…

腾讯开源软件镜像站上线

腾讯开源软件镜像站(Tencent Open Source Mirror Site)已于近日上线&#xff0c;其官方名称为「腾讯云软件源」&#xff0c;由腾讯云提供支持。官方表示搭建此开源镜像站的目的在于宣传自由软件的价值&#xff0c;提高自由软件社区文化氛围&#xff0c;推广自由软件在国内的应用…