NHibernate + SQLite + MVC 开发记录.doc_第1页
NHibernate + SQLite + MVC 开发记录.doc_第2页
NHibernate + SQLite + MVC 开发记录.doc_第3页
NHibernate + SQLite + MVC 开发记录.doc_第4页
NHibernate + SQLite + MVC 开发记录.doc_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

NHibernate + SQLite + MVC 开发记录 马上要转向学习Android开发了,打算做一个关于C#的总结项目这是我在后面加上来的图片。我会把实现的步骤一一记录。所有的文章都是我一边调试一边记录的 再加上水平有限 所以在开发过程中不可避免会有很多错误,希望大家谅解。好 下面让我们开始吧 一起解决问题,共同进步。开发环境vs2008+ NHibernate +SQLite 为了避免一些因为使用的类库组件的版本不同而与大家产生的异常出错等,我公布一下各版本号文件名文件版本NHibernate.dll000SQLite.NET.dll0.21.1869.3794Castle.DynamicProxy.dllIesi.Collections.dll000log4net.dllsqlite3.dll3.5.7其中log4net.dll可以不要,sqlite3.dll版本号可以不同没有问题。然后打开VS来建立项目,我是模仿人人网旗下的一款网页游戏乱世天下来写的一个WinForm的单机游戏。项目建立完成后如下图所示其中UI为Windows 窗体应用程序,其它均为类库.第一节先到这里 下一节将建立实体类及映射 配置Nhibernate,SQLite等。现在建立SQLite的数据库 我采用的是一个SQLite可视化的界面开发工具 SQLite Expert,界面如下:新建一个数据库:可以在这里写入SQL这里我只贴出部分代码 大家也不太关心这个, 值得一提是的:每条语句必须以 ; 分号结束。select,insert into.等等 都需要分号结束。每张表的主键如果是INTEGER类型的话 它会自动地增长 而不需要你再去加IDENTITY,但类型必须是INTEGER,int不会自增.建立关系 譬如外键 FOREIGN KEY ,不能像这样:CREATE TABLE IF NOT EXISTS o_user( userID INTEGER PRIMARY KEY, userName VARCHAR(18) UNIQUE NOT NULL,userPwd VARCHAR(18) NOT NULL, playerID INTEGER FOREIGN KEY REFERENCES o_player(playerID) ); 会提示FOREIGN KEY 错误,要像这样写:CREATE TABLE IF NOT EXISTS o_user( userID INTEGER PRIMARY KEY, userName VARCHAR(18) UNIQUE NOT NULL,userPwd VARCHAR(18) NOT NULL, playerID INTEGER , FOREIGN KEY (playerID) REFERENCES o_player(playerID);关于外键还有一点要说,SQLite默认foreign_keys是关闭的,你可以用触发器或者手动设置PRAGMA foreign_keys = ON。接下来我们F5执行这段SQL语句,得到还有很多表目前没有设计完,但不影响前期的开发,我打算后面再去加入它们。然后我们就要去建立实体类和配置文件了,你可以用工具自动生成实体类以及映射文件,譬如说MyGeneration,很久以前就开源了 你可以修改或者制作自己喜欢的模板,但初学者就自己手动创建吧,这样比较容易弄明白各个配置之间的关系,你也就更容易掌握它,调试改错也很快。下一节我们将手动创建这些类和文件。本节 建立实体类、映射、关系等1:准备类库组件把Castle.DynamicProxy.dllIesi.Collections.dlllog4net.dllNHibernate.dll SQLite.NET.dll拷贝到UI的binDebug下。2:添加引用各项目之间添加引用 UI引用BLL , Model; BLL引用DAL , Model ; DAL引用Model。对 DAL 添加Castle.DynamicProxy.dllIesi.Collections.dlllog4net.dllNHibernate.dll SQLite.NET.dll的引用。3:拷贝数据库文件lstx.db和sqlite3.dll 到UI项目下,并且在文件属性中,将文件的“复制到输出目录”设置为“如果较新则复制”。准备工作做好了 我们在Model里写实体类,我就先挑个简单的User类来写吧。User类在我的数据库中对应o_user表,表中有userID INTEGER,userName VARCHAR,userPwd VARCHAR,playerID INT , 其中playerID 为外键,对应到o_player表中的playerID。类结构如下:csharp view plaincopyprint?1. public class User 2.3. 4.5. #region 成员变量 . private int userID get; set; 10.11. private String userName get; set; 12.13. private String userPwd get; set; 14.15. private int playerID get; set; 9. #endregion 3. #region 构造函数 24.25. public User() 26.27. public User(int uid, String uname, String upwd, int pid) 28.29. 30.31. this.userID = uid; 32.33. this.userName = uname; 34.35. this.userPwd = upwd; 36.37. this.playerID = pid; 38.39. 40.41. #endregion 42.43. 因为另一个Player类还没有创建 暂时这里的playerID就用一个int来代替吧,我想先看看能不能正常的插入单表数据。接下来写该类的映射文件在Model项目里添加一个xml文件User.hbm.xml。html view plaincopyprint?1. 2. 3. 4.5. 6. 7. 8.9. 10. 11. 12.13. 14. assembly=Model 这是程序集的名称namespace=Model 这是命名空间的名称class name=Model.User, Model 指向命名空间下的类文件,table=o_user 指向数据库中该类对应的表名接下来id标签设置主键 unsaved-value 判断被操作的对象究竟是一个已经持久化过的持久对象还是临时对象默认unsaved-value=null 主键是对象类型,hebernate判断project的主键是否位null,来判断project是否已被持久化 是的话,对project对象发送save(project), 若自己设置了主键则直接生成update的sql,发送update(project),即便数据库里没有那条记录。 其它的值还有 none,any等 ,但主键是基本类型如int/long/double/ 的话 一般就设置为0,这样的话save和update操作都不会报错。再接下来的property标签就没有什么好说的了。最后不要忘记把这个文件的属性设置为嵌入的资源。否则出现“ failed: NHibernate.MappingException : No persister for: NHibernateSample.Domain.Entities.Customer”异常。然后我们去UI项目中添加一个App.config文件,在其中配置hibernate和log4net等html view plaincopyprint?1. 2. 3. 4. 6. 8. 9.10. 11. 12. true 13. on_close 14. NHibernate.Connection.DriverConnectionProvider 15. NHibernate.Driver.SQLiteDriver 16. Data Source=lstx.db;Version=3 17. NHibernate.Dialect.SQLiteDialect 18. true=1;false=0 19. 20. 21. 22. 23.24. 25. 27. 28. 30. 31. 32.33. 34. 35. 36. 37. 38. 39. 40.41. 42. 43. 44. 45. 46. 47.48. 在DAL项目中实现对SQLite的操作访问可能大家的设计思路不一样,我只是介绍我自己的一种方案,高手可以直接跳过去。我觉得一个通用的DAO应该具备以下几种方法:csharp view plaincopyprint?1. public interface IGenericDao 2. 3. Object save(Object entity); /增加 4.5. bool delete(Object entity); /删除 6.7. bool deleteById(Type type, object id);/根据主键删除 8.9. Object modify(Object obj); /修改 10.11. Object findById(Type type, object id);/根据主键查找 12.13. IList findByCriteria(ICriteria criteria, Object obj);/QBC查询,我喜欢用,当然你也可以用别的 14.15. List findAll(Type type);/查询所有 16.17. List findByQueryString(String queryString);/字符串查询 18. 我先实现save方法来测试一下是否能正常对SQLlite插入数据首先实现IGenericDao:然后创建接口IUserDao,它的实现类UserDao继承自GenericDao.using System;namespace DALpublic interface IUserDaovoid regUser(Model.User user);到这里DAL就可以先放下了 去BLL里写业务逻辑层在BLL里创建接口 IUserService,它的实现类UserService中有一个IUserDao类型的变量.using System;namespace BLLpublic interface IUserServicevoid regUser(Model.User user);好BLL也写完了,最后是去UI里创建一个测试的窗体Rspace UIpublic partial class Reg : Formpublic Reg()InitializeComponent();private IUserService service = new UserService();private void btnReg_Click(object sender, EventArgs e)String name = this.txtUserName.Text;String pwd = this.txtUserPwd.Text;int pid = Int32.Parse(this.txtPlayerID.Text);User user = new User(0, name, pwd, pid);service.regUser(user);到这里我们这个Hibernate+SQLite+MVC基本的配置就写完了来一张现在的解决方案截图;生成后的Debug目录:我们来插入一个User看看。单击注册,啊报错了。could not insert: Model.User#1SQL: INSERT INTO o_user (userPwd, userPwd, playerID, userID ) VALUES (?, ?, ?, ?)不难看出 是我的列名写错了 有两个userPwd,我们去User.hbm.xml中看一下,果然。property name=userName column=userPwd 把这里的userPwd改成userName。再试一次。这次点击注册后没有任何反应了,起码我们知道没有报错了。去数据库里看看。我懒得打命令 正好SQL Expert又是打开的 所以我直接进去看了。嗯 ,还真有。证明我们之前的配置可以正常的使用Hibernate来操作SQLite。今天写太多了,不知道有没有人发现playerID是一个外键,但是我随便输入了一个Int值它都可以正常插入,这样的看来外键似乎没有起到什么作用。其实我在之前就说过了,不明白的人可以回去看看。就到这里,下次见。今天来处理SQLite中外键的关系,它又包括一对一关联映射,还有一对多,多对一,多对多,我将只对我用到的进行讲解,如果你想知道更详细的资料,请私下与我联系。昨天说到,o_user表中有playerID映射到o_player中的playerID,我们可以想像一下,随便找一款游戏,你要试玩的话,首先你要注册一个帐号user,然后登录游戏后因为你一个角色都没有,系统会跳转到创建角色界面,这里你可能可以创建一个角色,也可以创建两个,三个之类的player。也就是说 一个帐号,可以创建多个角色。这样我们就说user表中的playerID与player中的playerID是多对一的关系映射。html view plaincopyprint?1. 于是我们在User.hbm.xml中 把原来测试用的那个int型的playerID换成这里顺便提一下,如果类中的属性名与其对应的表中对应的列名完全一样的话,我们可以缩写成这样: 接下来我们去建立Player类与其对应的Dao,Service。映射文件你可以单独写一个,也可以全部写在一个.hbm.xml中,以class标签声明。然后到窗体中,修改一下界面。添加User的构造函数csharp view plaincopyprint?1. public User() 2.3. public User(String uname, String upwd) 4. 5. init(-1, uname, upwd, null); 6. 7.8. public User(String uname, String upwd,Player player) 9. 10. init(-1, uname, upwd, player); 11. 12.13. public User(int uid, String uname, String upwd, Player player) 14. 15. init(uid, uname, upwd, player); 16. 17.18. private void init(int uid, String uname, String upwd, Player player) 19. 20. if (uid = 0) this.userID = uid; 21. this.userName = uname; 22. this.userPwd = upwd; 23. this.player = player; 24. 好现在我们开始测试注册。可以看到数据正常的插入了。但我们又想,要是想在注册的时候 给它一个默认的Player角色。Player player = new Player(玩家, 200, 1000, 5, 1, 0, 0, 20, 平民);userService.regUser(new User(name, pwd, player);好吧出错了。这样是因为我们配置了映射关系,但在Player表中并没有我刚刚实例化的这个Player对象。于是我们先插入这个玩家角色。为了使用方便 我创建了一个存放所有的Services给UI层调用的类:namespace BLLpublic static class Servicespublic static IUserService userService = new UserService();public static IPlayerService playerService = new PlayerService();然后在注册界面创建一个Player给它private void btnReg_Click(object sender, EventArgs e)String name = this.txtUserName.Text;String pwd = this.txtUserPwd.Text;Player player = new Player(玩家, 200, 1000, 5, 1, 0, 0, 20, 平民);User user = new User(name, pwd, player);BLL.Services.playerService.savePlayer(player);BLL.Services.userService.regUser(user);注册成功了同时它的playerID为1,在o_player表中也可以找到该条数据到这里我们的关系映射就做完了。其它的一对一,一对多,多对多也差不多是大同小异。这就是一个简单而完整的Hibernate+SQLite+MVC示例,后面我会继续写下去,不过不会再这么详细了,我会公布这个游戏的开发进度,希望大家能继续关注我的项目,同时也期待与大家一起探讨,共同进步。今天在学习Android的过程中有太多漫不经心,我也知道是我不对,但我从学习C#到现在 写过很多项目,像植物大战僵尸,斗地主这些 全部都只是完成了一个大概,没有一个是100%完成的,这是最后一个项目,我不想再像以前那样,有开始 便要有结束,我会尽快写完这个项目的,然后投身在Android开发去。18:35 2011-10-30完成登录界面 附图20:01 2011-10-30完成角色界面 附图20:30 2011-10-30完成背景介绍 暂时告一段落 发张我的桌面秀下Desktop.show();主界面 未完成 重新设计了一下数据库,改动很大。其中我考虑了一下 首先我要有个最原始的武将库资料,这里装着所有武将的基本属性,然后各个玩家达到条件都可以招募他,都可以去加强属性,还有穿戴装备之类的操作,于是我把武将的原始属性统一放在一张表里,sql view plaincopyprint?1. CREATE TABLE IF NOT EXISTS o_hero( -武将 2. heroID INTEGER PRIMARY KEY, 3. hname VARCHAR(10) UNIQUE NOT NULL, 4. price INTEGER NOT NULL, -招募价格 5. skillID INTEGER NOT NULL,-技能 外键 6. armID INTEGER NOT NULL, -兵种 外键 7. heroPic VARCHAR(255) NOT NULL,-头像 路径 8. heroIntro VARCHAR(255) NOT NULL,-介绍 9. governing INTEGER NOT NULL, -统御 10. force INTEGER NOT NULL, -武力 11. intelligence INTEGER NOT NULL, -智力 12.13. FOREIGN KEY (skillID) REFERENCES o_skill(skillID), 14. FOREIGN KEY (armID) REFERENCES o_arm(armID) 15. ); 这里的属性不管玩家怎么操作它都是不会变的,然后我建立了一张关系表 r_playerAndHeros:sql view plaincopyprint?1. CREATE TABLE IF NOT EXISTS r_playerAndHeros( 2. r_PHID INTEGER PRIMARY KEY, 3. playerID INTEGER NOT NULL, 4.5. hero

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论