Nhibernate学习

NHibernate学习

 

1.      hibernate.cfg.xml配置文件  (主要是数据库链接和关联映射文件)

 

<?xmlversion="1.0"encoding="utf-8"?>
 
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
  <session-factory>
   <propertyname="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
   
<propertyname="connection.connection_string">Uid=sa;Pwd=`1234qwert;Initial Catalog=T_DZ;Data Source=10.163.100.173</property>
<propertyname="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<propertyname="show_sql">true</property>
 
 <mappingassembly="NhibernatePro"/>
       <!--关联 hbm文件的 assembly-->
  </session-factory>
</hibernate-configuration>


 

注意:该文件的输出方式必须设置成:始终复制

2.      Domainhbm文件的声明

 

(1)    有两个表 Product Category表,表结构如下

 

(2)   对应的两个Domain如下:

 

1.      Category.cs


namespace NhibernatePro.App_Code.Domain
{
   [Serializable]
   public  class Category
    {
     
        public virtual string CategoryId { get; set; }
        public virtual string CategoryName { get; set; }
        public virtual IList<Product> ProductList { get; set; }
//用于一对多的关联,一个Category对应多个Product
    }
}


 

2.      Product.cs

namespace NhibernatePro.App_Code.Domain
{
    [Serializable]
    public class Product
    {
        public virtual string ProductId { get; set; }
        public virtual string ProductName { get; set; }
        public virtual decimal ProductProce { get; set; }
        public virtual Category Category { get; set; }
//多对一的关联一个Product属于一个Category
    }
}



备注属性必须定义成 virtual的。

(3)   Hbm映射文件的定义

 

Hbm文件的名称必须和Domain的名称一样

Hbm文件的生成操作必须设置成嵌入的资源

 

 

Eg:   Category对应的映射文件名称为:  Category.hbm.xml

 

1.      Category.hbm.xml

 

<?xmlversion="1.0"encoding="utf-8" ?>
<hibernate-mappingxmlns="urn:nhibernate-mapping-2.2"assembly="NhibernatePro"namespace="NhibernatePro.App_Code.Domain">
 
  <classname="Category"table="Category">
    <idcolumn="CategoryId"name="CategoryId"type="string">
      <generator class="assigned">
      </generator>
    </id>
 
    <propertyname="CategoryName"type="string">
    <columnname="CategoryName"></column>
    </property>
 
    <bag  name="ProductList" cascade="all" lazy="true" inverse="true">
    <key column="CId"  not-null = "false"/>
    <one-to-many class="Product"></one-to-many>
    </bag>
   <!--一对多的配置
    1. cascade 配置  可以保证在存Category时级联存Product. ,也可以在删除category时级联删除product
    2. lazy=true  延迟加载,因为分类下有很多产品,所以需要设置级联,这里需要保证session没有关闭,以便在级联取数据时不会报session关闭的错误。
    3.  inverse=true  默认的inverse为false表示关联关系由外键表维护即Product表,true表示由主键表维护,即Category。在级联删除时必须设置为true
-->
</class>
  </hibernate-mapping>
 

 

2.      Product.hbm.xml

 

 

<?xmlversion="1.0"encoding="utf-8" ?>
<hibernate-mappingxmlns="urn:nhibernate-mapping-2.2"assembly="NhibernatePro"namespace="NhibernatePro.App_Code.Domain">
 
<classname="Product"table="Product">
<idcolumn="ProductId"name="ProductId"type="string">
<generatorclass="assigned">
</generator>
</id>
 
<propertyname="ProductName"type="string">
<columnname="ProductName"></column>
</property>
   
<propertyname="ProductProce"type="decimal">
<columnname="ProductProce"></column>
</property>
 
<many-to-one  name="Category" column="CId" not-null="false" cascade="save-update" lazy="false"></many-to-one>
<!--
1. 多对一两边的column均为外键表中的关联外键
2. cascade="save-update" 保证在新建和保存Product时可以级联保存和更新Category
3. lazy =false 表示非延迟加载,在取product数据时就把category数据也取出来(这样可以防止session关闭后通过p.Category.CategoryName取数时报session关闭)
-->
</class>
</hibernate-mapping>
 

3.      Hibernate 工具类,用于获取Session和关闭链接

 

namespace NhibernatePro.App_Code.Utility
{
    classHibernateHelper
    {
        ISession session =null;
 
        publicISession GetSession() {
        if(null == session || !(session.IsOpen)){
            Configuration config = new Configuration().Configure("hibernate.cfg.xml");
            ISessionFactory sessionFactory = config.BuildSessionFactory();
            session = sessionFactory.OpenSession();
        }  
        return session;
        }
 
        public void Close(ISession session) {
            if(null != session){
             session.Flush();
            session.Clear();
            session.Close();
            }
          
        }
    }
}
 

 

4.      数据访问层

 

(1) 通用接口

 

namespace NhibernatePro.App_Code.DAL
{
    public interface IDAL<T>
    {
         void Add(T t);
         T Get(string id);
         void Update(T t);
         void Delete(string id);
         IList<T> ListAll();
         IList<T> ListByPage(int currPage,int pageSize);
         Int32 Count<T>();
    }
}
 
(2) ProductDAL对IDAL的实现
 
 
 
namespace NhibernatePro.App_Code.DAL
{
    public class ProductDAL: IDAL<Product>
    {
        HibernateHelper hh = new HibernateHelper();
 
        //添加一个Product
        public void Add(Product t)
        {
            try
            {
                ISession session = hh.GetSession();
                ITransaction trans = session.BeginTransaction();
                session.SaveOrUpdate(t);
                trans.Commit();
                hh.Close(session);
            }
            catch(Exception ex)
            {
                ex.StackTrace.ToString();
            }
        }
 
        //获取一个Product
        public Product Get(string id)
        {
            ISession session = hh.GetSession();
 
 
            Product product = session.Get<Product>(id);
            hh.Close(session);
            return product;
        }
 
        //更新
        public void Update(Product t)
        {
        }
 
        //删除
        public void Delete(string id)
        {
            Product p = Get(id);
            ISession session = hh.GetSession();
            session.Delete(p);
            hh.Close(session);
        }
 
        //获取全部的Product
        public IList<Product> ListAll()
        {
            ISession session =  hh.GetSession();
            IList<Product> productList =  session.CreateQuery("from Product").List<Product>();
            hh.Close(session);
            return productList;
        }
 
        //分页获取
        public IList<Product> ListByPage(int currPage, int pageSize)
        {
            ISession session = hh.GetSession();
            IQuery query = session.CreateQuery("from Product");
            //query.SetParameter(0,"value1");  //设置hql的参数,下标从0开始
            query.SetFirstResult((currPage - 1)*pageSize);   //分页的开始位置
            query.SetMaxResults(pageSize);              //一页有多少条
            IList<Product> productList = query.List<Product>();
            hh.Close(session);
            return productList;
        }
 
        //获取总条数
        public int Count<T>()
        {
            Int32 count = 0;
            ISession session = hh.GetSession();
            IQuery query = session.CreateSQLQuery("select count(*) from Product");
            count = (Int32)query.UniqueResult();
            return count;
        }
    }
}
 
 
(备注)对于有添加更新删除的操作,应该先开启事物,最后在提交
 
 
5.      业务层BLL
 
该层直接调用DAL层中的方法。
 
6.      测试
使用NUnit 进行测试
用NUnit加载项目生成的exe文件,即可看到如下的测试方法。
 
 
 
namespace NhibernatePro.App_Code.Test
{
    [TestFixture]
    class TestCase
    {
 
        [Test]
        public void ListCategory()
        {
            CategoryBLL categoryBLL = new CategoryBLL();
            IList<Category> categoryList =  categoryBLL.ListAll();
            if(null != categoryList)
            {
                foreach(Category c in categoryList)
                {
                    Console.WriteLine(c.CategoryName);
                    IList<Product> productList = c.ProductList;
                    foreach(Product p in productList)
                    {
                        Console.WriteLine(p.ProductName + ":" + p.ProductProce);
                    }
                    Console.WriteLine();
                }
            }
        }
        [Test]
        public void ListProduct()
        {
            ProductBLL productBLL = new ProductBLL();
            IList<Product> productList = productBLL.ListAll();
            if(null != productList)
            {
                foreach(Product p in productList)
                {
                    Console.WriteLine("{0},{1},{2}", p.ProductName, p.ProductProce, p.Category.CategoryName);
                }
            }
        }
 
        [Test]
        public void listByPage()
        {
            ProductBLL productBLL = new ProductBLL();
            Int32 currPage = 1;
            Int32 pageSize = 5;
            IList<Product> productList = productBLL.ListByPage(currPage, pageSize);
            if (null != productList)
            {
                foreach (Product p in productList)
                {
                    Console.WriteLine("{0},{1},{2}", p.ProductName, p.ProductProce, p.Category.CategoryName);
                }
            }
        }
 
        [Test]
        public void getProduct()
        {
            ProductBLL productBLL = new ProductBLL();
            string productId = "AE93D4DF-1650-4E12-BE0A-EF698E6E1127";
            Product p = productBLL.Get(productId);
            if(null != p)
            {
                Console.WriteLine("{0},{1},{2}", p.ProductName, p.ProductProce, p.Category.CategoryName);
            }
        }
 
        [Test]
        //保存一个product它的category是已经存在的
        public void saveProduct1()
        {
            CategoryBLL categoryBLL = new CategoryBLL();
            string categoryId = "aed459a5-2c0a-441f-a019-2c2b389a7fcd";
            Category category1 = categoryBLL.Get(categoryId);
            Product p = new Product();
            p.ProductId = Guid.NewGuid().ToString();
            p.ProductName = "banana";
            p.ProductProce = new decimal(15);
            p.Category = category1;
 
            ProductBLL productBLL = new ProductBLL();
            CategoryBLL categoryBll = new CategoryBLL();
            // categoryBll.Add(category1);
            productBLL.Add(p);
 
        }
 
 
        //保存一个product它的category需要级联添加
        [Test]
        public void  saveProductWithCategory()
        {
            Category c = new Category()
            {
                CategoryId = Guid.NewGuid().ToString(), CategoryName = "Water"
            };
            Product p = new Product()
            {
                ProductId = Guid.NewGuid().ToString(), ProductName = "EverGreat Ice Water", ProductProce = new decimal(500), Category = c
            };
            ProductBLL productBLL = new ProductBLL();
            CategoryBLL categoryBll = new CategoryBLL();
 
            productBLL.Add(p);
        }
 
        //删除一个product
        [Test]
        public void deleteProdcut()
        {
            string productId = "e0ccd2f1-dd26-4dca-bb39-ff318c297fff";
            ProductBLL productBLL = new ProductBLL();
            productBLL.Delete(productId);
            Console.WriteLine("删除成功....");
        }
 
        //删除一个category (会级联删除该category下的product)
        [Test]
        public void deleteCategory()
        {
            string categoryId = "7fc0a318-9031-4683-bf5d-1de0c5ee4680";
            CategoryBLL categoryBLL = new CategoryBLL();
            categoryBLL.Delete(categoryId);
            Console.WriteLine("删除Category成功..");
        }
 
        [Test]
        public void countProduct()
        {
            ProductBLL productBLL = new ProductBLL();
            Int32 pCount = productBLL.Count<Product>();
            Console.WriteLine("count:" + pCount);
        }
 
    }
}
 

 

7.      项目的完整结构如下:

 

 

 

 

 

Ps.

 

有用链接:

 

1.       http://www.cnblogs.com/GoodHelper/archive/2011/03/03/1965290.html

2.       NHibernate 常见错误

http://blog.csdn.net/coolhe21cn/article/details/2065087

 

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sust2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值