zoukankan      html  css  js  c++  java
  • MVC3+NHibernate项目实战(二) :数据库访问层

    我们现在使用NHibernate一步一步来构建数据库访问层.

    一.首先建立Blog.Model:实体层项目

    (1)先建立EntityBase实体基类,然后所有的实体都继承该类;

    View Code
    namespace Blog.Model
    {
        public class EntityBase
        {
            public virtual int Id { get; set; }
           public virtual bool IsDelete { get; set; }
           public virtual DateTime CreateDate { get; set; }
           public virtual int Version { get; set; }
        }
    }

    Id:使用int值作为id;

    IsDelete:是否删除;

    CreateDate:创建时间;

    Version:NHibernate中作并发控制;

    (2)建立实体User

    View Code
    namespace Blog.Model.Entities
    {    
        public class User:EntityBase
        {
            public virtual int Id{ get;set; }
            public virtual string UserName{ get;set; }
            public virtual string Password{ get;set; }
            public virtual string NickName{ get;set; }
            public virtual bool Gender{ get;set; }
            public virtual DateTime Birthday{ get;set; }
            public virtual string Email{ get;set; }
            public virtual string Address{ get;set; }
            public virtual string Phone{ get;set; }
            public virtual string QQ{ get;set; }
            public virtual bool IsActive{ get;set; }
        }
    }

    注意:属性都加上virtual关键字

    (3)建立实体xml映射文件

    View Code
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Blog.Model" assembly="Blog.Model">
        <class name="Blog.Model.Entities.User, Blog.Model" table="`User`">
            <id name="Id" type="Int32" unsaved-value="null">
                <column name="UserId" length="4" sql-type="int" not-null="true" unique="true" index="PK_USER"/>
                <generator class="native" />
            </id>
            <version name="Version" column="Version" type="integer" unsaved-value="0"/>
            <property name="UserName" type="String">
                <column name="UserName" length="50" sql-type="nvarchar" not-null="false"/>
            </property>
            <property name="Password" type="String">
                <column name="Password" length="50" sql-type="nvarchar" not-null="false"/>
            </property>
            <property name="NickName" type="String">
                <column name="NickName" length="50" sql-type="nvarchar" not-null="false"/>
            </property>
            <property name="Gender" type="Boolean">
                <column name="Gender" length="1" sql-type="bit" not-null="false"/>
            </property>
            <property name="Birthday" type="DateTime">
                <column name="Birthday" length="8" sql-type="datetime" not-null="false"/>
            </property>
            <property name="Email" type="String">
                <column name="Email" length="50" sql-type="varchar" not-null="false"/>
            </property>
            <property name="Address" type="String">
                <column name="Address" length="50" sql-type="nvarchar" not-null="false"/>
            </property>
            <property name="Phone" type="String">
                <column name="Phone" length="15" sql-type="varchar" not-null="false"/>
            </property>
            <property name="QQ" type="String">
                <column name="QQ" length="10" sql-type="varchar" not-null="false"/>
            </property>
            <property name="IsActive" type="Boolean">
                <column name="IsActive" length="1" sql-type="bit" not-null="false"/>
            </property>
            <property name="CreateDate" type="DateTime">
                <column name="CreateDate" length="8" sql-type="datetime" not-null="false"/>
            </property>
            <property name="IsDelete" type="Boolean">
                <column name="IsDelete" length="1" sql-type="bit" not-null="false"/>
        </class>
    </hibernate-mapping>

    注意:hbmXML映射文件,属性必须设置为"嵌入的资源";XML中的Version字段必须在Id字段之后

    NHibernate  Id生成方式选择
    映射文件id生成选择:<generator class="native" />
    Assigned : 主键由外部程序负责生成,无需Hibernate参与,如Guid
    identity : 采用数据库提供的主键生成机制
    native
     由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。
    我上面只是列举了常用的几种,具体可以自己查找;
    我们实体层的工作基本已经完成
     
    二.建立NHibernate配置文件
     
    我们使用的是单个的配置文件方式,配置文件名hibernate.cfg.xml;
    View Code
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
      <session-factory name="NHibernateWeb">
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="connection.connection_string">
          Data Source=.\SQLEXPRESS;Initial Catalog=BlogDB;Integrated Security=True;Pooling=False
        </property>
        <property name="adonet.batch_size">10</property>
        <property name="show_sql">true</property>
        <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
        <property name="command_timeout">10</property>
        <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
        <mapping assembly="Blog.Model"/>
      </session-factory>
    </hibernate-configuration>

    三.建立Blog.Repository:数据访问层

     

    (1)新建接口IRepository

    View Code
    namespace Blog.Repository
    {
        public interface IRepository<T, TId> where T : EntityBase
        {
            T Load(TId id);
            T Get(TId id);
            IList<T> GetAll();
            IList<T> FindForPage(int index, int count);
            IList<T> Find(Expression<Func<T, bool>> query);
            T FindForSingle(Expression<Func<T, bool>> query);
            IList<T> HQLQuery(string query);
            TId Save(T entity);
            void SaveOrUpdate(T entity);
            void Update(T entity);
            void Delete(T t);
            void PhysicsDelete(TId id);
        }
    }

    (2)新建Repository基类

    View Code
    namespace Blog.Repository
    {
        public abstract class Repository<T, TId> where T : EntityBase
        {
            private IUnitOfWork _uow;
            public Repository(IUnitOfWork uow)
            {
                _uow = uow;
            }
            protected virtual ISession Session
            {
                get { return NHSessionFactory.CreateSession(); }
            }
    
            /// <summary>
            /// 根据Id延迟加载获取实体
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public virtual T Load(TId id)
            {
                return Session.Load<T>(id);
            }
    
            /// <summary>
            /// 根据Id获取实体
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public virtual T Get(TId id)
            {
                return Session.Get<T>(id);
            }
    
            /// <summary>
            /// 获取所有实体
            /// </summary>
            /// <returns></returns>
            public virtual IList<T> GetAll()
            {
                return Session.CreateCriteria(typeof(T)).List<T>();//使用Criteria
                //return Session.Query<T>().ToList();
                //return Session.QueryOver<T>().List();//使用QueryOver linq
            }
    
            /// <summary>
            /// 获取分页数据
            /// </summary>
            /// <param name="index">index=(pageNum-1)*pageCount</param>
            /// <param name="count">每页的条数pageCount</param>
            /// <returns></returns>
            public IList<T> FindForPage(int index, int count)
            {
                return Session.CreateCriteria(typeof(T)).SetMaxResults(count).SetFirstResult(index).List<T>();
            }
    
            /// <summary>
            /// lambda表达式获取
            /// </summary>
            /// <param name="query"></param>
            /// <returns></returns>
            public IList<T> Find(Expression<Func<T, bool>> query)
            {
                return Session.QueryOver<T>().Where(query).List();
            }
    
            /// <summary>
            /// lambda表达式获取单个实体
            /// </summary>
            /// <param name="query"></param>
            /// <returns></returns>
            public T FindForSingle(Expression<Func<T, bool>> query)
            {
                return Session.Query<T>().SingleOrDefault(query);
            }
    
    
            /// <summary>
            /// HQL查询
            /// </summary>
            /// <param name="query"></param>
            /// <returns></returns>
            public IList<T> HQLQuery(string query)
            {
               return Session.CreateQuery(query).List<T>();
            }
    
            /// <summary>
            /// 保存
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            public virtual TId Save(T entity)
            {
                return (TId)Session.Save(entity);
            }
    
            /// <summary>
            /// 保存或更新
            /// </summary>
            /// <param name="entity"></param>
            public virtual void SaveOrUpdate(T entity)
            {
                Session.SaveOrUpdate(entity);
            }
    
            /// <summary>
            /// 更新
            /// </summary>
            /// <param name="entity"></param>
            public virtual void Update(T entity)
            {
                Session.Update(entity);
            }
    
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="id"></param>
            public virtual void PhysicsDelete(TId id)
            {
                var entity = Get(id);
                Session.Delete(entity);
            }
    
            public void Delete(T t)
            {
                t.IsDelete = true;
                Update(t);
            }
        }
    }

    (3)建立对应的实体的数据访问接口IUserRepository,该接口实现了IRepository

    View Code
    namespace Blog.Repository
    {    
        public interface IUserRepository:IRepository<User,int>
        {
        }
    }

    (4)建立实体的数据访问实现体

    View Code
    namespace Blog.Repository
    {    
        public class UserRepository:Repository<User,int>,IUserRepository
        {
            public UserRepository(IUnitOfWork uow)
               : base(uow)
            {}
        }
    }

     

    (5)Unit of Work模式,从上面的Repository基类可以看到,我们已经注入了该模式的实现;

       1.建立IUnitOfWork接口

    namespace Blog.Repository
    {
        public interface IUnitOfWork
        {
            void Commit();
        }
    }

     2.建立NHUnitOfWork类,实现IUnitOfWork接口

    View Code
    namespace Blog.Repository
    {
        public class NHUnitOfWork : IUnitOfWork
        {
            public ISession session
            {
                get { return NHSessionFactory.CreateSession(); }
            }
          
    
            public void Commit()
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.Flush();
                        transaction.Commit(); 
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        throw;
                    }
                }
            }
        }
    }

     (6)NHibernate的Session管理与初始化

    为了合理控制Session的生命周期,在.netMVC中我们把Session的生命周期绑定在一次Action里;

      1.建立接口ISessionStorage;

    View Code
    namespace Blog.Repository.SessionStorage
    {
        public interface ISessionStorage
        {
            ISession Get();
            void Set(ISession value);
        }
    }

      2.新建一个类HttpSessionStorage实现接口ISessionStorage; 

     

        public class HttpSessionStorage:ISessionStorage
        {
            private string sessionKey = "NhbSession";
            public NHibernate.ISession Get()
            {
                ISession session = null;
                if (HttpContext.Current.Items.Contains(sessionKey))
                    session = (ISession)HttpContext.Current.Items[sessionKey];
                return session;
            }
    
            public void Set(ISession value)
            {
                if (value != null)
                {
                    if (HttpContext.Current != null)
                    {
                        HttpContext.Current.Items.Add(sessionKey, value);
                    }               
                }
            }
        }
    

      

      3.新建一个工厂类,获取NHibernate的session

    View Code
    namespace Blog.Repository.SessionStorage
    {
        public static class NHSessionFactory
        {
            private static object locker = new object();
            private static Configuration _configuration = null;
            private static ISessionFactory _sessionFactory = null;
    
            private static ISessionStorage SessionStorage{get;set;}
            public static void InitSessionFactory(ISessionStorage sessionStorage)
            {
                SessionStorage = sessionStorage;//使用ioc容器注入
            }
    
            private static void CreateConfiguration()
            {          
                _configuration = new Configuration().Configure();
            }
    
            public static Configuration Configuration
            {
                get
                {
                    lock (locker)
                    {
                        if (_configuration == null)
                        {
                            CreateConfiguration();
                        }
                        return _configuration;
                    }
                }
                set { _configuration = value; }
            }
    
            internal static ISessionFactory SessionFactory
            {
                get
                {
                    if (_sessionFactory == null)
                    {
                        if (Configuration == null)
                        {
                            CreateConfiguration();
                        }
                        lock (locker)
                        {
                            _sessionFactory = Configuration.BuildSessionFactory();
                        }
                    }
                    return _sessionFactory;
                }
            }
    
            public static ISession CreateSession()
            {
                ISession s = SessionStorage.Get();
                if (s == null)
                {
                    s = SessionFactory.OpenSession();
                    SessionStorage.Set(s);
                }
                return s;
            }
        }
    }

     注意要在 void Application_Start()进行初始化

      如下代码

    NHSessionFactory.InitSessionFactory(container.Resolve<ISessionStorage>());//NHibernate session

    这样我们的数据库访问层基本完成了!!

  • 相关阅读:
    CMake 3.8.2 Online Manuals
    如何查找UDID
    产品经理那些事儿学习整理笔记
    IOS KVO与NSNotificationCenter简单使用
    整理分享内容
    iOS解决两个静态库的冲突 duplicate symbol
    IOS 添加libMobileVLCKit .a到项目中编译问题
    OpenERP为form和tree视图同时指定view_id的方法
    openerp related字段解读
    openerp图片路径处理
  • 原文地址:https://www.cnblogs.com/edwardloveyou/p/2690063.html
Copyright © 2011-2022 走看看