一、NHibernate简单介绍
1. NHibernate是一个面向.NET 环境的对象/关系数据库映射工具
2. NHibernate不仅仅管理.NET 类到数据库表的映射(包括.NET 数据类型到SQL 数据类型的映射),还提供数据查询和获取数据的方法
一、NHibernate的小项目:建立数据库表-----编写持久化类-----编写映射文件-----编写配置----编写factory----编写函数库-----应用
3. 使用NHibernate的步骤:
(1) 获取NHhibernate,有2.0、3.3版本
注意:NHibernate3.2或以上的版 NHibernate.ByteCode.Castle.dll,
NHibernate.ByteCode.LinFu.dll, NHibernate.ByteCode.Spring.dll 这三个DLL了,
hibernate.cfg.xml 配置文件中的 proxyfactory.factory_class要修改如下:
<property name="proxyfactory.factory_class">NHibernate.Bytecode.DefaultProxyFactoryFactory,NHibernate</property>
(2) 建立数据库
(3) 创建c#类库文件domain,data,data.test
(4) 设计Domain:
1) 编写持久化类(model)可用动软生成,不过字段要设置为virtual.
注意NHibernate默认使用代理功能,要求持久化类不是sealed的,而且其公共方法、属性和事件声明为virtual。
2) 编写映射文件
注意:a.文件后缀名为hbm.xml.对应表的对象
b. XML文件的默认生成操作为“内容”,这里需要修改为“嵌入的资源”生成
(5) 编写数据访问层
1) 辅助类:NHibernateHelper NHibernateFactory
注意:using NHibernate;using NHibernate.cfg;UsingNHibernate.engine;
2) 编写操作
(6) 编写数据访问层的测试
1) 配置NHibernate,cfg.xml
注意:XML文件的默认“复制到输出目录”为“不复制”,这里需要修改为“始终复制”
2) 测试
(7) 完成
4. 三层架构:model,数据访问层,业务逻辑bll层,表示层
二、NHibernate的查询语句HQL
1.from子句:返回表中所有数据
public IList<Customer> From()
{
return_session.CreateQuery("form Customer").List<Customer>();
}
2.select语句:在结果集中返回指定的对象和属性
Eg: public IList<Int32> GetID()
{
return_session.CreateQuery("select c.CustomerId fromCustomer c").List<Int32>();
}
还可以返回Object[],如select c.Firstname,count(c.Firstname) from Customer cgroup by c.Firstname
也就是查找了多个不同类型的属性
3.distinct和all用法
Select distinctc.firstname from c
5. where子句
eg:public IList<Customer>where()
{
return_session.CreateQuery("from c wherec.FirstName='zuo'").List<Customer>();
}
6. orderby子句
eg:desc esc
7. groupby
8. HQL的书写方式
Eg://写法1 //return _session.CreateQuery("from Customer c wherec.Firstname='" + firstname + "'") // .List<Customer>();
//写法2:位置型参数
//return_session.CreateQuery("from Customer c where c.Firstname=?") //.SetString(0, firstname) // .List<Customer>();
命名型参数(推荐)
public IList<Customer> GetCustomerByFirstname(string firstname)
{
return_session.CreateQuery("from c wherec.Firstname=:fn").SetString("fn",firstname).List<Customer>();
}
总结方法:
写法1:可能会引起SQL注入,不要使用。 写法2:ADO.NET风格的?参数,NHibernate的参数从0开始计数。 写法3:命名参数用:name的形式在查询字符串中表示,这时IQuery接口把实际参数绑定到命名参数。 写法4:命名的参数列表,把一些参数添加到一个集合列表中的形式,比如可以查询数据是否在这个集合列表中。
三.条件查询(criteria query)using NHibernate.Criterion
1.创建ICriteria实例(标准)
Eg: public IList<Customer> CreateCriteria()
{
ICriteriacrit = _session.CreateCriteria(typeof(Customer));
crit.SetMaxResults(50);
IList<Customer> customers = crit.List<Customer>();
returncustomers;
}
2.结果集限制
Eg: public IList<Customer> Narrowing()
{
return_session.CreateCriteria(typeof(Customer)).Add(Restrictions.Like("Firstname","zuo")).Add(Restrictions.Between("Lastname","A%","Y%")).List<Customer>();
}
3.结果集排序
Eg:false 降序,true升序
public IList<Customer> order()
{
return_session.CreateCriteria(typeof(Customer)).AddOrder(newNHibernate.Criterion.Order("Firstname",false)).List<Customer>();
}
4、根据实例查询(Query by Example)
四、增删改
1.新建对象:调用ISession.Save(),同步ISession
Eg:
public intCreateCustomer(Customer customer) { int newid = (int)_session.Save(customer);_session.Flush(); return newid; }
2.删除对象:获取一个对象;调用ISession.Delete();同步ISession
Eg:public voiddeletesample(Customer c)
{
_session.Delete(c);
_session.Flush();
}
3.更新对象
Eg:public voidupdatesample(Customer c)
{
_session.Update(c);
_session.Flush();
}
4.保存更新对象:SaveOrUpdate()
五、NHibernate事务
Eg: ITransaction tx = Session.BeginTransaction();
tx.Commit();
using(ITransaction tx = Session.BeginTransaction())
{
try
{
//deleteadd update
tx.Commit();
}
catch(Exception)
{
tx.Rollback();
throw;
}
}
六、并发控制
1. 当许多人试图同时修改数据库中的数据时,必须实现一个控制系统,使一个人所做的修改不会对他人所做的修改产生负面影响。这称为并发控制。
NHibernate支持乐观并发控制
七.巧用组件之依赖对象56
不需要修改数据库,在model和映射中修改即可,但是要写一个关于此组件的方法,获得组件的值
八.父子关系,主外键的关系,多表查询,一对多关系
1.NHibernate的集合类型:bag,set,list,map
2.eg:
Customer(主)del:public IList<Order> Orders{ get; set; }
Order: public virtual ISet<Order> Orders { get; set; }
父子关联映射:
Customer.hbm.xml映射文件:
<!--一对多关系:Customer有一个或多个Orders--> <setname="Orders" table="`Order`" generic="true"inverse="true"> <key column="Customer"foreign-key="FK_CustomerOrders"/> <one-to-manyclass="DomainModel.Entities.Order,DomainModel"/> </set>
Order.hbm,.xml:
<!--多对一关系:Orders属于一个Customer--> <many-to-onename="Customer" column="Customer" not-null="true"class="DomainModel.Entities.Customer,DomainModel"foreign-key="FK_CustomerOrders" />
十.关联查询
一对多关联查询
1. 原生SQL关联查询
Eg: public IList<Customer> UseSQL(DateTimeorderDate)
{
return_session.CreateSQLQuery("select distionct{customer.*} from Customer{customer} inner join [order] o ono.CustomerID={customer}.CUstomerId where o.OrderDate : orderDate").AddEntity("customer",typeof(Customer)).SetDateTime("orderDate",orderDate).List<Customer>();
}
2. HQL关联查询
3. Criteria API关联查询
Eg:存在多余的列
public IList<Customer> userCriteriaAPI(DateTime orderDate)
{
return_session.CreateCriteria(typeof(Customer)).CreateCriteria("Order").Add(Restrictions.Gt("OrderDate",orderDate)).List<Customer>();
}
欲过滤:
public IList<Customer> userCriteriaAPI(DateTime orderDate)
{
return_session.CreateCriteria(typeof(Customer)).CreateCriteria("Order").Add(Restrictions.Gt("OrderDate",orderDate)).SetResultTransformer(newNHibernate.Transform.DistinctRootEntityResultTransformer).List<Customer>();
}
应用投影去除重复的列:
return _session.CreateCriteria(typeof(Customer)).SetProjection(Projections.Distinct(Projections.ProjectionList().Add(Projections.Property("CustomerId")))).CreateCriteria("Order").Add(Restrictions.Gt("OrderDate",orderDate)).List<Customer>();
十一.多对多关系及查询
1. 多对多关系引入
(1)model //多对多关系:Order有多个Products publicvirtual IList<Product> Products { get; set; }
(2)Order.hbm.xml:
Eg: <bagname="Orders"generic="true"table="OrderProduct">
<keycolumn="Product"foreign-key="FK_ProductOrder"/>
<many-to-manycolumn="'Order'"class="DomainModel.Entities.order,DomainModel"foreign-key="FK_OrderProduct"/>
</bag>
2. 多对多映射关系
3. 多对多关联查询
(1) SQL:
Sql语句:select * from dbo.Customer c inner join [Order] o on c.CoustomerId=o.CustomerId inner join dbo.OrderProduct op on o.OrderId=op.OrderId inner join dbo.Product p on op.ProductId =p.ProductId where c.CoustomerId=1
Eg: public IList<Customer>UseSQL_GetCustomersWithOrdersHavingProduct(DateTime orderDate) { return_session.CreateSQLQuery("select distinct {customer.*} from Customer{customer}" + " inner join [Order] o ono.Customer={customer}.CustomerId"+ " inner join OrderProduct op ono.OrderId=op.[Order]"+ " inner join Product p on op.Product=p.ProductIdwhere o.OrderDate> :orderDate") .AddEntity("customer",typeof(Customer)) .SetDateTime("orderDate", orderDate).List<Customer>(); }
(2) HQL:
Eg: public IList<Customer> userHQL_G(DateTimeorderDate)
{
return_session.CreateQuery("select distinct c formCustomer c, c.Orders.elements o where o.OrderDate>:orderDate").SetDateTime("orderDate", orderDate).List<Customer>();
}
(3) 条件查询,criteria API
Eg: return _session.CreateCriteria(typeof(Customer)).Add(Restrictions.Eq("Firstname","YJing")).Add(Restrictions.Gt("orderDate",orderDate)).CreateCriteria("Orders").CreateCriteria("Products").Add(Restrictions.Eq("Name","Cnblogs")).List<Customer>();
十四.视图
1.创建视图
CREATE VIEW [dbo].[Customer_Order_view]
AS
SELECT dbo.Customer.CoustomerId, dbo.Customer.Firstname, dbo.Customer.Lastname, dbo.[Order].OrderId, dbo.[Order].OrderDate
FROM dbo.Customer INNER JOIN
dbo.[Order] ON dbo.Customer.CoustomerId = dbo.[Order].CustomerId
GO
2.持久化类。Model
2.映射文件
<?xmlversion="1.0" encoding="utf-8" ?> <hibernate-mappingxmlns="urn:nhibernate-mapping-2.2" assembly="DomainModel"namespace="DomainModel"> <classname="DomainModel.Entities.CustomerView,DomainModel"table="viewCustomer" mutable="false" > <idname="CustomerId" column="CustomerId"type="Int32"> <generator class="native" /></id> <property name="Firstname"column="Firstname" type="string" /> <propertyname="Lastname" column="Lastname" type="string"/> <property name="OrderId" column="OrderId"type="Int32" /> <property name="OrderDate"column="OrderDate" type="DateTime" /> </class></hibernate-mapping>
4. 测试
十五.存储过程
公司NHibernate步骤:
主要包括项目:
1. GetPracScoreService
2. JSTMBS.BLL
3. JSTMBS.Model
4. Test
1. 配置NHibernate:在test中的app.config文件中:放在 GetPracScoreService
Eg:
<configSections>
<sectionname="nhibernate"type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"/>
<sectionname="log4net"type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<nhibernate>
<addkey="show_sql"value="true"/>
<addkey="hibernate.connection.provider"value="NHibernate.Connection.DriverConnectionProvider"/>
<addkey="hibernate.dialect"value="NHibernate.Dialect.MsSql2000Dialect"/>
<addkey="hibernate.connection.driver_class"value="NHibernate.Driver.SqlClientDriver"/>
<addkey="hibernate.connection.connection_string"value="Server=172.23.30.97;Database=OrgUser;UserID=sa;Password=suypower;Trusted_Connection=False"/>
</nhibernate>
2. 配置对象关系映射:放在model层,和model放在一起
Id:特殊列
其他一般包括:name, column, type, length, not-null
特殊包括:many-to-one one-to-more many-to-many
Eg:
<?xmlversion="1.0"encoding="utf-8" ?>
<hibernate-mappingxmlns="urn:nhibernate-mapping-2.0">
<classname="Suypower.DataAccess.Data.Users,Suypower.DataAccess.Data"table="Users">
<idname="Userid"column="UserID"type="Int32"unsaved-value="0">
<generatorclass="native"/>
</id>
<many-to-onename="Orgid"column="OrgID" class="Suypower.DataAccess.Data.Organizes,Suypower.DataAccess.Data" />
<propertycolumn="UserName"type="String"name="UserName"not-null="true"length="20" />
<propertycolumn="LoginName"type="String"name="LoginName"not-null="true"length="20" />
<propertycolumn="LoginPwd"type="String"name="LoginPwd"not-null="true"length="20" />
<propertycolumn="Remark"type="String"name="Remark"not-null="true"length="200" />
<propertycolumn="CreateDate"type="DateTime"name="CreateDate"not-null="true" />
</class>
</hibernate-mapping>
注意:
映射的XML文件要以“.hbm.xml”为后缀,并且映射文件要包含在项目中,其属性“生成操作”要设置为“嵌入的资源”。
3. 建立NHibernate的SessionFactory类:放在BLL
Eg:
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Engine;
using JSTMBS.Model;
using JSTMBS.SJTException;
private static ISessionFactory sessions;
private staticConfiguration cfg;
public static ISession OpenSession()
{
try
{
if(sessions == null)
{
BuildSessionFactory();
}
returnsessions.OpenSession();
}
catch(Exception err)
{
throw;
}
}
private static void BuildSessionFactory()
{
cfg = newConfiguration();
try
{
cfg.AddAssembly("SJTSoft.DataAccess.Data");
}
catch(Exception err)
{
throw;
}
sessions =cfg.BuildSessionFactory();
}
4. 业务逻辑编写
Eg:增删改查
public IList GetUserList()
{
ISessionssion = SessionFactory.OpenSession();
try
{
returnssion.CreateCriteria(typeof(Users)).List();
}
catch(Exception err)
{
thrownew Exception("列出所有的用户时发生错误,请与管理员联系!" + err.Message);
}
finally
{
ssion.Close();
ssion.Dispose();
}
}
5. NHIbernate的使用
Eg: <configSections>
<sectionname="hibernate-configuration"type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
</configSections>
<!-- NHibernate配置 thread_static-->
<hibernate-configurationxmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<!-- SQL Server 2000-->
<propertyname="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
<propertyname="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<propertyname="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<propertyname="connection.connection_string">Server=localhost;Database=CPS;UserID=sa;Password=sjtsoft</property>
<propertyname="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<propertyname="use_outer_join">true</property>
<propertyname="command_timeout">60</property>
<propertyname="current_session_context_class">thread_static</property>
<propertyname="show_sql">true</property>
<mappingassembly="SJTSoft.Core"/>
<mappingassembly="SJTSoft.JSTMIISF.Model"/>
</session-factory>
</hibernate-configuration>