三层架构浅析

    

“三层架构”中的三层是指:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)

表现层:通俗讲就是展现给用户的界面,即用户在使用一个系统时候他的所见所得。

位于最外层(最上层),离用户最近。用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。

业务逻辑层:针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。

负责处理用户输入的信息,或者是将这些信息发送给数据访问层进行保存,或者是调用数据访问层中的函数再次读出这些数据。中间业务层也可以包括一些对“商业逻辑”描述代码在里面

数据访问层:该层所做事务直接操作数据库,正对数据的增添、删除、修改、更新、查找。

仅实现对数据的保存和读取操作。数据访问,可以访问数据库系统、二进制文件、文本文档或是XML文档



优缺点:

    优点:

  1、开发人员可以只关注整个结构中的其中某一层;

  2、可以很容易的用新的实现来替换原有层次的实现;

  3、可以降低层与层之间的依赖;

  4、有利于标准化;

  5、利于各层逻辑的复用。

  缺点:

    1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。

  2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。

简单的三层如下所示:

数据访问层:DAL

sqlhelp类:

public class SqlHelp
{
private SqlConnection con;//连接对象
private SqlCommand cmd;//操作对象
private SqlDataAdapter sda;//适配器(填充和更新数据库的一组数据命令和一个数据库连接)
private SqlDataReader reader;//读取行
private DataSet ds;//数据集

/// <summary>
/// 初始化连接对象
/// </summary>
public void Connection()
{
try
{
con
= new SqlConnection(SqlConn.Str);
con.Open();
}
catch (Exception)
{
///
}
}

public int Command(string strsql)
{
try
{
Connection();
//打开连接
cmd = new SqlCommand(strsql, con);
int count = cmd.ExecuteNonQuery();//返回受影响的行数
return count;
}
catch (Exception)
{
return -1;
}
finally
{
con.Dispose();
}
}

/// <summary>
/// 返回一个数据集合
/// </summary>
/// <param name="strsql">数据库操作语句</param>
/// <returns>数据集</returns>
public DataSet ReturnDs(string strsql, string table)
{
try
{
Connection();
sda
= new SqlDataAdapter(strsql, con);
ds
= new DataSet();
sda.Fill(ds, table);
return ds;
}
catch (Exception)
{
return null;
}
finally
{
con.Dispose();
}
}

/// <summary>
/// 返回一个只进的读取流
/// </summary>
/// <param name="strsql">数据库操作语句</param>
/// <returns>返回一行数据</returns>
public SqlDataReader ReturnReader(string strsql)
{
try
{
Connection();
cmd
= new SqlCommand(strsql, con);
reader
= cmd.ExecuteReader();
return reader;
}
catch (Exception)
{
return null;
}
finally
{
con.Dispose();
}
}
}

2.SqlConn类: 创建一个连接到数据库的类

public class SqlConn
{
private static string str = "server =.;database=Finance;uid=sa;pwd=123";

/// <summary>
/// Sqlconn连接的属性Str
/// </summary>
public static string Str
{
get { return str; }
set { str = value; }
}
}

3.SqlAccess类:

