小菜鸟一步步打造图书馆外挂之四:数据访问(一)
该系统数据量不大,正常情况下不到十条记录,再加上一些用户的配置,所以用XML文件来存储信息比较方便,以后也可能不会放到数据库中,所以在设计数据访问时没有什么设计,只是提供一些增删改的方法。
在解决方案LibraryHelper中添加工程DAL,添加一个类BookXML,对保存图书信息的XML文件的操作。把命名空间改为Libraryhelper.DAL,引入上一小节建好的Model工程。
创建名为BookXML.xml的XML文件用来保存从图书馆网站上读取下来的数据,结构如下:
<?xml version="1.0" standalone="yes"?>
<Books>
<book>
<title>重构:改善既有代码的设计</title>
<borrowDate>2008-12-21</borrowDate>
<returnDate>2009-03-23</returnDate>
<borrowNum>0 续借 </borrowNum>
<isbnNum>TP311.11/31</isbnNum>
</book>
<book>
<title>框架设计:CLR VIA C#</title>
<borrowDate>2008-12-21</borrowDate>
<returnDate>2009-03-23</returnDate>
<borrowNum>0 续借 </borrowNum>
<isbnNum>TP312C/330</isbnNum>
</book>
</Books> 分别保存了书名,外借时间,应还时间,续借次数,图书ISBN编号等信息。把该文件放到本工程的\bin\Debug目录下,读取时不用写路径,而且项目打包时比较方便,整个项目就放在一个文件夹里。
现在来写BookXML类中的方法,该类中有一个对象是用来对XML文件的操作的,可以用DataSet,但是这种做法用一个不好,就是当文件中没有记录时就出错,必须要保持至少有一条记录,如下:
1
DataSet bookDataSet;2
public BookXML()3


{4
bookDataSet = new DataSet();5
bookDataSet.ReadXml("BookXML.xml");6
}7

8
//取得所有对象9
public List<Book> GetBookList()10


{11
List<Book> bookList = new List<Book>();12
Int32 bookNum = bookDataSet.Tables["book"].Rows.Count;13
for (Int32 i = 0; i < bookNum; i++)14

{ 15
//
16
}17
//
18
}19

如上代码当没有记录时到第12行就出错,因为当XML文件中没有记录时是这样的:
<Books>
</Books>
没有book标签,所以它还对book的引用就出错,所以采用DOM解析,这种方法操作XML文件很方便,如下,我们写了一些增删改方法:
1
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Data;5
using System.Collections;6
using System.Xml;7

8
using LibraryHelper.Model;9

10

11
namespace LibraryHelper.DAL12


