Spring.Net + NHibernate 简单示例

环境:
1,VS2010
2,MySql 5.5.15

主要用到的dll:
Common.Logging.dll
Common.Logging.Log4Net.dll
log4net.dll
Iesi.Collections.dll
NHibernate.dll
Spring.Core.dll
Spring.Data.dll
Spring.Data.NHibernate32.dll

以上文件皆可从Spring.NET 下载包中获得。

实验目的:查找出一条记录显示其某个属性值。

本人喜欢Java的开发习惯,因此文件都挤在一个工程里:

重点的为配置文件 APP.Config:

View Code
<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
      <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/>
    </sectionGroup>
    <sectionGroup name="common">
      <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
    </sectionGroup>
    <section name="databaseSettings" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>
  
  <spring>
    <context>
      <resource uri="assembly://SpringNHibernateTest/SpringNHibernateTest.Conf/applicationContext_hibernate.xml"/>
      <resource uri="assembly://SpringNHibernateTest/SpringNHibernateTest.Conf/applicationContext_PM.xml"/>
      <resource uri="config://spring/objects"/>
    </context>
    <objects xmlns="http://www.springframework.net">
    </objects>
    <parsers>
      <parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"/>
      <parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data"/>
    </parsers>
  </spring>

  <!-- These properties are referenced in applicationContext_hibernate.xml -->
  <databaseSettings>
    <add key="db.datasource" value="192.168.1.186"/>
    <add key="db.user" value="root"/>
    <add key="db.password" value="root"/>
    <add key="db.database" value="hellodb"/>
  </databaseSettings>

  <common>
    <logging>
      <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net">
        <!-- choices are INLINE, FILE, FILE-WATCH, EXTERNAL-->
        <!-- otherwise BasicConfigurer.Configure is used   -->
        <!-- log4net configuration file is specified with key configFile-->
        <arg key="configType" value="INLINE"/>
        <arg key="configFile" value="filename"/>
      </factoryAdapter>
    </logging>
  </common>

  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%-5level %logger - %message%newline"/>
      </layout>
    </appender>

    <!-- Set default logging level to DEBUG -->
    <root>
      <level value="DEBUG"/>
      <appender-ref ref="ConsoleAppender"/>
    </root>

    <!-- Set logging for Spring.  Logger names in Spring correspond to the namespace -->
    <logger name="Spring">
      <level value="INFO"/>
    </logger>

    <logger name="Spring.Data">
      <level value="DEBUG"/>
    </logger>

    <logger name="NHibernate">
      <level value="INFO"/>
    </logger>

  </log4net>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

需要注意的地方:
      <resource uri="assembly://SpringNHibernateTest/SpringNHibernateTest.Conf/applicationContext_hibernate.xml"/>
      <resource uri="assembly://SpringNHibernateTest/SpringNHibernateTest.Conf/applicationContext_PM.xml"/>

这2句的意思就是去寻找Spring的配置文件。注意这2个文件的生成操作均为:嵌入的资源。

<databaseSettings>
    <add key="db.datasource" value="192.168.1.186"/>
    <add key="db.user" value="root"/>
    <add key="db.password" value="root"/>
    <add key="db.database" value="hellodb"/>
  </databaseSettings>

为数据库的所用,其实就是设置一些Key-Value对,其使用在applicationContext_hibernate.xml中,稍后解释

然后下面的语句就是配置日志的,这里稍微注意下,用Spring带的一套吧。(本人很悲情的使用了以前的log4Net 配合Spring中的common.logging ,结果各种悲剧报错)