namespace SQLAccessDatabase
{
class AccessDB
{
private string dbAddress;
private string sqlString;
private SqlConnection con=null;

public AccessDB(string dbAddress, string sqlString)
{
this.dbAddress = dbAddress;
this.sqlString = sqlString;
}

/// <summary>
/// 连接数据库
/// </summary>
private void Connect()
{
try
{
if (con == null) //单件模式
con = new SqlConnection(this.dbAddress);
con.Open();
}
catch
{
}
}

/// <summary>
/// 对数据库进行操作
/// </summary>
/// <param name="strArray">字符串的参数</param>
/// <returns>是否连接成功</returns>
public bool ConnectDB(params string[] strArray)
{
try
{
Connect();

SqlCommand cmd
= new SqlCommand(this.sqlString, con);

//取SQL语句中的参数进行赋值
string[] sqlstr = this.sqlString.Split('@');
int i = -1;
string tempstr = "";
foreach (string str in sqlstr)
{
i
++;
if (i == 0)
continue;
tempstr
= "@" + str.Remove(str.IndexOf(' '));
cmd.Parameters.Add(tempstr, SqlDbType.VarChar).Value
= strArray[i - 1];
}

//对SQL语句进行操作
string s = sqlString.Remove(sqlString.IndexOf(' '));
if (s == "select")
{
SqlDataReader reader
= cmd.ExecuteReader();
if (reader.Read())
{
return true;
}
}
else if (s == "insert" || s == "update" || s == "delete")
{
int count = cmd.ExecuteNonQuery();
if (count >= 1)
{
return true;
}
}
return false;
}
catch
{
return false;
}
finally
{
con.Dispose();
}
}

/// <summary>
/// 无连接读取数据库
/// </summary>
/// <param name="tableName">获取表的名字</param>
/// <returns>数据集合</returns>
public DataSet GetTable(params string[] tableName)
{
try
{
Connect();

SqlDataAdapter sda
= new SqlDataAdapter(sqlString, con);

DataSet ds
= new DataSet();
if (tableName.Length == 0)
{
sda.Fill(ds);
}
else
{
foreach (string str in tableName)
sda.Fill(ds, str);
}

return ds;
}
catch
{
return null;
}
finally
{
con.Dispose();
}
}
}

public class SQLServer
{
public static string dbAddress = "server=.;database=Finance;uid=sa;pwd=123";
}
}

4.DBHelper类(用于存储过程)

public class DBHelper
{
/// <summary>
/// 构建 SqlCommand 对象(用来返回一个结果集,而不是一个整数值)
/// </summary>
/// <param name="connection">数据库连接</param>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlCommand</returns>
private static SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
{
SqlCommand command
= new SqlCommand(storedProcName, connection);
command.CommandType
= CommandType.StoredProcedure;

foreach (SqlParameter parameter in parameters)
{
if (parameter != null)
{
// 检查未分配值的输出参数,将其分配以DBNull.Value.
if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
(parameter.Value
== null))
{
parameter.Value
= DBNull.Value;
}
command.Parameters.Add(parameter);
}
}

return command;
}

/// <summary>
/// 执行存储过程,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlDataReader</returns>
public static SqlDataReader RunProcedure(string storedProcName, IDataParameter[] parameters)
{
SqlConnection connection
= new SqlConnection(Config.ConStr);
SqlDataReader returnReader;
connection.Open();
SqlCommand command
= BuildQueryCommand(connection, storedProcName, parameters);
command.CommandType
= CommandType.StoredProcedure;
returnReader
= command.ExecuteReader(CommandBehavior.CloseConnection);
return returnReader;

}

/// <summary>
/// 执行存储过程,返回DataSet
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlDataReader</returns>
public static DataSet RunProcedure(string storedProcName, IDataParameter[] parameters,string resultTableName)
{
SqlConnection connection
= new SqlConnection(Config.ConStr);

SqlDataAdapter da
= new SqlDataAdapter("",connection);

SqlCommand command
= BuildQueryCommand(connection, storedProcName, parameters);
command.CommandType
= CommandType.StoredProcedure;

da.SelectCommand
= command;

DataSet ds
= new DataSet();

if (resultTableName.Trim() != "")
da.Fill(ds, resultTableName.Trim());
else
da.Fill(ds);

return ds;

}

/// <summary>
/// 执行存储过程,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlDataReader</returns>
public static SqlDataReader RunSQL(string storedProcName, IDataParameter[] parameters)
{
SqlConnection connection
= new SqlConnection(Config.ConStr);
SqlDataReader returnReader;
connection.Open();
SqlCommand command
= BuildQueryCommand(connection, storedProcName, parameters);
command.CommandType
= CommandType.Text;
returnReader
= command.ExecuteReader(CommandBehavior.CloseConnection);
return returnReader;

}
}

业务逻辑层:BLL

Operation类:

#region 报销管理

SqlHelp help
= new SqlHelp();
public bool ExpendAccountPopedom()
{
string sqlstr = string.Format("select * from Popedom_Employee inner join Popedom on Popedom_Employee.PopedomID=Popedom.PopedomID ,Employee where Popedom_Employee.EmployeeID={0} and PopedomName='{1}' and Employee.EmployeeID={2} and Grade like '{3}'", int.Parse(IDNumber.IdNumber), "报销管理", int.Parse(IDNumber.IdNumber), "%经理");
AccessDB adb
= new AccessDB(SQLServer.dbAddress, sqlstr);
return adb.ConnectDB();
}
public DataSet Bind(string table)
{
string strsql = "select *from ExpendAccount";
return RetrunnewDS(table, strsql);
}
//将表中的数据在textBox一一显示
public DataSet ShowIntxt(string expendaccountid, string table)
{
string strsql = string.Format("select *from ExpendAccount where ExpendaccountID={0}", expendaccountid);
return RetrunnewDS(table, strsql);
}

