适用于关系型数据库的抽象工厂的数据库访问类

适用于SQLite、Access、MySQL、MSSQLServer、Oracle这类关系型数据库,不适于非关系型数据库,例如MongoDB。

下面是代码:

  1 using System;

  2 using System.Configuration;

  3 using System.Data;

  4 using System.Data.Common;

  5 using System.Data.SQLite;

  6 

  7 namespace WinFormTest

  8 {

  9     public static class DbHelperSQL

 10     {

 11         private static readonly object Obj4Lock = new object();

 12         private static readonly string ConnectionString = ConfigurationManager.

 13             ConnectionStrings["ConnectionString"].ConnectionString;

 14 

 15         /// <summary>

 16         ///  程序每次运行都只创建一个工厂

 17         /// </summary>

 18         private static DbProviderFactory DBProviderFactory

 19         {

 20             get

 21             {

 22                 var providerFactoryString = ConfigurationManager.ConnectionStrings["ConnectionString"].ProviderName;

 23                 if (providerFactoryString == "System.Data.SQLite")

 24                 {

 25                     return SQLiteFactory.Instance;

 26                 }

 27 

 28                 var dbProviderFactory = DbProviderFactories.GetFactory(providerFactoryString);

 29                 if (dbProviderFactory == null)

 30                 {

 31                     throw new Exception("dbProviderFactory==null");

 32                 }

 33 

 34                 return dbProviderFactory;

 35             }

 36         }

 37 

 38 

 39         public static int ExecuteNonQuery(string commandText, bool isStoredProcedure)

 40         {

 41             if (commandText == null)

 42             {

 43                 throw new ArgumentNullException("commandText");

 44             }

 45 

 46             int result;

 47 

 48             lock (Obj4Lock)

 49             {

 50                 using (var connection = CreateConnection())

 51                 {

 52                     using (var transaction = CreateTransaction(connection))

 53                     {

 54                         using (var command = CreateCommand(commandText, isStoredProcedure, connection, transaction))

 55                         {

 56                             try

 57                             {

 58                                 result = command.ExecuteNonQuery();

 59                                 command.Parameters.Clear();

 60                                 transaction.Commit();

 61                             }

 62                             catch

 63                             {

 64                                 transaction.Rollback();

 65                                 return 0;

 66                             }

 67                         }

 68                     }

 69                 }

 70             }

 71 

 72             return result;

 73         }

 74 

 75         public static object ExecuteScalar(string commandText, bool isStoredProcedure)

 76         {

 77             if (commandText == null)

 78             {

 79                 throw new ArgumentNullException("commandText");

 80             }

 81 

 82             object result;

 83 

 84             lock (Obj4Lock)

 85             {

 86                 using (var connection = CreateConnection())

 87                 {

 88                     using (var transaction = CreateTransaction(connection))

 89                     {

 90                         using (var command = CreateCommand(commandText, isStoredProcedure, connection, transaction))

 91                         {

 92                             try

 93                             {

 94                                 result = command.ExecuteScalar();

 95                                 command.Parameters.Clear();

 96                                 transaction.Commit();

 97                             }

 98                             catch

 99                             {

100                                 transaction.Rollback();

101                                 return null;

102                             }

103                         }

104                     }

105                 }

106             }

107 

108             return result;

109         }

110 

111         public static IDataReader ExecuteReader(string commandText, bool isStoredProcedure)

112         {

113             if (commandText == null)

114             {

115                 throw new ArgumentNullException("commandText");

116             }

117 

118             lock (Obj4Lock)

119             {

120                 var connection = CreateConnection();

121 

122                 var command = CreateCommand(commandText, isStoredProcedure, connection, null);

123 

124                 try

125                 {

126                     var myReader = command.ExecuteReader(CommandBehavior.CloseConnection);

127                     command.Parameters.Clear();

128                     return myReader;

129                 }

130                 catch

131                 {

132                     connection.Close();

133                     throw;

134                 }

135             }

136         }

137 

138         public static DataSet Query(string commandText, bool isStoredProcedure)

139         {

140             if (commandText == null)

141             {

142                 throw new ArgumentNullException("commandText");

143             }

144 

145             var dataSet = new DataSet();

146 

147             lock (Obj4Lock)

148             {

149                 using (var connection = CreateConnection())

150                 {

151                     using (var transaction = CreateTransaction(connection))

152                     {

153                         using (var command = CreateCommand(commandText, isStoredProcedure, connection, transaction))

154                         {

155                             using (var dataAdapter = DBProviderFactory.CreateDataAdapter())

156                             {

157                                 if (dataAdapter == null)

158                                 {

159                                     throw new ArgumentNullException("commandText");

160                                 }

161 

162                                 try

163                                 {

164                                     dataAdapter.Fill(dataSet, "dataSet");

165                                     command.Parameters.Clear();

166                                     transaction.Commit();

167                                 }

168                                 catch

169                                 {

170                                     transaction.Rollback();

171                                     return null;

172                                 }

173                             }

174                         }

175                     }

176                 }

177             }

178 

179             return dataSet;

180         }

181 

182 

183         private static IDbConnection CreateConnection()

184         {

185             IDbConnection connection = DBProviderFactory.CreateConnection();

186             if (connection == null)

187             {

188                 throw new Exception("connection == null");

189             }

190 

191             connection.ConnectionString = ConnectionString;

192 

193             if (connection.State != ConnectionState.Open)

194             {

195                 connection.Open();

196             }

197 

198             return connection;

199         }

200 

201         private static IDbTransaction CreateTransaction(IDbConnection connection)

202         {

203             var transaction = connection.BeginTransaction();

204             if (transaction == null)

205             {

206                 throw new ArgumentNullException("connection");

207             }

208             return transaction;

209         }

210 

211         private static IDbCommand CreateCommand(string commandText, bool isStoredProcedure,

212             IDbConnection connection, IDbTransaction transaction)

213         {

214             IDbCommand command = DBProviderFactory.CreateCommand();

215             if (command == null)

216             {

217                 throw new Exception("command == null");

218             }

219 

220             command.Connection = connection;

221             command.CommandType = isStoredProcedure ? CommandType.StoredProcedure : CommandType.Text;

222             command.CommandText = commandText;

223             command.Transaction = transaction;

224 

225             return command;

226         }

227     }

228 }

 

