环境:
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:
<?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