//提交报销申请
public bool ExpendAccount(int expendPeopleid, string goodTag, string purpose, string beforePay, string expendSum)
{
string strsql = string.Format("insert into ExpendAccount (ExpendPeopleID,GoodsTag,ExpendaccountTime,GoodsPurpose,BeforePay,ExpendSum) values({0},'{1}','{2}','{3}','{4}','{5}')", expendPeopleid, goodTag, DateTime.Now.ToShortDateString(), purpose, beforePay, expendSum);
return ReturnCount(strsql);
}
//审批报销申请
public bool ExpendAccountExamin(string promiserstatu, string index)
{
string strsql = string.Format("update ExpendAccount set PromiserStatu='{0}',Promiserid={1} where ExpendAccountId={2}", promiserstatu, int.Parse(IDNumber.IdNumber), index);
return ReturnCount(strsql);
}
#endregion

#region 工资管理
//将工资表中的数据一一读到txtBox中
public DataSet ShowIntxtPay(string table, string employeeid)
{
string strsql = string.Format("select *from EmployeePay where EmployeeID={0}", employeeid);
return RetrunnewDS(table, strsql);
}
//Bind显示工资表中数据
public DataSet BindPay(string table)
{
string strsql = "select *from EmployeePay";
return RetrunnewDS(table, strsql);
}
//更新工资表
public bool EmployeePayUpdate(int id, string baspay, string perpay, string subsidy, string prize, string allpay, string perincome, string reallypay)
{
string strsql = string.Format
(
"update EmployeePay set EmployeeID={0},BasicPay='{1}',PerformancePay='{2}',Subsidy='{3}',Prize='{4}', AllPay ='{5}',PersonalIncometax='{6}',ReallyPay='{7}' where EmployeeID={0}", id, baspay, perpay, subsidy, prize, allpay, perincome, reallypay, id);
return (ReturnCount(strsql));
}
//添加员工工资信息
public bool EmployeePayAdd(int id, string baspay, string perpay, string subsidy, string prize, string allpay, string perincome, string reallypay)
{
string strsql = string.Format
(
"insert into EmployeePay ( EmployeeID,BasicPay,PerformancePay,Subsidy,Prize, AllPay,PersonalIncometax,ReallyPay ) values ({0},'{1}','{2}','{3}','{4}','{5}','{6}','{7}')", id, baspay, perpay, subsidy, prize, allpay, perincome, reallypay);
return ReturnCount(strsql);
}
//删除员工工资信息
public bool EmployeePayDel(int id)
{
string strsql = string.Format("delete from EmployeePay where EmployeeID={0}", id);
return ReturnCount(strsql);
}
#endregion

#region 方法
//返回受影响行数
private bool ReturnCount(string strsql)
{
int count = help.Command(strsql);
if (count >= 1)
{
return true;
}
else
return false;
}
//返回数据集
private DataSet RetrunnewDS(string table, string strsql)
{
DataSet ds
= help.ReturnDs(strsql, table);
return ds;
}
#endregion

UserLogin类:防注入式攻击

public class UserLogin
{
public bool UseLogin(string name, string pwd)
{
string str = "server=.;database=Finance;uid=sa;pwd=123";
using (SqlConnection con =new SqlConnection (str))
{
con.Open();
string strsql = "select * from PersonInfo where employeeid=@employeeid and employeepwd=@employeepwd";
SqlCommand cmd
= new SqlCommand(strsql, con);
cmd.Parameters.Add(
"@employeeid",SqlDbType.VarChar).Value = name;
cmd.Parameters.Add(
"@employeepwd", SqlDbType.VarChar).Value = pwd;
SqlDataReader reader
= cmd.ExecuteReader();
if (reader.Read())
{
return true;
}
else
return false;
}
}

SqlHelp help
= new SqlHelp();
#region 方法
//返回受影响行数
private bool ReturnCount(string strsql)
{
int count = help.Command(strsql);
if (count >= 1)
{
return true;
}
else
return false;
}
//返回数据集
private DataSet RetrunnewDS(string table, string strsql)
{
DataSet ds
= help.ReturnDs(strsql, table);
return ds;
}
#endregion
}