解释:

1、Obj4Lock用于锁定代码块,保证在多线程程序中,只有一个数据库连接存在。

2、外部接口只有ExecuteNonQuery、ExecuteScalar、ExecuteReader、Query四个方法,可以使用存储过程和事务。

3、为什么不用参数化查询?一是因为面向接口编程的原因,程序中不能使用具体数据库相关的参数对象,只能使用IDbParameter和DbParameter,这两个是接口和抽象类,不能够实例化,可以写在工厂中,但是没法使用。二是我做的程序中不需要参数化查询。

4、代码可读性良好,不必注释了。

下面是配置文件:

1 <?xml version="1.0" encoding="utf-8" ?>

2 <configuration>

3   <connectionStrings>

4     <!--<add name="ConnectionString" connectionString="Data Source=Test" providerName="System.Data.SQLite"/>-->

5     <!--<add name="ConnectionString" connectionString="Provider=Microsoft.ACE.OLEDB.12.0; Data Source=TestAccess.accdb" providerName="System.Data.OleDb"/>-->

6     <add name="ConnectionString" connectionString="server=127.0.0.1;database=testDB;uid=root;pwd=123456" providerName="MySql.Data.MySqlClient"/>

7   </connectionStrings>

8 </configuration>

通过更改配置文件,就可以实现对数据库种类的屏蔽了。

下面是用了抽象工厂的数据库访问类和普通数据库访问类的效率差异:

数据库

类型

2

5

10

20

50

100

200

SQLite

文件

0.197s

0.285s

0.547s

1.099s

2.509s

5.632s

11.386s

SQLite(抽象工厂)

文件

0.246s

0.362s

0.499s

1.191s

2.539s

6.692s

10.464s

Access

文件

0.199s

0.280s

0.521s

1.071s

2.604s

5.320s

10.760s

Access(抽象工厂)

文件

0.363s

0.510s

0.780s

1.326s

2.805s

5.569s

10.648s

MySql

服务器

0.217s

0.106s

0.226s

0.331s

0.952s

1.545s

2.666s

MySql(抽象工厂)

服务器

0.310s

0.323s

0.403s

0.545s

0.942s

1.623s

2.746s

表中的数字是线程数,每个线程只执行一条语句。

All Comments are Welcome.

你可能感兴趣的:(抽象工厂)