因为最近无意中学了AOP ,所以想一探究竟,看看.net里这个Spring.Net 到底是怎么回事,请有需要的童鞋往下,不需要的请alt+w。因为是先配置的 Nhibernate 所以就从这个开始。开发环境:VS2012
1. 下载Nhibernate 我这里用的是 NHibernate-3.3.2.GA-bin
2. 添加映射文件 *.hbm.xml 当然 你可以使用映射或者其他一些方式 不过这个比较常用 需要注意的地方有如下几点:
1.这个映射文件需要在属性中设置为 嵌入的资源,如果丢了这一步 可能会异常。
2. 在映射文件里, 程序集以及命名空间很重要。
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="TestNHISpringIntegral.Core" namespace="TestNHISpringIntegral.Core.Model">
这个对应的是model的。
3. 列名一定要对应上,主键外键这些的设置也要注意,在这里就不再赘述。 例子如下:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="TestNHISpringIntegral.Core" namespace="TestNHISpringIntegral.Core.Model"> 3 4 <class name="Author" table="Authors" lazy="false" > 5 <cache usage="read-write"/> 6 <id name="Id" column="Id" type="Int32"> 7 <generator class="identity"/> 8 </id> 9 <property name="FirstName" length="50" type="String" column="FirstName" /> 10 <property name="LastName" length="50" type="String" column="LastName" /> 11 12 </class> 13 </hibernate-mapping>
3.添加 NHibernate 配置文件 从配置模板里复制出对应的配置文件,我这里是sql2005,请童鞋参照自己的数据库进行设置,注意 将此文件放到bin里面,这样方便读取,还要在app.config 或者web.config 里设置下section,因为顺序是先单独配置,然后进行整合所以可能在后续的内容里会重新设置,请童鞋注意。section 必须是放在最前面 否则依然会报错
1.在app.config 或者web.config里添加如下内容:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" /> </configSections> </configuration>
2.修改数据库相关配置:
1 <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" > 2 <session-factory> 3 <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property> 4 <property name="connection.connection_string">Server=.\SQLEXPRESS;Database=BookDemo;Integrated Security=SSPI</property> 5 6 <!--<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property> 7 <property name="adonet.batch_size">10</property> 8 <property name="show_sql">false</property> 9 <property name="use_outer_join">true</property> 10 <property name="command_timeout">60</property> 11 <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property> 12 <property name="proxyfactory.factory_class">NHibernate.ByteCode.Spring.ProxyFactoryFactory, NHibernate.ByteCode.Spring</property>--> 13 14 <!-- mapping files 关键配置,否则出异常:No persister for --> 15 <mapping assembly="TestNHISpringIntegral.DAO" /> 16 </session-factory> 17 </hibernate-configuration>
上面注释掉的内容都是在配置完成之后正式使用的时候才需要的内容,所以我这里全部注释掉了。
4.到这里 NHibernate 就配置完成了,童鞋们可以写代码自己测试下 我的代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using NHibernate; 6 using NHibernate.Cfg; 7 8 namespace TestNhibreateWithConsole 9 { 10 public class ConfigurationHelper 11 { 12 private Configuration _config; 13 14 private static ISessionFactory _sessionFactory; 15 public ConfigurationHelper() 16 { 17 _config=new Configuration(); 18 } 19 20 21 22 private ISessionFactory SessionFactory 23 { 24 get 25 { 26 if (_sessionFactory == null) 27 { 28 _config= new Configuration().Configure(); 29 _sessionFactory = _config.BuildSessionFactory(); 30 } 31 return _sessionFactory; 32 } 33 } 34 public ISession OpenSession() 35 { 36 return SessionFactory.OpenSession(); 37 } 38 39 40 } 41 }
页面上如下:
1 static void Main(string[] args) 2 { 3 using (var sessionFactory = new ConfigurationHelper().OpenSession()) 4 { 5 6 var user = sessionFactory.CreateCriteria<R.Books>(); 7 var auList = user.List<R.Books>(); 8 auList.ToList().ForEach(au => Trace.WriteLine(au.Publisher)); 9 10 } 11 12 }
忘记说明一点 因为这个NHibernate 依赖其他程序集 请一并进行引用。到这里NHibernate 配置就完成了,下面是spring.net 的配置
5. 引用spring.net 相关程序集,因为我这里是使用的web测试的 所以将一些文件都分开了,我的文件目录如图:
6.各个程序集的配置以及使用,我将分步描述
1.在DAO里面添加Mapping,并添加映射文件。
2.在core里面添加model 并且添加相应的类,注意 这里spring 使用的是castle 所以记住一定要用virtual 修饰 例子如下
1 using System; 2 3 namespace TestNHISpringIntegral.Core.Model 4 { 5 [Serializable] 6 public class Author 7 { 8 public virtual Int32 Id { get; set; } 9 public virtual String FirstName { get; set; } 10 public virtual String LastName { get; set; } 11 } 12 }
3.添加IRepository 泛型类 所有的实体都将继承这个。 代码如下
1 public interface IRepository<T> 2 { 3 void Delete(T entity); 4 T Get(object id); 5 object Save(T entity); 6 void Update(T entity); 7 }
4.使用泛型Repository模式,代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Spring.Data.NHibernate.Support; 6 7 namespace TestNHISpringIntegral.Core 8 { 9 public class NHibernateRepository<T> : Spring.Data.NHibernate.Generic.Support.HibernateDaoSupport,IRepository<T> 10 { 11 public object Save(T entity) 12 { 13 // return Spring.Data.NHibernate.Generic.HibernateTemplate 14 return this.HibernateTemplate.Save(entity); 15 } 16 17 public T Get(object id) 18 { 19 return HibernateTemplate.Get<T>(id); 20 21 } 22 23 public void Update(T entity) 24 { 25 HibernateTemplate.Update(entity); 26 } 27 28 public void Delete(T entity) 29 { 30 HibernateTemplate.Delete(entity); 31 } 32 } 33 }
可能出现的问题以及解决方法,这里的HibernateTemplate 需要引用Spring.Data.NHibernate32 程序集,请注意继承的接口不是Spring.Data.NHibernate.Support 这个命名空间下的,如果这里忽视可能会出 TypeMismatchException: Cannot convert property value of type[Spring.Data.NHibernate.HibernateTemplate] to required type [Spring.Data.NHibernate.Generic.HibernateTemplate] for property ... Spring.Data.NHibernate.Generic.HibernateTemplate Spring.Data.NHibernate.HibernateTemplate-
这个错误是第一个,第二 可能在
1 public T Get(object id) 2 { 3 return HibernateTemplate.Get<T>(id); 4 5 }
这个代码处会出现错误,如果童鞋遇到请参考我说的不同命名空间导致的问题,如果不对的话这个地方应该是提供两个参数,我配置的时候也曾在这个地方改过,后来因为程序集转换的时候改了命名空间所以这个就改回去了
5. 添加xml配置文件 我的配置文件如下 这里主要是一个数据库的连接配置,因为这里由spring 接管所以需要这个配置,我的配置如下
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net" 3 xmlns:db="http://www.springframework.net/database"> 4 <!-- 用以我们在其它的应用程序中,配置数据访问 --> 5 <object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core"> 6 <property name="ConfigSections" value="databaseSettings"/> 7 </object> 8 9 <!-- 数据库和Nhibernate的相关配置 --> 10 <db:provider id="DbProvider" provider="SqlServer-2.0" 11 connectionString="Server=${db.datasource};database=${db.database};uid=${db.user};pwd=${db.password};"/> 12 13 14 15 <!--SessionFactory对象,其中包括一些比较重要的属性 --> 16 <object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate32"> 17 <property name="DbProvider" ref="DbProvider"/> 18 <property name="MappingAssemblies"> 19 <list> 20 <!--<value>Model</value>--> 21 <value>TestNHISpringIntegral.DAO</value> 22 </list> 23 </property> 24 <property name="HibernateProperties"> 25 <dictionary> 26 <entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/> 27 <entry key="dialect" value="NHibernate.Dialect.MsSql2005Dialect"/> 28 <entry key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/> 29 <entry key="use_outer_join" value="true"/> 30 <entry key="show_sql" value="false"/> 31 <!--自动建表(反向映射)--> 32 <entry key="hbm2ddl.auto" value="update"/> 33 <entry key="adonet.batch_size" value="10"/> 34 <entry key="command_timeout" value="60"/> 35 <!--显式启用二级缓存--> 36 <entry key="cache.use_second_level_cache" value="true"/> 37 <!--启动查询缓存--> 38 <entry key="cache.use_query_cache" value="false"/> 39 <entry key="query.substitutions" value="true 1, false 0, yes 'Y', no 'N"/> 40 <!--<entry key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"/>--> 41 </dictionary> 42 </property> 43 <property name="ExposeTransactionAwareSessionFactory" value="true" /> 44 </object> 45 46 <object id="HibernateTemplate" type="Spring.Data.NHibernate.Generic.HibernateTemplate"> 47 <property name="SessionFactory" ref="NHibernateSessionFactory" /> 48 <property name="TemplateFlushMode" value="Auto" /> 49 <property name="CacheQueries" value="true" /> 50 </object> 51 52 53 54 <object id="repository.Author" type="TestNHISpringIntegral.Core.NHibernateRepository<TestNHISpringIntegral.Core.Model.Author>,TestNHISpringIntegral.Core"> 55 <property name="HibernateTemplate" ref="HibernateTemplate"/> 56 </object> 57 58 59 </objects>
可能会出现的问题
1. modle 那里是映射文件所在程序集 请正确配置
2.数据库的不一样导致provider也不一样,不同的数据库有不同的配置,比如原来我的是
<db:provider id="DbProvider" provider="SqlServerCe-3.1" connectionString="Server=${db.datasource};Initial Catalog=${db.database};Integrated Security=SSPI;"/>
但是spring 加载的时候始终提示未识别的关键字Server 这里是因为我的provider 配置错误导致的 正确的 请参考上面的配置文件,我的数据库是sql2005。
3.这里的${db.datasource};是占位符一样的东西,在后面由app.config 或者webconfig传入,请童鞋清楚。
1 <object id="repository.Author" type="TestNHISpringIntegral.Core.NHibernateRepository<TestNHISpringIntegral.Core.Model.Author>,TestNHISpringIntegral.Core"> 2 <property name="HibernateTemplate" ref="HibernateTemplate"/> 3 </object>
这里的<也许让你很奇怪是不是格式错误,因为这里使用的是泛型的 Repository 所以被加载后实际上是 NHibernateRepository<Model.Author>了,请童鞋对此不必惊慌 注意这里的程序集一定要配置程序集正确 不然会引起 1.System.TypeLoadException: Could not load type from string value'xxxxxx' 2.无法从程序集'xxxxx'加载某个方法。如果这两个问题都没有出现 报告程序集转换错误的问题,请看前面关于这个错误的具体解决方法,就是命名空间的问题
6.添加bll
1.添加接口,我这里代码如下
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using TestNHISpringIntegral.Core; 5 using System.Text; 6 using M=TestNHISpringIntegral.Core.Model; 7 8 namespace TestNHISpringIntegral.Bll 9 { 10 public interface IAuthor 11 { 12 void Delete(M.Author entity); 13 M.Author Get(object id); 14 object Save(M.Author entity); 15 void Update(M.Author entity); 16 IRepository<M.Author> AuthorRepository { get; set; } 17 } 18 }
2.实现接口 代码如下
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using TestNHISpringIntegral.Core; 6 using M=TestNHISpringIntegral.Core.Model; 7 8 namespace TestNHISpringIntegral.Bll 9 { 10 public class Author:IAuthor 11 { 12 public IRepository<M.Author> AuthorRepository { get; set; } 13 public void Delete(M.Author entity) 14 { 15 AuthorRepository.Delete(entity); 16 17 } 18 19 public M.Author Get(object id) 20 { 21 return AuthorRepository.Get(id); 22 } 23 24 public object Save(M.Author entity) 25 { 26 return AuthorRepository.Save(entity); 27 } 28 29 public void Update(M.Author entity) 30 { 31 AuthorRepository.Update(entity); 32 } 33 } 34 }
3.添加配置文件 我的配置文件如下:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net"> 3 4 <object id="transactionManager" 5 type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate32"> 6 <property name="DbProvider" ref="DbProvider"/> 7 <property name="SessionFactory" ref="NHibernateSessionFactory"/> 8 </object> 9 10 11 <object id="transactionInterceptor" type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data"> 12 <property name="TransactionManager" ref="transactionManager"/> 13 <property name="TransactionAttributeSource"> 14 <object type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data"/> 15 </property> 16 </object> 17 18 <object id="BaseTransactionManager" type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data" abstract="true"> 19 <property name="PlatformTransactionManager" ref="transactionManager"/> 20 <property name="TransactionAttributes"> 21 <name-values> 22 <add key="Save*" value="PROPAGATION_REQUIRED"/> 23 <add key="Set*" value="PROPAGATION_REQUIRED"/> 24 <add key="Finish*" value="PROPAGATION_REQUIRED"/> 25 <add key="Update*" value="PROPAGATION_REQUIRED"/> 26 <add key="Delete*" value="PROPAGATION_REQUIRED"/> 27 <add key="Add*" value="PROPAGATION_REQUIRED"/> 28 <add key="Get*" value="PROPAGATION_SUPPORTS,readOnly"/> 29 <add key="Find*" value="PROPAGATION_SUPPORTS,readOnly"/> 30 <add key="Load*" value="PROPAGATION_SUPPORTS,readOnly"/> 31 <add key="*" value="PROPAGATION_REQUIRED"/> 32 </name-values> 33 </property> 34 </object> 35 36 <object id="AuthorManager" parent="BaseTransactionManager"> 37 <property name="Target"> 38 <object type="TestNHISpringIntegral.Bll.Author,TestNHISpringIntegral.Bll"> 39 <property name="AuthorRepository" ref="repository.Author"/> 40 </object> 41 </property> 42 </object> 43 44 </objects>
这部分代码我是从之前别人的东西里扒出来的,稍稍修改了下,请童鞋根据自己的东西进行修改,需要特别注意的是这里的配置文件都要在属性里设置为嵌入的资源
7.测试最终结果此时的配置文件
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <!-- 4 有关如何配置 ASP.NET 应用程序的详细信息,请访问 5 http://go.microsoft.com/fwlink/?LinkId=169433 6 --> 7 8 <configuration> 9 10 <configSections> 11 <sectionGroup name="spring"> 12 <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/> 13 <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/> 14 <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/> 15 </sectionGroup> 16 17 <section name="databaseSettings" type="System.Configuration.NameValueSectionHandler"/> 18 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" /> 19 20 </configSections> 21 <system.web> 22 <compilation debug="true" targetFramework="4.0" /> 23 </system.web> 24 <spring> 25 <parsers> 26 <parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"/> 27 <parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data"/> 28 </parsers> 29 <context> 30 <resource uri="assembly://TestNHISpringIntegral.Core/TestNHISpringIntegral.Core/Repository.xml"/> 31 <resource uri="assembly://TestNHISpringIntegral.Bll/TestNHISpringIntegral.Bll/Manager.xml"/> 32 </context> 33 34 </spring> 35 36 <log4net> 37 <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> 38 <layout type="log4net.Layout.PatternLayout"> 39 <conversionPattern value="%-5level %logger - %message%newline" /> 40 </layout> 41 </appender> 42 43 <!-- Set default logging level to DEBUG --> 44 <root> 45 <level value="DEBUG" /> 46 <appender-ref ref="ConsoleAppender" /> 47 </root> 48 49 <!-- Set logging for Spring. Logger names in Spring correspond to the namespace --> 50 <logger name="Spring"> 51 <level value="INFO" /> 52 </logger> 53 54 <logger name="Spring.Data"> 55 <level value="DEBUG" /> 56 </logger> 57 58 <logger name="NHibernate"> 59 <level value="INFO" /> 60 </logger> 61 62 63 </log4net> 64 <databaseSettings> 65 <add key="db.datasource" value=".\SQLEXPRESS" /> 66 <add key="db.database" value="BookDemo" /> 67 <add key="db.user" value="sa"/> 68 <add key="db.password" value="123456"/> 69 </databaseSettings> 70 71 <!--<runtime> 72 73 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 74 75 <dependentAssembly> 76 77 <assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" /> 78 79 <bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" /> 80 81 </dependentAssembly> 82 83 </assemblyBinding> 84 85 </runtime>--> 86 87 </configuration>
里面的程序集
1 <context> 2 <resource uri="assembly://TestNHISpringIntegral.Core/TestNHISpringIntegral.Core/Repository.xml"/> 3 <resource uri="assembly://TestNHISpringIntegral.Bll/TestNHISpringIntegral.Bll/Manager.xml"/> 4 </context>
对应的是前面添加的配置文件,请配置正确,否则也会报错跑不起来,这里因为我忘记具体的错误了,所以只是提醒大家注意这里,这样整个就贯穿起来了。
页面代码:
log4net.Config.XmlConfigurator.Configure();
IApplicationContext applicationContext = ContextRegistry.GetContext();
authorManager = (IAuthor)applicationContext.GetObject("AuthorManager");
var authorM=authorManager.Get(2);
Response.Write(authorM.FirstName+"^^^^^^^");
到此全部完成,至于MVC 只是调用所以就没写上来,大家自己去整合,如果有问题请留言大家一起探讨,不喜勿喷。