以上DAL仅仅是针对SqlServer数据库,要想针对所有的数据库均有效,可用到工厂模式。

下面是工厂模式封装的DAL针对多个数据库,而且既可以封装的SqlHelper不仅对简单的五大对象封装,而且还可以针对对存储过程的封装(就是将上面的DbHelper和SqlHelp结合起来用)

下面以PetShop4.0为例讲解如下:

DBUtility类:OracleHelper


/// <summary>
/// A helper class used to execute queries against an Oracle database
/// </summary>
public abstract class OracleHelper {

// Read the connection strings from the configuration file
public static readonly string ConnectionStringLocalTransaction = ConfigurationManager.ConnectionStrings["OraConnString1"].ConnectionString;
public static readonly string ConnectionStringInventoryDistributedTransaction = ConfigurationManager.ConnectionStrings["OraConnString2"].ConnectionString;
public static readonly string ConnectionStringOrderDistributedTransaction = ConfigurationManager.ConnectionStrings["OraConnString3"].ConnectionString;
public static readonly string ConnectionStringProfile = ConfigurationManager.ConnectionStrings["OraProfileConnString"].ConnectionString;
public static readonly string ConnectionStringMembership = ConfigurationManager.ConnectionStrings["OraMembershipConnString"].ConnectionString;

//Create a hashtable for the parameter cached
private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());

/// <summary>
/// Execute a database query which does not include a select
/// </summary>
/// <param name="connString">Connection string to database</param>
/// <param name="cmdType">Command type either stored procedure or SQL</param>
/// <param name="cmdText">Acutall SQL Command</param>
/// <param name="commandParameters">Parameters to bind to the command</param>
/// <returns></returns>
public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {
// Create a new Oracle command
OracleCommand cmd = new OracleCommand();

//Create a connection
using (OracleConnection connection = new OracleConnection(connectionString)) {

//Prepare the command
PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);

//Execute the command
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
}

/// <summary>
/// Execute an OracleCommand (that returns no resultset) against an existing database transaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24));
/// </remarks>
/// <param name="trans">an existing database transaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or PL/SQL command</param>
/// <param name="commandParameters">an array of OracleParamters used to execute the command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(OracleTransaction trans, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {
OracleCommand cmd
= new OracleCommand();
PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Execute an OracleCommand (that returns no resultset) against an existing database connection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24));
/// </remarks>
/// <param name="conn">an existing database connection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or PL/SQL command</param>
/// <param name="commandParameters">an array of OracleParamters used to execute the command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(OracleConnection connection, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {

OracleCommand cmd
= new OracleCommand();

