本节 建立实体类、映射、关系等
1:准备类库组件
<wbr style="line-height:22px">把<span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px">Castle.DynamicProxy.dll</span></span>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px">Iesi.Collections.dll</span></span></div>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px">log4net.dll</span></span></div>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px">NHibernate.dll</span></span></div>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px">SQLite.NET.dll</span></span></div>
<div style="line-height:22px">
<span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px">拷贝到UI的bin\Debug下。</span></span>
<p style="line-height:22px; padding-top:0px; padding-bottom:0px; margin-top:10px; margin-bottom:10px; text-indent:2em">
</p>
<div style="line-height:22px">
<img src="http://img2081.poco.cn/mypoco/myphoto/20111101/09/64469767201111010912461372541192860_022.jpg" alt=""><br>
</div>
</div>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px">2:添加引用</span></span></div>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px">各项目之间添加引用 UI引用BLL , Model; BLL引用DAL , Model ; DAL引用Model。</span></span></div>
<div style="line-height:22px">
<span style="line-height:22px; color:rgb(51,51,51); font-family:Arial">对 DAL 添加</span><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><span style="line-height:22px"><br style="line-height:22px"></span></span><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial">Castle.DynamicProxy.dll<br style="line-height:22px">
Iesi.Collections.dll<br style="line-height:22px">
log4net.dll<br style="line-height:22px">
NHibernate.dll<br style="line-height:22px">
SQLite.NET.dll</span>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial">的引用。</span></div>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><br style="line-height:22px"></span></div>
<div style="line-height:22px">
<span style="line-height:26px; color:rgb(51,51,51); font-family:Arial">3:拷贝数据库文件lstx.db和sqlite3.dll 到UI项目下,</span><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial">并且在文件属性中,将文件的“复制到输出目录”设置为“如果较新则复制”。</span>
</div>
<div style="line-height:22px"><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial"><br style="line-height:22px"></span></div>
<div style="line-height:22px">
<span style="line-height:26px; color:rgb(51,51,51); font-family:Arial">准备工作做好了 我们在Model里写实体类,我就先挑个简单的</span><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial">User类</span><span style="line-height:26px; color:rgb(51,51,51); font-family:Arial">来写吧。</span>
</div>
<div style="line-height:22px"><span style="font-family:Arial; color:#333333; line-height:22px"><span style="line-height:26px">User类在我的数据库中对应o_user表,表中有userID INTEGER,userName VARCHAR,userPwd VARCHAR,playerID INT , 其中playerID 为外键,对应到o_player表中的playerID。类结构如下:</span></span></div>
<div style="line-height:22px">
<span style="font-family:Arial; color:#333333; line-height:22px"><span style="line-height:26px"></span></span><textarea readonly name="code" class="csharp"> public class User
{
#region 成员变量
private int userID { get; set; }
private String userName { get; set; }
private String userPwd { get; set; }
private int playerID { get; set; }
#endregion
#region 构造函数
public User() { }
public User(int uid, String uname, String upwd, int pid)
{
this.userID = uid;
this.userName = uname;
this.userPwd = upwd;
this.playerID = pid;
}
#endregion
}
}
</textarea><br><br>
</div>
<div style="line-height:22px"><span style="font-family:Arial; color:#333333; line-height:22px"><span style="line-height:26px"><br></span></span></div>
<div style="line-height:22px">
<p style="line-height:22px; padding-top:0px; padding-bottom:0px; margin-top:10px; margin-bottom:10px; color:rgb(51,51,51); text-indent:2em">
</p>
<p style="line-height:22px; padding-top:0px; padding-bottom:0px; margin-top:10px; margin-bottom:10px; color:rgb(51,51,51); text-indent:2em">
因为另一个Player类还没有创建 暂时这里的playerID就用一个int来代替吧,我想先看看能不能正常的插入单表数据。</p>
<div style="line-height:22px; color:rgb(51,51,51)"><br style="line-height:22px"></div>
<div style="line-height:22px; color:rgb(51,51,51)">接下来写该类的映射文件</div>
<div style="line-height:22px; color:rgb(51,51,51)">在Model项目里添加一个xml文件User.hbm.xml。</div>
<div style="line-height:22px">
<div style="line-height:22px">
<div style="line-height:22px">
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px">
<textarea readonly name="code" class="html"><?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model" default-lazy="false">
<class name="Model.User, Model" table="o_user">
<id name="userID" column="userID " type="int" unsaved-value="0">
<generator class="increment" />
</id>
<property name="userName" column="userPwd" unique="true" not-null="true" type="String" />
<property name="userPwd" column="userPwd" not-null="true" type="String" />
<property name="playerID" column="playerID" type="String"/>
</class>
</hibernate-mapping></textarea><br><br>
</div>
</div>
</div>
</div>
</div>
<p style="line-height:22px; padding-top:0px; padding-bottom:0px; margin-top:10px; margin-bottom:10px; color:rgb(51,51,51); text-indent:2em">
</p>
<div style="line-height:22px">
<span style="line-height:22px; color:rgb(51,51,51)">assembly="</span><span style="color:#333333; line-height:22px">Model" 这是程序集的名称</span>
</div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">namespace="Model" 这是命名空间的名称</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">class name="Model.User, Model" 指向命名空间下的类文件,</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">table="o_user" 指向数据库中该类对应的表名</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">接下来id标签设置主键</span></div>
<div style="line-height:22px"><span style="line-height:22px; color:rgb(51,51,51)">unsaved-value判断被操作的对象究竟是一个已经持久化过的持久对象还是临时对象</span></div>
<div style="line-height:22px">
<span style="line-height:22px; color:rgb(51,51,51)"></span>
<div style="line-height:22px">默认unsaved-value="null"</div>
<div style="line-height:22px">主键是对象类型,hebernate判断project的主键是否位null,来判断project是否已被持久化</div>
<div style="line-height:22px">是的话,对project对象发送save(project),</div>
<div style="line-height:22px">若自己设置了主键则直接生成update的sql,发送update(project),即便数据库里没有那条记录。</div>
<span style="line-height:22px; color:rgb(51,51,51)"></span>
<div style="line-height:22px">其它的值还有 none,any等 ,但主键是基本类型如int/long/double/ 的话 一般就设置为0,</div>
<div style="line-height:22px; color:rgb(51,51,51)">这样的话save和update操作都不会报错。</div>
<div style="line-height:22px; color:rgb(51,51,51)">再接下来的property标签就没有什么好说的了。最后不要忘记把这个文件的属性设置为嵌入的资源。否则出现“ failed: NHibernate.MappingException : No persister for: NHibernateSample.Domain.Entities.Customer”异常。</div>
<div style="line-height:22px; color:rgb(51,51,51)">
<div style="line-height:22px">
<img src="http://img2081.poco.cn/mypoco/myphoto/20111101/09/64469767201111010912461372541192860_021.jpg" alt=""><br>
</div>
</div>
<div style="line-height:22px; color:rgb(51,51,51)">然后我们去UI项目中添加一个App.config文件,在其中配置hibernate和log4net等</div>
<div style="line-height:22px">
<div style="line-height:22px">
<span style="color:#333333"></span><textarea readonly name="code" class="html"><?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
<section name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.connection.release_mode">on_close</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SQLiteDriver</property>
<property name="connection.connection_string">Data Source=<!-- 数据库名-->lstx.db;Version=3</property>
<property name="dialect">NHibernate.Dialect.SQLiteDialect</property>
<property name="query.substitutions">true=1;false=0</property>
<!-- 在这里添加assembly程序集的话可以减少后面设置程序集的麻烦 它将自动映射Model下所有的配置 -->
<mapping assembly="Model" />
</session-factory>
</hibernate-configuration>
<log4net>
<appender name="console"
type="log4net.Appender.ConsoleAppender, log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern"
value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n" />
</layout>
</appender>
<appender name="fileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<level value="WARN" />
<appender-ref ref="console" />
<appender-ref ref="fileAppender" />
</root>
</log4net>
</configuration>
</textarea>
</div>
</div>
</div>
</div>
</div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"><br></span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">在DAL项目中实现对SQLite的操作访问</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">可能大家的设计思路不一样,我只是介绍我自己的一种方案,高手可以直接跳过去。</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">我觉得一个通用的DAO应该具备以下几种方法:</span></div>
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px">
<textarea readonly name="code" class="csharp">public interface IGenericDao
{
Object save(Object entity); //增加
bool delete(Object entity); //删除
bool deleteById(Type type, object id);//根据主键删除
Object modify(Object obj); //修改
Object findById(Type type, object id);//根据主键查找
IList findByCriteria(ICriteria criteria, Object obj);//QBC查询,我喜欢用,当然你也可以用别的
List<Object> findAll(Type type);//查询所有
List<Object> findByQueryString(String queryString);//字符串查询
}</textarea><br><br>
</div>
我先实现save方法来测试一下是否能正常对SQLlite插入数据</div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">首先实现IGenericDao:</span></div>
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px">
<img src="http://img2081.poco.cn/mypoco/myphoto/20111101/09/64469767201111010912461372541192860_019.jpg" alt=""><br>
</div>
然后创建接口IUserDao,它的实现类UserDao继承自GenericDao.</div>
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px">using System;</div>
<div style="line-height:22px">namespace DAL</div>
<div style="line-height:22px">{</div>
<div style="line-height:22px"> public interface IUserDao</div>
<div style="line-height:22px"> {</div>
<div style="line-height:22px"> void regUser(Model.User user);</div>
<div style="line-height:22px"> }</div>
<div style="line-height:22px">}</div>
<div style="line-height:22px">到这里DAL就可以先放下了 去BLL里写业务逻辑层</div>
<div style="line-height:22px">在BLL里创建接口 IUserService,它的实现类UserService中有一个IUserDao类型的变量.</div>
<div style="line-height:22px">
<div style="line-height:22px">using System;</div>
<div style="line-height:22px">namespace BLL</div>
<div style="line-height:22px">{</div>
<div style="line-height:22px"> public interface IUserService</div>
<div style="line-height:22px"> {</div>
<div style="line-height:22px"> void regUser(Model.User user);</div>
<div style="line-height:22px"> }</div>
<div style="line-height:22px">}</div>
</div>
<div style="line-height:22px">好BLL也写完了,最后是去UI里创建一个测试的窗体Reg.cs.</div>
<div style="line-height:22px">
<div style="line-height:22px">
<img src="http://img2081.poco.cn/mypoco/myphoto/20111101/09/64469767201111010912461372541192860_018.jpg" alt=""><br>
</div>
</div>
<span style="line-height:22px; color:rgb(51,51,51)">namespace UI</span>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">{</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> public partial class Reg : Form</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> {</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> public Reg()</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> {</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> InitializeComponent();</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> }</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> private IUserService service = new UserService();</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"><br style="line-height:22px"></span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> private void btnReg_Click(object sender, EventArgs e)</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> {</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> String name = this.txtUserName.Text;</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> String pwd = this.txtUserPwd.Text;</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> int pid = Int32.Parse(this.txtPlayerID.Text);</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> User user = new User(0, name, pwd, pid);</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> service.regUser(user);</span></div>
<div style="line-height:22px"><span style="line-height:22px; color:rgb(51,51,51)"> }</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"> }</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">}</span></div>
</div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"><br style="line-height:22px"></span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px"><br style="line-height:22px"></span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">到这里我们这个Hibernate+SQLite+MVC基本的配置就写完了</span></div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">来一张现在的解决方案截图;</span></div>
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px">
<img src="http://img2081.poco.cn/mypoco/myphoto/20111101/09/64469767201111010912461372541192860_017.jpg" alt=""><br>
</div>
生成后的Debug目录:</div>
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px">
<div style="line-height:22px">
<img src="http://img2081.poco.cn/mypoco/myphoto/20111101/09/64469767201111010912461372541192860_016.jpg" alt=""><br>
</div>
</div>
<span style="line-height:22px; color:rgb(51,51,51)">我们来插入一个User看看。</span>
</div>
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px"><br></div>
单击注册,啊报错了。。。</div>
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px">
<img src="http://img2081.poco.cn/mypoco/myphoto/20111101/09/64469767201111010912461372541192860_014.jpg" alt=""><br>
</div>
<div style="line-height:22px">could not insert: [Model.User#1][SQL: INSERT INTO o_user (userPwd, userPwd, playerID, userID ) VALUES (?, ?, ?, ?)]</div>
<div style="line-height:22px">不难看出 是我的列名写错了 有两个userPwd,我们去User.hbm.xml中看一下,果然。</div>
<div style="line-height:22px">property name="userName" column="userPwd" 把这里的userPwd改成userName。再试一次。</div>
这次点击注册后没有任何反应了,起码我们知道没有报错了。去数据库里看看。</div>
<div style="line-height:22px"><span style="color:#333333; line-height:22px">我懒得打命令 正好SQL Expert又是打开的 所以我直接进去看了。嗯 ,还真有。</span></div>
<div style="line-height:22px">
<span style="color:#333333; line-height:22px"></span>
<div style="line-height:22px">
<img src="http://img2081.poco.cn/mypoco/myphoto/20111101/09/64469767201111010912461372541192860_013.jpg" alt=""><br>
</div>
<div style="line-height:22px">证明我们之前的配置可以正常的使用Hibernate来操作SQLite。</div>
<div style="line-height:22px">今天写太多了,不知道有没有人发现playerID是一个外键,但是我随便输入了一个Int值它都可以正常插入,</div>
<div style="line-height:22px">这样的看来外键似乎没有起到什么作用。其实我在之前就说过了,不明白的人可以回去看看。就到这里,下次见。</div>
</div>
<div><span style="color:#333333; line-height:22px"><br></span></div>
</wbr>