{13
public class BookXML14

{15
XmlDocument xmlDoc;16
XmlNode xmlNode;17

18
public BookXML()19

{20
xmlDoc = new XmlDocument();21
xmlDoc.Load("BookXML.xml"); //加载XML文件22
xmlNode = xmlDoc.SelectSingleNode("Books");23
}24

25
//添加26
public Boolean InsertBook(Book insertBook)27

{28
try29

{30
XmlElement xmlNodeBook = xmlDoc.CreateElement("book"); //创建一个标签31

32
XmlElement xmlNodeTitle = xmlDoc.CreateElement("title");//创建一个标签33
xmlNodeTitle.InnerText = insertBook.Title;//设置标签的值34
xmlNodeBook.AppendChild(xmlNodeTitle);//把该标签加到它的父标签中35

36
XmlElement xmlNodeBorrowDate = xmlDoc.CreateElement("borrowDate");//同上37
xmlNodeBorrowDate.InnerText = insertBook.BorrowDate.ToShortDateString();38
xmlNodeBook.AppendChild(xmlNodeBorrowDate);39

40
XmlElement xmlNodeReturnDate = xmlDoc.CreateElement("returnDate");41
xmlNodeReturnDate.InnerText = insertBook.ReturnDate.ToShortDateString();42
xmlNodeBook.AppendChild(xmlNodeReturnDate);43

44
XmlElement xmlNodeBorrowNum = xmlDoc.CreateElement("borrowNum");45
xmlNodeBorrowNum.InnerText = insertBook.BorrowNum;46
xmlNodeBook.AppendChild(xmlNodeBorrowNum);47

48
XmlElement xmlNodeIsbn = xmlDoc.CreateElement("isbn");49
xmlNodeIsbn.InnerText = insertBook.ISBN;50
xmlNodeBook.AppendChild(xmlNodeIsbn);51
52
xmlNode.AppendChild(xmlNodeBook);53

54
xmlDoc.Save("BookXML.xml");55

56
return true;57
}58
catch (Exception ex)59

{60
throw ex;61
}62
}63

64
//取得所有对象65
public List<Book> GetBookList()66

{67
List<Book> bookList = new List<Book>();68
for (Int32 i = 0; i < xmlNode.ChildNodes.Count; i++)69

{70
Book book = new Book();71
book.Title = xmlNode.ChildNodes[i].ChildNodes[0].InnerText;72
book.BorrowDate = Convert.ToDateTime(xmlNode.ChildNodes[i].ChildNodes[1].InnerText);73
book.ReturnDate = Convert.ToDateTime(xmlNode.ChildNodes[i].ChildNodes[2].InnerText);74
book.BorrowNum = xmlNode.ChildNodes[i].ChildNodes[3].InnerText;75
book.ISBN = xmlNode.ChildNodes[i].ChildNodes[4].InnerText;76
bookList.Add(book);77
}78
return bookList;79
}80

81
//取得记录数量82
public Int32 GetBookNum()83

{84
return xmlNode.ChildNodes.Count;85
}86

87
//取得一条记录88
public Book GetSingleBookByRowIndex(Int32 rowIndex)89

{90
Book book = new Book();91
book.Title = xmlNode.ChildNodes[rowIndex].ChildNodes[0].InnerText;92
book.BorrowDate = Convert.ToDateTime(xmlNode.ChildNodes[rowIndex].ChildNodes[1].InnerText);93
book.ReturnDate = Convert.ToDateTime(xmlNode.ChildNodes[rowIndex].ChildNodes[2].InnerText);94
book.BorrowNum = xmlNode.ChildNodes[rowIndex].ChildNodes[3].InnerText;95
book.ISBN = xmlNode.ChildNodes[rowIndex].ChildNodes[4].InnerText;96
return book;97
}98

99
//删除一条记录100
public Boolean DeleteBookByRowIndex(Int32 rowIndex)101

{102
try103

{104
xmlNode.RemoveChild(xmlNode.ChildNodes[rowIndex]);105
xmlDoc.Save("BookXML.xml");106
return true;107
}108
catch (Exception ex)109

{110
throw ex;111
}112
}113

114
//删除所有记录115
public Boolean DeleteAllBook()116

{117
try118

{119
xmlNode.RemoveAll();120
xmlDoc.Save("BookXML.xml");121
return true;122
}123
catch (Exception ex)124

{125
throw ex;126
}127
}128

129
//修改130
public Boolean UpdataBookByRowIndex(Int32 rowIndex,Book updateBook)131

{132
try133

{134
XmlNode updateNode = xmlNode.ChildNodes[rowIndex];135
updateNode.ChildNodes[0].InnerText = updateBook.Title;136
updateNode.ChildNodes[1].InnerText = updateBook.BorrowDate.ToShortDateString();137
updateNode.ChildNodes[2].InnerText = updateBook.ReturnDate.ToShortDateString();138
updateNode.ChildNodes[3].InnerText = updateBook.BorrowNum;139
updateNode.ChildNodes[4].InnerText = updateBook.ISBN;140

141
xmlDoc.Save("BookXML.xml");142

143
return true;144
}145
catch (Exception ex)146

{147
throw ex;148
}149
} 150
}151
}152

我们再建一个UserXML的类,把它的命名空间也改成LibraryHelper.DAL,再建一个UserXML.xml的文件,保存用户登录到图书馆的账号和密码,一样放到bin\Debug目录下,在UserXML类里也写了些简单的方法对UserXML.xml文件的操作,如下:
UserXML.xml:
<?xml version="1.0" encoding="utf-8"?>
<Users>
<User>
<LoginName>20050632540</LoginName>
<Password>850313</Password>
</User>
</Users>
UserXML类:
1
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Xml;5
using LibraryHelper.Model;6

7
namespace LibraryHelper.DAL8


{9
public class UserXML10

{11
XmlDocument xmlDoc;12
XmlNode xmlNode;13

14
public UserXML()15

{16
xmlDoc = new XmlDocument();17
xmlDoc.Load("UserXML.xml"); //加载18
xmlNode = xmlDoc.SelectSingleNode("Users");19
}20

21
//取得User22
public User GetUser()23

{24
User user = new User();25
user.LoginID = xmlNode.ChildNodes[0].ChildNodes[0].InnerText;26
user.Password = xmlNode.ChildNodes[0].ChildNodes[1].InnerText;27
return user;28
}29
30
//保存31
public Boolean SaveUser(User user)32

{33
try34

{35
xmlNode.ChildNodes[0].ChildNodes[0].InnerText = user.LoginID;36
xmlNode.ChildNodes[0].ChildNodes[1].InnerText = user.Password;37
xmlDoc.Save("UserXML.xml");38
return true;39
}40
catch (Exception ex)41

{42
throw ex;43
}44
}45
46
}47
}48