PrepareCommand(cmd, connection,
null, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Execute a select query that will return a result set
/// </summary>
/// <param name="connString">Connection string</param>
//// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or PL/SQL command</param>
/// <param name="commandParameters">an array of OracleParamters used to execute the command</param>
/// <returns></returns>
public static OracleDataReader ExecuteReader(string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {

//Create the command and connection
OracleCommand cmd = new OracleCommand();
OracleConnection conn
= new OracleConnection(connectionString);

try {
//Prepare the command to execute
PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);

//Execute the query, stating that the connection should close when the resulting datareader has been read
OracleDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;

}
catch {

//If an error occurs close the connection as the reader will not be used and we expect it to close the connection
conn.Close();
throw;
}
}

/// <summary>
/// Execute an OracleCommand that returns the first column of the first record against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24));
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or PL/SQL command</param>
/// <param name="commandParameters">an array of OracleParamters used to execute the command</param>
/// <returns>An object that should be converted to the expected type using Convert.To{Type}</returns>
public static object ExecuteScalar(string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {
OracleCommand cmd
= new OracleCommand();

using (OracleConnection conn = new OracleConnection(connectionString)) {
PrepareCommand(cmd, conn,
null, cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}
}

/// <summary>
/// Execute a OracleCommand (that returns a 1x1 resultset) against the specified SqlTransaction
/// using the provided parameters.
/// </summary>
/// <param name="transaction">A valid SqlTransaction</param>
/// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">The stored procedure name or PL/SQL command</param>
/// <param name="commandParameters">An array of OracleParamters used to execute the command</param>
/// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(OracleTransaction transaction, CommandType commandType, string commandText, params OracleParameter[] commandParameters) {
if(transaction == null)
throw new ArgumentNullException("transaction");
if(transaction != null && transaction.Connection == null)
throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

// Create a command and prepare it for execution
OracleCommand cmd = new OracleCommand();

PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters);

// Execute the command & return the results
object retval = cmd.ExecuteScalar();

// Detach the SqlParameters from the command object, so they can be used again
cmd.Parameters.Clear();
return retval;
}

/// <summary>
/// Execute an OracleCommand that returns the first column of the first record against an existing database connection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// Object obj = ExecuteScalar(conn, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24));
/// </remarks>
/// <param name="conn">an existing database connection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or PL/SQL command</param>
/// <param name="commandParameters">an array of OracleParamters used to execute the command</param>
/// <returns>An object that should be converted to the expected type using Convert.To{Type}</returns>
public static object ExecuteScalar(OracleConnection connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {
OracleCommand cmd
= new OracleCommand();

PrepareCommand(cmd, connectionString,
null, cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Add a set of parameters to the cached
/// </summary>
/// <param name="cacheKey">Key value to look up the parameters</param>
/// <param name="commandParameters">Actual parameters to cached</param>
public static void CacheParameters(string cacheKey, params OracleParameter[] commandParameters) {
parmCache[cacheKey]
= commandParameters;
}

/// <summary>
/// Fetch parameters from the cache
/// </summary>
/// <param name="cacheKey">Key to look up the parameters</param>
/// <returns></returns>
public static OracleParameter[] GetCachedParameters(string cacheKey) {
OracleParameter[] cachedParms
= (OracleParameter[])parmCache[cacheKey];

if (cachedParms == null)
return null;

// If the parameters are in the cache
OracleParameter[] clonedParms = new OracleParameter[cachedParms.Length];

// return a copy of the parameters
for (int i = 0, j = cachedParms.Length; i < j; i++)
clonedParms[i]
= (OracleParameter)((ICloneable)cachedParms[i]).Clone();

return clonedParms;
}

/// <summary>
/// Internal function to prepare a command for execution by the database
/// </summary>
/// <param name="cmd">Existing command object</param>
/// <param name="conn">Database connection object</param>
/// <param name="trans">Optional transaction object</param>
/// <param name="cmdType">Command type, e.g. stored procedure</param>
/// <param name="cmdText">Command test</param>
/// <param name="commandParameters">Parameters for the command</param>
private static void PrepareCommand(OracleCommand cmd, OracleConnection conn, OracleTransaction trans, CommandType cmdType, string cmdText, OracleParameter[] commandParameters) {

//Open the connection if required
if (conn.State != ConnectionState.Open)
conn.Open();

//Set up the command
cmd.Connection = conn;
cmd.CommandText
= cmdText;
cmd.CommandType
= cmdType;

//Bind it to the transaction if it exists
if (trans != null)
cmd.Transaction
= trans;

// Bind the parameters passed in
if (commandParameters != null) {
foreach (OracleParameter parm in commandParameters)
cmd.Parameters.Add(parm);
}
}

/// <summary>
/// Converter to use boolean data type with Oracle
/// </summary>
/// <param name="value">Value to convert</param>
/// <returns></returns>
public static string OraBit(bool value) {
if(value)
return "Y";
else
return "N";
}

/// <summary>
/// Converter to use boolean data type with Oracle
/// </summary>
/// <param name="value">Value to convert</param>
/// <returns></returns>
public static bool OraBool(string value) {
if(value.Equals("Y"))
return true;
else
return false;
}
}

SqlHelper类:

/// <summary>
/// The SqlHelper class is intended to encapsulate high performance,
/// scalable best practices for common uses of SqlClient.
/// </summary>
public abstract class SqlHelper {

//Database connection strings
public static readonly string ConnectionStringLocalTransaction = ConfigurationManager.ConnectionStrings["SQLConnString1"].ConnectionString;
public static readonly string ConnectionStringInventoryDistributedTransaction = ConfigurationManager.ConnectionStrings["SQLConnString2"].ConnectionString;
public static readonly string ConnectionStringOrderDistributedTransaction = ConfigurationManager.ConnectionStrings["SQLConnString3"].ConnectionString;
public static readonly string ConnectionStringProfile = ConfigurationManager.ConnectionStrings["SQLProfileConnString"].ConnectionString;

// Hashtable to store cached parameters
private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());

/// <summary>
/// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {

SqlCommand cmd
= new SqlCommand();

using (SqlConnection conn = new SqlConnection(connectionString)) {
PrepareCommand(cmd, conn,
null, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
}

/// <summary>
/// Execute a SqlCommand (that returns no resultset) against an existing database connection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="conn">an existing database connection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {

SqlCommand cmd
= new SqlCommand();

PrepareCommand(cmd, connection,
null, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Execute a SqlCommand (that returns no resultset) using an existing SQL Transaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="trans">an existing sql transaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {
SqlCommand cmd
= new SqlCommand();
PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Execute a SqlCommand that returns a resultset against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// SqlDataReader r = ExecuteReader(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>A SqlDataReader containing the results</returns>
public static SqlDataReader ExecuteReader(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {
SqlCommand cmd
= new SqlCommand();
SqlConnection conn
= new SqlConnection(connectionString);

// we use a try/catch here because if the method throws an exception we want to
// close the connection throw code, because no datareader will exist, hence the
// commandBehaviour.CloseConnection will not work
try {
PrepareCommand(cmd, conn,
null, cmdType, cmdText, commandParameters);
SqlDataReader rdr
= cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;
}
catch {
conn.Close();
throw;
}
}

/// <summary>
/// Execute a SqlCommand that returns the first column of the first record against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>An object that should be converted to the expected type using Convert.To{Type}</returns>
public static object ExecuteScalar(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {
SqlCommand cmd
= new SqlCommand();

using (SqlConnection connection = new SqlConnection(connectionString)) {
PrepareCommand(cmd, connection,
null, cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}
}

/// <summary>
/// Execute a SqlCommand that returns the first column of the first record against an existing database connection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="conn">an existing database connection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>An object that should be converted to the expected type using Convert.To{Type}</returns>
public static object ExecuteScalar(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {

SqlCommand cmd
= new SqlCommand();

PrepareCommand(cmd, connection,
null, cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// add parameter array to the cache
/// </summary>
/// <param name="cacheKey">Key to the parameter cache</param>
/// <param name="cmdParms">an array of SqlParamters to be cached</param>
public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters) {
parmCache[cacheKey]
= commandParameters;
}

/// <summary>
/// Retrieve cached parameters
/// </summary>
/// <param name="cacheKey">key used to lookup parameters</param>
/// <returns>Cached SqlParamters array</returns>
public static SqlParameter[] GetCachedParameters(string cacheKey) {
SqlParameter[] cachedParms
= (SqlParameter[])parmCache[cacheKey];

if (cachedParms == null)
return null;

SqlParameter[] clonedParms
= new SqlParameter[cachedParms.Length];

for (int i = 0, j = cachedParms.Length; i < j; i++)
clonedParms[i]
= (SqlParameter)((ICloneable)cachedParms[i]).Clone();

return clonedParms;
}

/// <summary>
/// Prepare a command for execution
/// </summary>
/// <param name="cmd">SqlCommand object</param>
/// <param name="conn">SqlConnection object</param>
/// <param name="trans">SqlTransaction object</param>
/// <param name="cmdType">Cmd type e.g. stored procedure or text</param>
/// <param name="cmdText">Command text, e.g. Select * from Products</param>
/// <param name="cmdParms">SqlParameters to use in the command</param>
private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) {

if (conn.State != ConnectionState.Open)
conn.Open();

cmd.Connection
= conn;
cmd.CommandText
= cmdText;

if (trans != null)
cmd.Transaction
= trans;

cmd.CommandType
= cmdType;

if (cmdParms != null) {
foreach (SqlParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
}
}

 图片转自:http://www.cnblogs.com/terrydong/archive/2007/12/06/985722.html

背景:

由于目前服务的公司,系统复杂度很高,数据库使用了Oracle、SqlServer、MySql......(就差用到所有的数据库产品了,呵呵)

系统重构的过程中,之前写的基于sqlserver的简单三层架构已经不能满足系统重构的需求...

需求:

支持多类型数据库

操作多个同一类型数据库

参考:

PetShop4.0

解决方案框架图如上图

数据访问工具类

数据访问类使用DbProviderFactory实现,方法在父类实现,子类中只需通过实现CreateInstance()方法来指定providerName和connectionString 即可,唯一遗憾的是Mysql数据库不能通过这种方式实现,需要再单独写数据访问类了。

数据访问类 

 转载自:http://blog.sina.com.cn/s/blog_4a24068d01009mia.html

 工厂模式三层架构

项目

描述

BLL

商务逻辑层组件

DALFactory

用于定义要加载哪个数据库访问程序集的工厂类

IDAL

接口集合,需要被每一个DAL类具体实现

Model

业务实体模型

SQLServerDAL

SQL Server数据库的IDAL接口实现

Web

Web 页和用户控件

BLL:调用接口实现数据层的访问,至于调用的是哪个数据类的实现,由DALFactory来实现.

DALFactory:通过工厂模式来实现调用具体哪个的数据子层.通过读取读取web.config参数用反射机制来动态加载具体的程序集.

IDAL:接口是一种系列‘功能’的声明或名单,接口没有实现细节,只是一些功能方法的定义.

Model: 数据库是关系型,不是面向对象的,要实现面向对象那就得把平面的‘表’结合业务规则抽象成类.

SQLServerDAL:是接口层的(SQLServer)实现,为了支持多数据库还可以有OracleDAL的实现.具体使用哪个由DALFactory决定.

Common:项目所用的公共类库或组件。

DBUtility:对ADO.NET数据访问封装的组件类库。

 

简单三层结构

 

项目

描述

BLL

业务逻辑层

Common

通用类库组件

DAL

数据访问层

DBUtility

数据访问组件

Web

Web 页表示层

Model

业务实体模型

BLL:调用接口实现数据层的访问,至于调用的是哪个数据类的实现,由DALFactory来实现.

Common:项目所用的公共类库或组件。

DBUtility:对ADO.NET数据访问封装的组件类库。

Model: 数据库是关系型,不是面向对象的,要实现面向对象那就得把平面的‘表’结合业务规则抽象成类.

DAL:是接口层的(SQLServer)实现,为了支持多数据库还可以有OracleDAL的实现.具体使用哪个由DALFactory决定.

 

转载自:http://blog.csdn.net/xiaolukatie/archive/2009/04/01/4041109.aspx
工厂模式则是属于一种设计模式,指的是专门定义一个类来负责创建其他类的实例,属于类的创建型模式,通常根据一个条件(参数)来返回不同的类的实例。

以下是转自别人的观点,留待细看

设计模式也是分类的

三层模式是体系结构模式,MVC是设计模式

三层模式又可归于部署模式,MVC可归于表示模式,工厂模式可归于分布式系统模式。

三层模式跟工厂模式,个人的见解如下:

工厂当然是得建立在三层的基础上的

三层,简单的说,数据访问,业务逻辑,表示,3个层面,3层会在一定程度上降低效率

但是他的优点远远的大于了那一点点的缺点,代码易于维护,程序结构清晰,关键是松散耦合

工厂呢,就是

例如,如果我要个对象,就会让工厂去创建,创建完成,给你返回个结果。

假如你去吃麦当劳,你说要个汉堡,你不会自己去做吧,相当于,你跟服务员说,我要个汉堡,服务员跟后面的“工厂”说,然后工厂帮你做个汉堡,然后“工厂”会给你个结果

三层架构,数据层(DAL)、逻辑层(BLL)、表示层(UI);
从功能上来说:
表示层就象你去饭店吃饭,你点了一个清真鲈鱼。
业务层负责洗、切、蒸等。
数据层负责提供鱼、油、盐等。


确切的说现在应用一般为7层结构

---DBUtility数据层基类
---DALFactory数据层工厂类
---IDAL接口层
---SQLDAL接口实现层
---Model实体类
---Logic业务逻辑层
---Web表示层

 

原文地址:https://www.cnblogs.com/lhws/p/1826818.html