解下来是hibernate的配置:applicationContext_hibernate.xml:

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
         xmlns:db="http://www.springframework.net/database"
         xmlns:tx="http://www.springframework.net/tx">

  <!-- Referenced by main application context configuration file -->
  <description>
    The Northwind object definitions for the Data Access Objects.
  </description>

  <!-- Property placeholder configurer for database settings -->
  <object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
    <property name="ConfigSections" value="databaseSettings"/>
  </object>

  <!-- Database Configuration -->
  <db:provider id="DbProvider"
                   provider="MySql"
                   connectionString="Database=${db.database};Data Source=${db.datasource};User Id=${db.user};Password=${db.password}"/>

  <!-- NHibernate Configuration -->
  <object id="NHibernateSessionFactory" type="SpringNHibernateTest.Common.NHibernate.CustomLocalSessionFactoryObject, SpringNHibernateTest">
    <property name="DbProvider" ref="DbProvider"/>
    <property name="MappingAssemblies">
      <list>
        <value>SpringNHibernateTest</value>
      </list>
    </property>
    <property name="HibernateProperties">
      <dictionary>
        <entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
        <entry key="dialect" value="NHibernate.Dialect.MySQLDialect"/>
        <entry key="connection.driver_class" value="NHibernate.Driver.MySqlDataDriver"/>
        <entry key="use_proxy_validator" value="false" />
        <entry key="proxyfactory.factory_class" value="NHibernate.Bytecode.DefaultProxyFactoryFactory , NHibernate"/>
      </dictionary>
    </property>

    <!-- provides integation with Spring's declarative transaction management features -->
    <property name="ExposeTransactionAwareSessionFactory" value="true" />

  </object>

  <!-- Transaction Management Strategy - local database transactions -->
  <object id="transactionManager"
        type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate32">

    <property name="DbProvider" ref="DbProvider"/>
    <property name="SessionFactory" ref="NHibernateSessionFactory"/>

  </object>

  <object id="TransactionInterceptor" type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
    <property name="TransactionManager" ref="transactionManager"/>
    <property name="TransactionAttributeSource">
      <object type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data"/>
    </property>
  </object>
  
  <!-- Exception translation object post processor -->
  <object type="Spring.Dao.Attributes.PersistenceExceptionTranslationPostProcessor, Spring.Data"/>

  <tx:attribute-driven />
</objects>

 

 

首先第一句:

<object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
    <property name="ConfigSections" value="databaseSettings"/>
  </object>

这个就是上面讲的读取那些 Key-Value,使用的时候如下所示:用${} 来读取

<db:provider id="DbProvider"
                   provider="MySql"
                   connectionString="Database=${db.database};Data Source=${db.datasource};User Id=${db.user};Password=${db.password}"/>

需要注意的是provider 不要乱写!!

然后:

<property name="MappingAssemblies">
      <list>
        <value>SpringNHibernateTest</value>
      </list>
    </property>

Value值就是Mapping文件所在的项目名称。

最后几句就是开启Spring的事物处理。

需要注意的是那个很小的几个字母:  <tx:attribute-driven />。本人在此悲剧了半天。。一定要加上!

最后PM.XML 就是我们平时频繁修改的文件了:

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
         xmlns:db="http://www.springframework.net/database">

  <!-- Referenced by main application context configuration file -->
  <description>
    PM
  </description>
  
  <!-- Data Access Objects -->
  <object id="ProductDAO" type="SpringNHibernateTest.PM.DAO.ProductDAO, SpringNHibernateTest">
    <property name="SessionFactory" ref="NHibernateSessionFactory"/>
  </object>
  <object id="ProductService" type="SpringNHibernateTest.PM.Service.ProductService, SpringNHibernateTest">
    <property name="ProductDAO" ref="ProductDAO"/>
  </object>
</objects>

 

 这个文件的格式都很简单,照着写就行了。

另外需要注意DAO的书写:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SpringNHibernateTest.PM.DAO.iface;
using SpringNHibernateTest.Common.DAO;
using SpringNHibernateTest.PM.Entity;

using Spring.Stereotype;
using Spring.Transaction.Interceptor;
namespace SpringNHibernateTest.PM.DAO
{
    [Repository]
    public class ProductDAO : HibernateDao,IProductDAO
    {
        [Transaction(ReadOnly = true)]
        public Product Get(int productId)
        {
            return CurrentSession.Get<Product>(productId);
        }

        [Transaction(ReadOnly = true)]
        public IList<Product> GetAll()
        {
            return GetAll<Product>();
        }

        [Transaction]
        public int Save(Product product)
        {
            return (int)CurrentSession.Save(product);
        }

        [Transaction]
        public void Update(Product product)
        {
            CurrentSession.SaveOrUpdate(product);
        }

        [Transaction]
        public void Delete(Product product)
        {
            CurrentSession.Delete(product);
        }
    }
}

 

注意那些标签,用于事务处理的。

然后测试代码:

IApplicationContext ctx = ContextRegistry.GetContext();

ProductService dao = ctx.GetObject("ProductService") as ProductService;

MessageBox.Show(dao.Get(1).PName);

 

还有需要注意的一点,本人在此也停顿了一会的问题:

引用Spring.Data.NHibernate.dll 没有效果,每次编译VS就默认把这个dll忽略了。导致编译不通过,遇到此种情况,请检查项目的目标框架,正确的应该是:.NET Framework 4

 

--不会上传附件,就不带源码了。具体请参照Spring.Net 的例子:Spring.Data.NHibernate.Northwind

 

 

 

 

 

 

posted on 2012-04-27 17:04  Rush_Sykes  阅读(931)  评论(0编辑  收藏  举报