依次再加一个对宽带连接账号信息的xml文件和对该文件操作的类如下:
ADSLXML.xml:
<?xml version="1.0" encoding="utf-8"?>
<ADSL>
<ConnectionName>宽带</ConnectionName>
<UserName>user@xyw</UserName>
<UserPassword>user</UserPassword>
</ADSL>
1
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Xml;5

6
namespace LibraryHelper.DAL7


{8
public class ADSLXML9

{10
XmlDocument xmlDoc;11
XmlNode xmlNode;12

13
public ADSLXML()14

{15
xmlDoc = new XmlDocument();16
xmlDoc.Load("ADSLXML.xml"); //加载17
xmlNode = xmlDoc.SelectSingleNode("ADSL");18
}19

20
//返回用户指定的宽带连接名21
public String GetConnectionName()22

{23
return xmlNode.ChildNodes[0].InnerText;24
}25

26
//返回用户名27
public String GetUserName()28

{29
return xmlNode.ChildNodes[1].InnerText;30
}31

32
//返回密码33
public String GetUserPassword()34

{35
return xmlNode.ChildNodes[2].InnerText;36
}37

38
//保存39
public Boolean SaveADSL(String connectionName, String userName, String userPassword)40

{41
try42

{43
xmlNode.ChildNodes[0].InnerText = connectionName;44
xmlNode.ChildNodes[1].InnerText = userName;45
xmlNode.ChildNodes[2].InnerText = userPassword;46
xmlDoc.Save("ADSLXML.xml");47
return true;48
}49
catch (Exception ex)50

{51
throw ex;52
}53
}54
}55
}56

同样再那一个xml文件用来保存用户的一些配置信息和对该文件操作的类如下:
SettingXML.xml:
<?xml version="1.0" encoding="utf-8"?>
<Setting>
<warningDay>100</warningDay>
<startType>0</startType>
<lastStartTime>2009-3-6</lastStartTime>
<disConnectionADSL>0</disConnectionADSL>
</Setting>
warningDay是说当还剩n天还书时,当n<100时该书就进入警戒范围,用户开机时就给出提示
startType是说系统每次计算机启动时都启动还是每天只启动一次,0为每次都启动,1为每天只能启动一次,所以下面lastStartTime就保存了上一次的登录时间
disConnectionADSL是说当退出该系统时是否自动断开宽带连接,0为断开,1为不断开
对该文件操作的类SettingXML中的一些方法如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace LibraryHelper.DAL
{
public class SettingXML
{
XmlDocument xmlDoc;
XmlNode xmlNode;
public SettingXML()
{
xmlDoc = new XmlDocument();
xmlDoc.Load("SettingXML.xml");
xmlNode = xmlDoc.SelectSingleNode("Setting");
}
//取得进入警戒时间
public String GetWarningDay()
{
return xmlNode.ChildNodes[0].InnerText;
}
//取得启动类型
public String GetStartType()
{
return xmlNode.ChildNodes[1].InnerText;
}
//取得上次启动时间
public String GetLastStartTime()
{
return xmlNode.ChildNodes[2].InnerText;
}
//取得是否断开宽带连接
public String GetDisconnectionADSL()
{
return xmlNode.ChildNodes[3].InnerText;
}
//该设置可能是分开来设置的,所以方法也分开
//设置进入警戒时间
public void SetWarningDay(String warningDay)
{
try
{
xmlNode.ChildNodes[0].InnerText = warningDay;
xmlDoc.Save("SettingXML.xml");
}
catch (Exception ex)
{
throw ex;
}
}
//设置启动类型
public void SetStartType(String startType)
{
try
{
xmlNode.ChildNodes[1].InnerText = startType;
xmlDoc.Save("SettingXML.xml");
}
catch (Exception ex)
{
throw ex;
}
}
//设置上次启动时间
public void SetLastStartTime(String lastStartTime)
{
try
{
xmlNode.ChildNodes[2].InnerText = lastStartTime;
xmlDoc.Save("SettingXML.xml");
}
catch (Exception ex)
{
throw ex;
}
}
//设置是否断开宽带连接
public Boolean SetDisconnectionADSL(String isConnection)
{
try
{
xmlNode.ChildNodes[3].InnerText = isConnection;
xmlDoc.Save("SettingXML.xml");
return true;
}
catch (Exception ex)
{
throw ex;
}
}
}
}
注意到对ADSLXML.xml和SettingXML.xml文件的操作时我们并没有封装到对象,而是用方法每个属性都分开来取,是因为这些可能在不同一个地方使用,这样单个写用得更方便.

浙公网安备 33010602011771号