NHibernate主要数据操作方法 | 2007-1-24 11:52:14 | |
一 NHibernate简介
二 NHibernate中主要接口的介绍
ISession
ISession是面向用户的主要接口,主要用于对象持久化,数据加载等操作,支持数据库事务,它隐藏了NHB内部复杂的实现细节,ISession由ISessionFactory创建。
ISessionFactory
ISessionFactory是NHB内部的核心类,它维护到持久机制(数据库)的连接并对它们进行管理,同时还会保存所有持久对象的映射信息。 ISessionFactory由Configuration创建,因为创建ISessionFactory的开销非常大(需要加载映射信息),所以这个对象一般使用Singleton(单例)模式。
ITransaction
ITransaction是NHB的事务处理接口,它只是简单的封装了底层的数据库事务。 事务必须由ISession来启动。
ICriteria
ICriteria是Expression(表达式)数据加载接口,Expression是一个关系表达式组合,通过它能产生SQL语句的Where部分, 用户需要通过ISession来间接调用它。
IQuery
IQuery是HQL数据加载接口,HQL(Hibernate Query Language)是NHB专用的面向对象的数据查询语言,它与数据库的SQL有些类似,但功能更强大!同ICriteria一样,也需要通过ISession来间接调用它。
三 HQL数据加载
NH中,HQL是一个十分强大的面向对象的查询语言,简单的说,就是不需要使用实际的表名和列名来查询数据,而改用类名和属性。
有两种方式来执行HQL数据加载,一种是直接使用ISession的Find方法,另一种是使用IQuery接口。 IQuery最终还是会调用ISession的Find方法,下面来分析一下IQuery中HQL语句的处理. 示例代码 : 1、 IQuery query = session.CreateQuery( " from User u where u.Name = :Name " ) query.SetString( "Name", "billy" ); IList users = query.List();
2、 IList users = session.Find(" from User u where u.Name = ‘billy");
四 NHibernate数据加载之Criteria加载
Criteria是通过一组条件表达式(Expression)来加载数据的,它返回满足条件的对象集合。
主要接口为ICriteria,实现为CriteriaImpl类,此类加有Internal修饰,因此不能在程序集外显示创建,nhibernate在session对象中为我们提供了一个方法CreateCriteria,此方法返回ICriteria接口。
这里列出了ICriteria接口的一些方法:
SetMaxResults:设置返回的最大结果数,可用于分页; SetFirstResult:设置首个对象返回的位置,可用于分页; SetTimeout:设置操作的超时值,此值将传递给IDbCommand对象; Add:加入条件表达式(Expression对象),此方法可多次调用以组合多个条件; AddOrder:加入排序的字段(Order对象); List:返回满足条件的对象集合。
Criteria数据加载的关键就在Expression对象上,此对象组成了查询语句的where部分。
Expression是一个abstract(抽象)类,它通过一组static方法实现Factory Method(工厂方法)模式,这些static方法返回的都是Expression类的子类,下面列出一些常用的: Eq:返回EqExpression,这是一个相等判断的表达式; Like:返回LikeExpression,这是一个like判断的表达式; Gt:返回GtExpression,这是一个大于判断的表达式; And:返回AndExpression,这是两个表达式And操作后的表达式; Or:返回OrExpression,这是两个表达式Or操作后的表达式;
更多的Expression请参考相关文档或源代码。
下面以几个例子来说明Criteria数据加载的用法: 1. 取得用户名(username)为billy的用户对象: Expression ex = Expression.Eq( "Username", "billy" ); IList users = session.CreateCriteria(typeof(User)).Add( ex ).List(); 2.取得用户名(username)为billy, 密码为123456的用户对象 Expression ex = Expression.And( Expression.Eq("Username", "billy"), Expression.Eq("Password", "123456") ); IList users = session.CreateCriteria(type(User)).Add( ex ).List(); 3. 取得数据中第20-40的用户对象。 IList users = session.CreateCriteria(typeof(User)) .SetFirstResult(20).SetMaxResults(40) .List(); 对于SQLSERVER,数据定位采用的是IDataReader前滚至firstResult处,然后取maxResults条记录。
4. 取得按注册日期(Regdate)降序排序后的用户对象.
ICriteria c = session.CreateCriteria(typeof(User)); IList users = c.AddOrder( Order.Desc("Regdate") ).List();
五 多表关联的查询
1、添加持久化类
1〉、创建持久化类:
public class AssociateJoinIssues
{ int _issueID;
public int IssueID
{
get { return _issueID; }
set { _issueID = value; }
}
string _IssueSubject;
public string IssueSubject
{ get { return _IssueSubject; }
set { _IssueSubject = value; }
}
string _IssueDetectedDate;
public string IssueDetectedDate
{ get { return _IssueDetectedDate; }
set { _IssueDetectedDate = value; }
}
string _IssueLastestResponseDate;
public string IssueLastestResponseDate
{
get { return _IssueLastestResponseDate; }
set { _IssueLastestResponseDate = value; }
}
string _CreatedDate;
public string CreatedDate
{
get { return _CreatedDate; }
set { _CreatedDate = value; }
}
string _CreatedUser;
public string CreatedUser
{ get { return _CreatedUser; }
set { _CreatedUser = value; }
}
public AssociateJoinIssues(int IssueID, string IssueSubject, DateTime IssueDetectedDate, Nullables.NullableDateTime IssueLastestResponseDate, DateTime CreatedDate, string CreatedUser)
{
this._issueID = IssueID;
this._IssueSubject = IssueSubject;
this._IssueDetectedDate = IssueDetectedDate.ToShortDateString();
this._IssueLastestResponseDate = IssueLastestResponseDate.ToString();
this._CreatedDate = CreatedDate.ToShortDateString();
this._CreatedUser = CreatedUser;
}
}
2〉 、影射文件里添加持久化类的引用
RIssues.hbm.xml
3〉、查询语句
public IList RetrieveSpecifiedIssues(int AssociateItemid, string AssociateItem, int issueStatus)
{
ISession vSession = HibernateUtil.Session();
string hql = "select new AssociateJoinIssues(i.Issueid,i.IssueSubject,i.IssueDetectedDate,"
+ "i.IssueLastestResponseDate,i.CreatedDate,u.UserDisplayName) from RIssues as ri join ri.Issueid as i join ri.Issueid.CreatedByUserid as u "
+ " where ri.AssociateItem=:aitem and ri.AssociateItemid=:aitemid and i.IssueStatus=:issueStatus";
IQuery query = vSession.CreateQuery(hql);
query.SetString("aitem", AssociateItem);
query.SetInt32("aitemid", AssociateItemid);
query.SetInt32("issueStatus", issueStatus);
IList Results = query.List();
return Results;
}
六 删除
1、删除主表中的记录,首先要删除它的关联表中的记录
之后再删除主表中的记录
Parent p = session.Load( typeof( Parent ), pid ) as Parent;
Child c = null;
foreach( Child child in p.Children )
{
c = child;
p.Children.Remove( c );
c.Parent = null;
session.Delete( c );
session.Delete(p);
}
2、级联删除很少使用(删除主表记录时自动去删除子表记录)
七 修改
1、
private bool UpdateObjectiveCompletion(ArrayList arrList, int objectiveID)
{
ISession vSession = HibernateUtil.Session();
OmObjectives omObjective = vSession.Load(typeof(OmObjectives), objectiveID) as OmObjectives;
omObjective.Objectivepid = omObjective.Objectivepid;
omObjective.ObjectiveCode = omObjective.ObjectiveCode;
omObjective.ObjectiveSubject = omObjective.ObjectiveSubject;
omObjective.ObjectiveDesc = omObjective.ObjectiveDesc;
omObjective.ObjectiveStartDate = omObjective.ObjectiveStartDate;
omObjective.ObjectiveEndDate = omObjective.ObjectiveEndDate;
omObjective.ObjectiveLastingDays = omObjective.ObjectiveLastingDays;
omObjective.SystemOptionItemGradeid = omObjective.SystemOptionItemGradeid;
omObjective.SystemOptionItemTypeid = omObjective.SystemOptionItemTypeid;
omObjective.CreatedDate = omObjective.CreatedDate;
omObjective.CreatedByUserid = omObjective.CreatedByUserid;
omObjective.ObjectiveWeight = omObjective.ObjectiveWeight;
omObjective.ObjectiveQuota = omObjective.ObjectiveQuota;
omObjective.OrgUnitid = omObjective.OrgUnitid;
omObjective.Userid = omObjective.Userid;
omObjective.ObjectiveCompletionAmount = decimal.Parse(arrList[0].ToString());
omObjective.ObjectiveCompletionPercentage = int.Parse(arrList[1].ToString());
omObjective.ObjectiveCompletionDate = Convert.ToDateTime(arrList[2].ToString());
omObjective.ObjectiveStatus = 4;
vSession.Update(omObjective);
return true;
}
2、
private bool UpdateObjectiveCompletion(ArrayList arrList, int objectiveID)
{
ISession vSession = HibernateUtil.Session();
OmObjectives omObjective = vSession.Load(typeof(OmObjectives), objectiveID) as OmObjectives;
omObjective.ObjectiveCompletionAmount = decimal.Parse(arrList[0].ToString());
omObjective.ObjectiveCompletionPercentage = int.Parse(arrList[1].ToString());
omObjective.ObjectiveCompletionDate = Convert.ToDateTime(arrList[2].ToString());
omObjective.ObjectiveStatus = 4;
vSession.Save(omObjective);
return true;
vSession.Close();
}
3、注意:
多个表关联时,要用一个Session,事务才有效。
我们知道,数据库中DateTime子段允许为空(null)。当我们在ASP.NET中映射为DateTime是就不允为空了。该怎么处理?基本有两种办法:
1、修改.hbm.xml文件中的类型,该"DateTime"为"String",该实体文件中的属性类型"DateTime"为"String"。 处理的时候,该属性值要么为空,要么是具有正确日期格式的字符串。 该方法只适合DateTime类型,而对int,bool类型就不适应了。下面就看第二种方法。 2、Nullables处理 (1)添加引用:Nullables.dll与Nullables.NHibernate.dll
NHibernate.Mapping.Attributes.dll
(2)修改配置文件.hbm.xml对应的类型,如: (3)修改实体类文件,如: private DateTime _inDate; /// /// 添加日期 /// public DateTime InDate { get { return _inDate; } set { _inDate = value; } 修改为: private Nullables.NullableDateTime _InDate; /// /// 添加日期 /// [NHibernate.Mapping.Attributes.Property] public Nullables.NullableDateTime InDate { get { return _InDate; } set { _InDate = value; } } (4)给属性InDate赋值: Item clsItem = new Item(); clsItem.InDate = new NullableDateTime(System.DateTime.Now); 如果要输入空值,如:clsItem.InDate = nulll; (5)获取属性InDate的值: ItemCRUD clsCRUD = new ItemCRUD(); //对实体类的操作 Item clsItem = clsCRUD.ItemDetails(id); //获取实体类 this.txtInDate.Text = clsItem.InDate.ToString(); 通过第二种方法可以对数据库中对应的整形、bool类型等赋空值。 |