厚积薄发,丰富的公用类库积累,助你高效进行系统开发(3)----数据库相关操作
在前面随笔《
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(1)
》和《
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(2)
》,介绍了公用类库的包含的内容以及相关使用说明,本文将继续把在整理帮助文档成CHM过程中,完成的类库使用说明逐步放送,一是使得大家对类库的功能及使用有一个大致的了解,并能够在实际中应用,或者能够和大家在这方面继续探讨,逐步改进和完善。
1、 Access数据库文件操作辅助类JetAccessUtil
实现效果
1)本辅助类主要是用来方便实现Access数据库文件操作,包括新建Access数据库(可含密码)、压缩数据库、设置数据库密码、列出数据库表、列出数据库表字段等常用的Access数据库文件操作的实现。
实现代码
1)辅助类库JetAccessUtil的相关方法定义
///
<summary>
///
新建带密码的空Access 2000 数据库
///
</summary>
///
<param name="mdbFilePath">
数据库文件路径
</param>
///
<param name="password">
数据库密码
</param>
///
<returns>
字符0为操作成功,否则为失败异常消息。
</returns>
public
static
string
CreateMDB(
string
mdbFilePath,
string
password)
///
<summary>
///
新建空的Access数据库
///
</summary>
///
<param name="mdbFilePath">
数据库文件路径
</param>
///
<returns>
字符0为操作成功,否则为失败异常消息。
</returns>
public
static
string
CreateMDB(
string
mdbFilePath)
///
<summary>
///
压缩带密码Access数据库
///
</summary>
///
<param name="mdbFilePath">
数据库文件路径
</param>
///
<param name="password">
数据库密码
</param>
///
<returns>
字符0为操作成功,否则为失败异常消息。
</returns>
public
static
string
CompactMDB(
string
mdbFilePath,
string
password)
///
<summary>
///
压缩没有带密码Access数据库
///
</summary>
///
<param name="mdbFilePath">
数据库文件路径
</param>
///
<returns>
字符0为操作成功,否则为失败异常消息。
</returns>
public
static
string
CompactMDB(
string
mdbFilePath)
///
<summary>
///
设置Access数据库的访问密码
///
</summary>
///
<param name="mdbFilePath">
数据库文件路径
</param>
///
<param name="oldPwd">
旧密码
</param>
///
<param name="newPwd">
新密码
</param>
///
<returns>
字符0为操作成功,否则为失败异常消息。
</returns>
public
static
string
SetMDBPassword(
string
mdbFilePath,
string
oldPwd,
string
newPwd)
///
<summary>
///
列出Access 2000 数据库的表名称
///
</summary>
///
<param name="mdbFilePath">
数据库文件路径
</param>
///
<param name="password">
数据库密码
</param>
///
<returns></returns>
public
static
List
<
string
>
ListTables(
string
mdbFilePath,
string
password)
///
<summary>
///
列出Access2000数据库的表字段
///
</summary>
///
<param name="mdbFilePath">
数据库文件路径
</param>
///
<param name="password">
数据库密码
</param>
///
<param name="tableName">
表名称
</param>
///
<returns>
返回字段名称和对应类型的字典数据
</returns>
public
static
Dictionary
<
string
,
string
>
ListColumns(
string
mdbFilePath,
string
password,
string
tableName)
2)辅助类库的使用例子。
fileNoPass
=
Path.Combine(Path.GetTempPath(),
"
EmptyNoPass.mdb
"
);
string
filePass
=
Path.Combine(Path.GetTempPath(),
"
EmptyWithPass.mdb
"
);
//
创建不带密码的空数据库
JetAccessUtil.CreateMDB(fileNoPass);
//
创建带密码的空数据库
JetAccessUtil.CreateMDB(filePass,
"
wuhuacong@163.com
"
);
//
压缩不带密码的数据库
JetAccessUtil.CompactMDB(fileNoPass);
//
压缩带密码的数据库
JetAccessUtil.CompactMDB(filePass,
"
wuhuacong@163.com
"
);
//
重新设置数据库的密码
JetAccessUtil.SetMDBPassword(filePass,
"
wuhuacong@163.com
"
,
"
6966254
"
);
//
列出数据库的表名称
List
<
string
>
tableNameList
=
JetAccessUtil.ListTables(filePass,
"
6966254
"
);
string
strNameList
=
""
;
foreach
(
string
name
in
tableNameList)
{
strNameList
+=
string
.Format(
"
,{0}
"
, name);
}
if
(
!
string
.IsNullOrEmpty(strNameList))
{
MessageUtil.ShowTips(strNameList);
}
Process.Start(Path.GetTempPath());
2、常用的Access数据库Sql操作辅助类库 OleDbHelper
实现效果
1)本辅助类主要是用来方便实现对Access数据库文件的Sql访问,包括测试连接、执行Sql、获取返回数据集等操作。
2)辅助类库构造对象的时候,只需要传入Access数据库文件,即可对其进行相关的Sql操作,简化对Access数据库执行脚本的操作。
实现代码
1)辅助类OleDbHelper提供的函数列表如下所示。
<summary>
///
常用的Access数据库Sql操作辅助类库
///
</summary>
public
class
OleDbHelper
{
///
<summary>
///
构造函数
///
</summary>
///
<param name="accessFilePath"></param>
public
OleDbHelper(
string
accessFilePath)
///
<summary>
///
测试数据库是否正常连接
///
</summary>
///
<returns></returns>
public
bool
TestConnection()
///
<summary>
///
执行Sql,并返回成功的数量
///
</summary>
///
<param name="sqlList">
待执行的Sql列表
</param>
///
<returns></returns>
public
int
ExecuteNonQuery(List
<
string
>
sqlList)
///
<summary>
///
执行无返回值的语句,成功返回True,否则False
///
</summary>
///
<param name="sql">
待执行的Sql
</param>
///
<returns></returns>
public
bool
ExecuteNoQuery(
string
sql)
///
<summary>
///
执行单返回值的语句
///
</summary>
///
<param name="sql">
待执行的Sql
</param>
///
<returns></returns>
public
object
ExecuteScalar(
string
sql)
///
<summary>
///
执行Sql,并返回IDataReader对象。
///
</summary>
///
<param name="sql">
待执行的Sql
</param>
///
<returns></returns>
public
IDataReader ExecuteReader(
string
sql)
///
<summary>
///
执行Sql并返回DataSet集合
///
</summary>
///
<param name="sql">
待执行的Sql
</param>
///
<returns></returns>
public
DataSet ExecuteDataSet(
string
sql)
}
2)实现操作例子如下所示。
access
=
@"
C:\Orderwater.mdb
"
;
List
<
string
>
tableNameList
=
JetAccessUtil.ListTables(access,
""
);
OleDbHelper helper
=
new
OleDbHelper(access);
foreach
(
string
tableName
in
tableNameList)
{
string
sql
=
string
.Format(
"
Select * from {0}
"
, tableName);
DataSet ds
=
helper.ExecuteDataSet(sql);
if
(ds.Tables[
0
].Rows.Count
>
0
)
{
MessageUtil.ShowTips(
string
.Format(
"
tableName:{0} RowCount:{1}
"
, tableName, ds.Tables[
0
].Rows.Count));
}
}
3、根据各种不同数据库生成不同分页语句的辅助类 PagerHelper
1)本辅助类主要是用来方便根据各种条件,生成不同的分页语句,且支持Oracle、SqlServer、Access、MySql数据库分页语句的生成。
2)辅助类可以根据表名、查询字段列表、排序字段、分页数量、分页页码、降序升序、查询条件等条件组合成一条完整的分页语句,并且支持获取数量和列表两种语句接口,非常方便用于数据的分页处理。
实现代码:
1)使用例子说明。通过构造PageHelper类,并传入表名、查询字段、排序字段、页面大小、当前页码、降序升序、查询条件等参数,可以生成基于Oracle、SqlServer、Access、MySql数据库的分页语句。然后通过具体查询总数语句、查询列表语句可以完成获取指定数据列表的显示,由于分页是基于一页一页的获取,这样提高了数据分页的效率。
<summary>
///
通过自己组装分页语句
///
</summary>
///
<param name="where"></param>
///
<param name="pagerInfo"></param>
///
<returns></returns>
private
DataTable DirectLoadData(
string
where
, PagerInfo pagerInfo)
{
DataTable dt
=
null
;
PagerHelper helper
=
new
PagerHelper(
"
All_Customer
"
,
"
*
"
,
"
ID
"
, pagerInfo.PageSize, pagerInfo.CurrenetPageIndex,
true
,
where
);
string
countSql
=
helper.GetPagingSql(DatabaseType.SqlServer,
true
);
string
dataSql
=
helper.GetPagingSql(DatabaseType.SqlServer,
false
);
string
value
=
SqlValueList(countSql);
pagerInfo.RecordCount
=
Convert.ToInt32(value);
dt
=
SqlTable(dataSql);
return
dt;
}
4、 查询条件组合辅助类 SearchCondition
实现效果
3)使用目的: 1.减少对参数非空的条件判断 2. 支持SqlServer、Oracle、Access、MySql数据访问的Sql语句的生成,根据不同数据库的一些特点差异,生成对应的语句. 3. 减少拼接语句的代码并减少出错的几率 4.构造Sql语句或者参数化条件更加易读。
4) SearchCondition辅助类的类图如下所示,其中SearchCondtion是语句操作对象类,SearchInfo是语句的条件实体类,SqlOperator是各种查询条件的枚举对象,方便操作并减少输入字符条件的出错。
实现代码
1)生成Sql语句
2)与普通做法的比较。下面我们比较一下使用该控件和不使用在列表查询页面中的代码,可以看出使用了控件后的代码大大较少了,并且可读性也增强了
string
GetCondition()
{
SearchCondition search
=
new
SearchCondition();
search.AddCondition(
"
GroupID
"
,
this
.ddlUserGroup.SelectedValue, SqlOperator.Equal,
true
)
//
班组ID
.AddCondition(
"
DealGroupName
"
,
this
.ddlDealGroup.SelectedValue, SqlOperator.Equal,
true
)
/*
消缺单位
*/
.AddCondition(
"
VisioStationID
"
,
this
.ddlStation.SelectedValue, SqlOperator.Like,
true
)
//
变电站
.AddCondition(
"
VisioImageID
"
,
this
.ddlLine.SelectedValue, SqlOperator.Like,
true
)
/*
馈线
*/
.AddCondition(
"
BugNo
"
,
this
.txtBugNo.Text.Trim(), SqlOperator.Like,
true
)
/*
编号
*/
.AddCondition(
"
Finder
"
,
this
.ddlFindUser.SelectedValue, SqlOperator.Like,
true
)
/*
发现人
*/
.AddCondition(
"
CheckUser
"
,
this
.ddlCheckUser.SelectedValue, SqlOperator.Like,
true
)
//
验收人
.AddCondition(
"
DeviceBug.BugType
"
,
this
.ddlBugType.SelectedValue, SqlOperator.Equal,
true
)
//
缺陷类别
.AddCondition(
"
CurrentState
"
,
this
.ddlCurrentState.SelectedValue, SqlOperator.Equal,
true
)
//
处理状态
.AddCondition(
"
FindDate
"
,
this
.txtFindBeginDate.Text.Trim(), SqlOperator.MoreThanOrEqual,
true
)
//
发现日期
.AddCondition(
"
FindDate
"
,
this
.txtFindEndDate.Text.Trim(), SqlOperator.LessThanOrEqual,
true
)
//
发现日期
.AddCondition(
"
EndDate
"
,
this
.txtEndBeginDate.Text.Trim(), SqlOperator.MoreThanOrEqual,
true
)
//
消缺日期
.AddCondition(
"
EndDate
"
,
this
.txtEndEndDate.Text.Trim(), SqlOperator.LessThanOrEqual,
true
);
//
消缺日期
return
search.BuildConditionSql(DatabaseType.SqlServer);
}
{
string condition = "" ;
if ( this .ddlUserGroup.SelectedValue != " 0 " )
{
condition += string .Format( " GroupID = {0} " , this .ddlUserGroup.SelectedValue.ToString() );
}
// 消缺单位
if ( this .ddlDealGroup.SelectedValue != " 0 " )
{
if (condition == "" )
{
condition += string .Format( " DealGroupName = '{0}' " , this .ddlDealGroup.SelectedItem.Text );
}
else
{
condition += string .Format( " And DealGroupName = '{0}' " , this .ddlDealGroup.SelectedItem.Text );
}
}
if ( this .txtStation.Text.Trim() != "" )
{
if (condition == "" )
{
condition += string .Format( " Station like '%{0}%' " , this .txtStation.Text.Trim() );
}
else
{
condition += string .Format( " And Station like '%{0}%' " , this .txtStation.Text.Trim() );
}
}
..............(很多类似的代码)
5、转换IDataReader字段对象的格式辅助类 SmartDataReader
实现效果
2)在使用数据库返回对象IDataReader的时候,我们需要判断数据库字段是否为可空类型,并赋予空字段默认值,或者转换为可空类型数据,使用该辅助类,可以简化繁琐的数据库字段转换操作,是数据库字段转换必备的辅助类。
实现代码
1)辅助类SmartDataReader的转换数据格式的操作例子如下。
///
<summary>
///
通用获取集合对象方法
///
</summary>
///
<param name="sql">
查询的Sql语句
</param>
///
<param name="paramList">
参数列表,如果没有则为null
</param>
///
<returns></returns>
private
List
<
T
>
GetList(
string
sql, IDbDataParameter[] paramList)
{
T entity
=
null
;
List
<
T
>
list
=
new
List
<
T
>
();
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
if
(paramList
!=
null
)
{
command.Parameters.AddRange(paramList);
}
using
(IDataReader dr
=
db.ExecuteReader(command))
{
while
(dr.Read())
{
entity
=
DataReaderToEntity(dr);
list.Add(entity);
}
}
return
list;
}
///
<summary>
///
将DataReader的属性值转化为实体类的属性值,返回实体类
///
</summary>
///
<param name="dr">
有效的DataReader对象
</param>
///
<returns>
实体类对象
</returns>
protected
ItemDetailInfo DataReaderToEntity(IDataReader dataReader)
{
ItemDetailInfo itemDetailInfo
=
new
ItemDetailInfo();
SmartDataReader reader
=
new
SmartDataReader(dataReader);
itemDetailInfo.ID
=
reader.GetInt32(
"
ID
"
);
itemDetailInfo.ItemNo
=
reader.GetString(
"
ItemNo
"
);
itemDetailInfo.ItemName
=
reader.GetString(
"
ItemName
"
);
itemDetailInfo.Manufacture
=
reader.GetString(
"
Manufacture
"
);
itemDetailInfo.MapNo
=
reader.GetString(
"
MapNo
"
);
itemDetailInfo.Specification
=
reader.GetString(
"
Specification
"
);
itemDetailInfo.Material
=
reader.GetString(
"
Material
"
);
itemDetailInfo.ItemBigType
=
reader.GetString(
"
ItemBigType
"
);
itemDetailInfo.ItemType
=
reader.GetString(
"
ItemType
"
);
itemDetailInfo.Unit
=
reader.GetString(
"
Unit
"
);
itemDetailInfo.Price
=
reader.GetDecimal(
"
Price
"
);
itemDetailInfo.Source
=
reader.GetString(
"
Source
"
);
itemDetailInfo.StoragePos
=
reader.GetString(
"
StoragePos
"
);
itemDetailInfo.UsagePos
=
reader.GetString(
"
UsagePos
"
);
itemDetailInfo.Note
=
reader.GetString(
"
Note
"
);
itemDetailInfo.WareHouse
=
reader.GetString(
"
WareHouse
"
);
itemDetailInfo.Dept
=
reader.GetString(
"
Dept
"
);
return
itemDetailInfo;
}
2)辅助类SmartDataReader提供了各种类型的数据转换函数,如Int32、Int16、Decimal、Float、DateTime等数据类型的格式转换,每个格式提供了几种方式的处理,如对Int类型的数据转换,其封装的函数实现如下所示。
<summary>
///
转换为Int类型数据
///
</summary>
public
int
GetInt32(
string
column)
{
return
GetInt32(column,
0
);
}
///
<summary>
///
转换为Int类型数据
///
</summary>
public
int
GetInt32(
string
column,
int
defaultIfNull)
{
int
data
=
(reader.IsDBNull(reader.GetOrdinal(column)))
?
(
int
)defaultIfNull :
int
.Parse(reader[column].ToString());
return
data;
}
///
<summary>
///
转换为Int类型数据
///
</summary>
public
int
?
GetInt32Nullable(
string
column)
{
int
?
data
=
(reader.IsDBNull(reader.GetOrdinal(column)))
?
(
int
?
)
null
:
int
.Parse(reader[column].ToString());
return
data;
}
6、OSql命令操作函数辅助类 SqlScriptHelper
实现效果
2)本辅助类库通常用在SqlServer数据库脚本执行,附加、分离、备份、恢复数据库等操作。
实现代码
1)主要的类库函数如下所示。
<summary>
///
本地执行SQL脚本
///
</summary>
///
<param name="path">
脚本文件路径全名
</param>
public
static
void
DoSQL(
string
path)
///
<summary>
///
执行SQL脚本
///
</summary>
///
<param name="path">
脚本文件路径全名
</param>
///
<param name="userID">
数据库登录ID
</param>
///
<param name="password">
数据库登录密码
</param>
///
<param name="server">
数据库服务器地址
</param>
public
static
void
DoSQL(
string
path,
string
userID,
string
password,
string
server)
///
<summary>
///
后台执行DOS文件
///
</summary>
///
<param name="fileName">
文件名(包含路径)
</param>
///
<param name="argument">
运行参数
</param>
///
<param name="hidden">
是否隐藏窗口
</param>
public
static
void
RunDos(
string
fileName,
string
argument,
bool
hidden)
///
<summary>
///
在运行脚本之前把脚本中的数据库名称替换成安装界面输入的数据库名称
///
</summary>
///
<param name="filePath">
脚本文件名
</param>
///
<param name="oldDBName">
原有的数据库名称
</param>
///
<param name="newDBName">
新的数据库名称
</param>
public
static
void
ReplaceDBName(
string
filePath,
string
oldDBName,
string
newDBName)
///
<summary>
///
附加SqlServer数据库
///
</summary>
public
bool
AttachDB(
string
connectionString,
string
dataBaseName,
string
dataBase_MDF,
string
dataBase_LDF)
///
<summary>
///
分离SqlServer数据库
///
</summary>
public
bool
DetachDB(
string
connectionString,
string
dataBaseName)
///
<summary>
///
还原数据库
///
</summary>
public
bool
RestoreDataBase(
string
connectionString,
string
dataBaseName,
string
DataBaseOfBackupPath,
string
DataBaseOfBackupName)
///
<summary>
///
备份SqlServer数据库
///
</summary>
public
bool
BackupDataBase(
string
connectionString,
string
dataBaseName,
string
DataBaseOfBackupPath,
string
DataBaseOfBackupName)
2)安装执行数据库脚本的操作例子如下所示。
sqlFilePath
=
physicalRoot
+
"
Hotel.sql
"
;
SqlScriptHelper.ReplaceDBName(sqlFilePath,
"
Hotel_Database
"
, EdnmsDb.Database);
if
(
!
string
.IsNullOrEmpty(EdnmsDb.UserId)
&&
!
string
.IsNullOrEmpty(EdnmsDb.Password))
{
SqlScriptHelper.DoSQL(sqlFilePath, EdnmsDb.UserId, EdnmsDb.Password, EdnmsDb.Server);
}
else
{
SqlScriptHelper.DoSQL(sqlFilePath, EdnmsDb.Server);
}
最新公用类库DLL+XML注释文件下载地址是:
https://files.cnblogs.com/wuhuacong/WHC.OrderWater.Commons.rar
基于时间和篇幅考虑,下次继续介绍相关的类库使用,另外提一下,整个系列的CHM文档也在同步整理中,我们来看看目前进度的完成的CHM文件情况。
再次感谢大家的支持和鼓励。
CHM帮助文档持续更新中,统一下载地址是:
http://www.iqidi.com/download/commonshelp.rar