NHibernate 学习20101103
最近在看李永京的NHibernate文章 "传送门",做了下DEMO。
后期借助这个DEMO 来加Spring.net 和MVC 以及购物车 做个总结,以便日后留用...
表两张 Customer、Order. 数据库 Oracle 10g
结构参考
Customer XML配置:
<?xml version="1.0" encoding="utf-8" ?>
<!--父表CustomerXML配置(Customer.hbm.xml) 对应Oracle里的表 CUSTOMER(全大写) -->
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHibernateSample.Domain"
namespace="NHibernateSample.Domain.Entities">
<!--父端路径:NHibernateSample.Domain.Entities.Customer...程序集:NHibernateSample.Domain...父端在数据库中对应的表名为CUSTOMER(全大写)-->
<class name ="NHibernateSample.Domain.Entities.Customer,NHibernateSample.Domain" table="CUSTOMER">
<!--父表的主键-->
<id name="Id" column ="CUSTOMERID">
<generator class ="assigned"/>
<!--非自增长assigned.Add的时候可自定义-->
</id>
<!--assigned-->
<!--类Customer中Firstname字段对应数据库Customer表中的FIRSTNAME字段-->
<property name ="Firstname" column ="FIRSTNAME" />
<property name ="Lastname" column ="LASTNAME" />
<!--Relationship : 1:n One customer have many orders-->
<!--映射一对多<set> (在父端映射)
<set>标签中:name为Orders类的名称,table可写可不写,如果写的话应该分下面两种:
第一种让NHibernate自动判断,可以写为:table="Order" or table="ORDER" 其中" "中的大小写可以随便写。注:(Oracle中的Order表命名为:Order)
第二种就是关键字处理 在Oracle中可用table="`Order`" SQL2005中为table="[Order]"。
-->
<set name="Orders" table="`Order`" generic="true" inverse="true">
<!--这个key 应该就是Order表中的CUSTOMERID(外键)-->
<key column="CUSTOMERID"></key>
<!--标示一对多 子端Orders类的路径以及程序集-->
<one-to-many class="NHibernateSample.Domain.Entities.Order,NHibernateSample.Domain"/>
</set>
<!-- 结束 ^_^-->
</class>
</hibernate-mapping>
<!--父表CustomerXML配置(Customer.hbm.xml) 对应Oracle里的表 CUSTOMER(全大写) -->
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHibernateSample.Domain"
namespace="NHibernateSample.Domain.Entities">
<!--父端路径:NHibernateSample.Domain.Entities.Customer...程序集:NHibernateSample.Domain...父端在数据库中对应的表名为CUSTOMER(全大写)-->
<class name ="NHibernateSample.Domain.Entities.Customer,NHibernateSample.Domain" table="CUSTOMER">
<!--父表的主键-->
<id name="Id" column ="CUSTOMERID">
<generator class ="assigned"/>
<!--非自增长assigned.Add的时候可自定义-->
</id>
<!--assigned-->
<!--类Customer中Firstname字段对应数据库Customer表中的FIRSTNAME字段-->
<property name ="Firstname" column ="FIRSTNAME" />
<property name ="Lastname" column ="LASTNAME" />
<!--Relationship : 1:n One customer have many orders-->
<!--映射一对多<set> (在父端映射)
<set>标签中:name为Orders类的名称,table可写可不写,如果写的话应该分下面两种:
第一种让NHibernate自动判断,可以写为:table="Order" or table="ORDER" 其中" "中的大小写可以随便写。注:(Oracle中的Order表命名为:Order)
第二种就是关键字处理 在Oracle中可用table="`Order`" SQL2005中为table="[Order]"。
-->
<set name="Orders" table="`Order`" generic="true" inverse="true">
<!--这个key 应该就是Order表中的CUSTOMERID(外键)-->
<key column="CUSTOMERID"></key>
<!--标示一对多 子端Orders类的路径以及程序集-->
<one-to-many class="NHibernateSample.Domain.Entities.Order,NHibernateSample.Domain"/>
</set>
<!-- 结束 ^_^-->
</class>
</hibernate-mapping>
Order XML配置:
<?xml version="1.0" encoding="utf-8" ?>
<!--子表Order配置(Order.hbm.xml) 对应Oracle里的表 Order (有大有小写)-->
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHibernateSample.Domain"
namespace="NHibernateSample.Domain.Mappings">
<!--子端路径:NHibernateSample.Domain.Entities.Order...程序集:NHibernateSample.Domain...子端在数据库中对应的表名为Order(有大有小写)-->
<class name ="NHibernateSample.Domain.Entities.Order,NHibernateSample.Domain" table="`Order`">
<!--子表主键-->
<id name ="OrderID" column="ORDERID">
<generator class ="assigned"/>
<!--非自增长assigned. Add的时候可自定义-->
</id>
<!--类Order中OrderDate字段对应数据库Order表中的ORDERDATE字段-->
<property name="OrderDate" column="ORDERDATE"></property>
<!--映射多对一,many-to-one (在子端映射)
name为父端的类名,column为父端类对应的表中的主键.(即表CUSTOMER中的CUSTOMERID
Class 为父端类(Customer)的路径-->
<many-to-one name="Customer" column="CUSTOMERID"
class="NHibernateSample.Domain.Entities.Customer,NHibernateSample.Domain" foreign-key="FK_CustomerOrders">
</many-to-one>
</class>
<!-- 结束 ^_^-->
</hibernate-mapping>
<!--子表Order配置(Order.hbm.xml) 对应Oracle里的表 Order (有大有小写)-->
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHibernateSample.Domain"
namespace="NHibernateSample.Domain.Mappings">
<!--子端路径:NHibernateSample.Domain.Entities.Order...程序集:NHibernateSample.Domain...子端在数据库中对应的表名为Order(有大有小写)-->
<class name ="NHibernateSample.Domain.Entities.Order,NHibernateSample.Domain" table="`Order`">
<!--子表主键-->
<id name ="OrderID" column="ORDERID">
<generator class ="assigned"/>
<!--非自增长assigned. Add的时候可自定义-->
</id>
<!--类Order中OrderDate字段对应数据库Order表中的ORDERDATE字段-->
<property name="OrderDate" column="ORDERDATE"></property>
<!--映射多对一,many-to-one (在子端映射)
name为父端的类名,column为父端类对应的表中的主键.(即表CUSTOMER中的CUSTOMERID
Class 为父端类(Customer)的路径-->
<many-to-one name="Customer" column="CUSTOMERID"
class="NHibernateSample.Domain.Entities.Customer,NHibernateSample.Domain" foreign-key="FK_CustomerOrders">
</many-to-one>
</class>
<!-- 结束 ^_^-->
</hibernate-mapping>
Customer类.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Iesi.Collections.Generic;
namespace NHibernateSample.Domain.Entities
{
//父端类Customer 对用Oracle 中的CUSTOMER
public class Customer
{
//CUSTOMER表中的字段
public virtual int Id { get; set; }
public virtual string Firstname { get; set; }
public virtual string Lastname { get; set; }
//由于CUSTOMER与Order是Many to one 所以用Iset<T>集合来表示多个Orders
//详情参考http://www.cnblogs.com/lyj/archive/2008/10/24/1319052.html
public virtual ISet<Order> Orders { get; set; }
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Iesi.Collections.Generic;
namespace NHibernateSample.Domain.Entities
{
//父端类Customer 对用Oracle 中的CUSTOMER
public class Customer
{
//CUSTOMER表中的字段
public virtual int Id { get; set; }
public virtual string Firstname { get; set; }
public virtual string Lastname { get; set; }
//由于CUSTOMER与Order是Many to one 所以用Iset<T>集合来表示多个Orders
//详情参考http://www.cnblogs.com/lyj/archive/2008/10/24/1319052.html
public virtual ISet<Order> Orders { get; set; }
}
}
Order类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NHibernateSample.Domain.Entities
{
//父端类Order 对用Oracle 中的Order
public class Order
{
//Order表中对应的字段
public virtual int OrderID { get; set; }
public virtual DateTime OrderDate { get; set; }
//由于Order与CUSTOMER是one to many 所以用一个Customer来表示
public virtual Customer Customer { get; set; }
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NHibernateSample.Domain.Entities
{
//父端类Order 对用Oracle 中的Order
public class Order
{
//Order表中对应的字段
public virtual int OrderID { get; set; }
public virtual DateTime OrderDate { get; set; }
//由于Order与CUSTOMER是one to many 所以用一个Customer来表示
public virtual Customer Customer { get; set; }
}
}
NhibernateCriteria.cs 与Oracle进行交互
NhibernateCriteria.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernateSample.Domain.Entities;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Criterion.Lambda;
namespace NHibernateSample.Data
{
public class NhibernateCriteria
{
public NhibernateCriteria()
{
NHibernateHelper Hhelp = new NHibernateHelper();
this.Session = Hhelp.GetSession();
}
protected ISession Session { get; set; }
public NhibernateCriteria(ISession session)
{
Session = session;
}
public IList<Customer> UseCriteriaAPI_GetCustomersWithOrders()
{
DateTime dtime = new DateTime(1989, 10, 1);
return Session.CreateCriteria(typeof(Customer))
.CreateAlias("Orders", "o")
.Add(Restrictions.Gt("o.OrderDate", dtime))
.List<Customer>();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernateSample.Domain.Entities;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Criterion.Lambda;
namespace NHibernateSample.Data
{
public class NhibernateCriteria
{
public NhibernateCriteria()
{
NHibernateHelper Hhelp = new NHibernateHelper();
this.Session = Hhelp.GetSession();
}
protected ISession Session { get; set; }
public NhibernateCriteria(ISession session)
{
Session = session;
}
public IList<Customer> UseCriteriaAPI_GetCustomersWithOrders()
{
DateTime dtime = new DateTime(1989, 10, 1);
return Session.CreateCriteria(typeof(Customer))
.CreateAlias("Orders", "o")
.Add(Restrictions.Gt("o.OrderDate", dtime))
.List<Customer>();
}
}
}
NHibernateHelper.cs 创建_session
NHibernateHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using Iesi.Collections;
using NHibernate.Cfg;
using NHibernate.Bytecode;
namespace NHibernateSample.Data
{
public class NHibernateHelper
{
private ISessionFactory _sessionFactory;
public NHibernateHelper()
{
_sessionFactory = GetSessionFactory();
}
private ISessionFactory GetSessionFactory()
{
return (new Configuration()).Configure().BuildSessionFactory();
}
public ISession GetSession()
{
return _sessionFactory.OpenSession();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using Iesi.Collections;
using NHibernate.Cfg;
using NHibernate.Bytecode;
namespace NHibernateSample.Data
{
public class NHibernateHelper
{
private ISessionFactory _sessionFactory;
public NHibernateHelper()
{
_sessionFactory = GetSessionFactory();
}
private ISessionFactory GetSessionFactory()
{
return (new Configuration()).Configure().BuildSessionFactory();
}
public ISession GetSession()
{
return _sessionFactory.OpenSession();
}
}
}
FullName.aspx HTML 做个简单的循环来查看每个CUSTOMER中有多少个订单详情
FullName.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FullName.aspx.cs" Inherits="NHibernateSample.Web.FullName" %>
<%@ Import Namespace="NHibernateSample.Domain.Entities" %>
<%@ Import Namespace="Iesi.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<% for (int I = 0; I < Cus.Count; I++) %>
<%{ %>
<tr>
<td>
CustomerID:<%=Cus[I].Id.ToString() %>
</td>
<td>
LastName:<%=Cus[I].Lastname.ToString() %>
</td>
<td>
FirstName<%= Cus[I].Firstname.ToString() %>
</td>
</tr>
<tr>
<% foreach (Order o in Cus[I].Orders) %>
<%{ %>
<td>
OrderID<%= o.OrderID.ToString()%>
</td>
<td>
OrderDate<%=o.OrderDate.ToString()%>
</td>
<%} %>
</tr>
<%} %>
</tr>
</table>
</div>
</form>
</body>
</html>
<%@ Import Namespace="NHibernateSample.Domain.Entities" %>
<%@ Import Namespace="Iesi.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<% for (int I = 0; I < Cus.Count; I++) %>
<%{ %>
<tr>
<td>
CustomerID:<%=Cus[I].Id.ToString() %>
</td>
<td>
LastName:<%=Cus[I].Lastname.ToString() %>
</td>
<td>
FirstName<%= Cus[I].Firstname.ToString() %>
</td>
</tr>
<tr>
<% foreach (Order o in Cus[I].Orders) %>
<%{ %>
<td>
OrderID<%= o.OrderID.ToString()%>
</td>
<td>
OrderDate<%=o.OrderDate.ToString()%>
</td>
<%} %>
</tr>
<%} %>
</tr>
</table>
</div>
</form>
</body>
</html>
FullName.aspx.cs
FullName.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using NHibernateSample.Data;
using NHibernateSample.Domain.Entities;
using Iesi.Collections.Generic;
using System.Collections;
namespace NHibernateSample.Web
{
public partial class FullName : System.Web.UI.Page
{
public static IList<Customer> Cus = null;
NHibernateSample.Data.NhibernateCriteria NHcri = new NhibernateCriteria();
protected void Page_Load(object sender, EventArgs e)
{
Cus = NHcri.UseCriteriaAPI_GetCustomersWithOrders();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using NHibernateSample.Data;
using NHibernateSample.Domain.Entities;
using Iesi.Collections.Generic;
using System.Collections;
namespace NHibernateSample.Web
{
public partial class FullName : System.Web.UI.Page
{
public static IList<Customer> Cus = null;
NHibernateSample.Data.NhibernateCriteria NHcri = new NhibernateCriteria();
protected void Page_Load(object sender, EventArgs e)
{
Cus = NHcri.UseCriteriaAPI_GetCustomersWithOrders();
}
}
}
hibernate.cfg.xml
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider, NHibernate</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver, NHibernate</property>
<property name="connection.connection_string">
Data Source = (
description = (
address_list = (
address = (HOST = DataBaseIP)(PROTOCOL = TCP)(PORT = 端口))
)
(connect_data = (
service_name = 数据库名字))
);
User Id=UserID;Password=PassWord;
</property>
<property name="show_sql">false</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name="proxyfactory.factory_class">
NHibernate.ByteCode.Castle.ProxyFactoryFactory,
NHibernate.ByteCode.Castle
</property>
<mapping assembly="NHibernateSample.Domain"/>
</session-factory>
</hibernate-configuration>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider, NHibernate</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver, NHibernate</property>
<property name="connection.connection_string">
Data Source = (
description = (
address_list = (
address = (HOST = DataBaseIP)(PROTOCOL = TCP)(PORT = 端口))
)
(connect_data = (
service_name = 数据库名字))
);
User Id=UserID;Password=PassWord;
</property>
<property name="show_sql">false</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name="proxyfactory.factory_class">
NHibernate.ByteCode.Castle.ProxyFactoryFactory,
NHibernate.ByteCode.Castle
</property>
<mapping assembly="NHibernateSample.Domain"/>
</session-factory>
</hibernate-configuration>
记录第一个Nhibernate 程序.在大家的帮助下还是顺利的完成了。
严重感谢群里的各位童鞋。。。
想班长大人了...
未完待续...