NHibernate的简单例子
@(编程)
因为项目需求,搭了一个NHibernate的例子,中间遇到了一些问题,通过各种方法解决了,在这里记录一下最后的结果。
1. 需要的dll
Common.Logging.dll 1.2.0.0
Common.Logging.Log4Net.dll 1.2.0.2
log4net.dll 1.2.10.0
MySql.Data.dll 6.9.8.0
NHibernate.dll 3.0.0.400
Spring.Aop.dll 1.3.1.40711
Spring.Core.dll 1.3.1.40711
Spring.Data.dll 1.3.1.40711
Spring.Data.NHibernate30.dll 1.3.1.40711
2.需要安装的程序
MySQL-connector-net
如果不安装,则报错,大致如下:
Error thrown by a dependency of object 'MySql-5.0' defined in 'assembly [Spring.Data, Version=1.1.2.20125, Culture=neutral, PublicKeyToken=65e474d141e25e07], resource [Spring.Data.Common.dbproviders.xml]' :
2.Unsatisfied dependency expressed through constructor argument with index 2 of type [System.Type] :
3.Could not convert constructor argument value [MySql.Data.MySqlClient.MySqlConnection, MySql.Data, Version=5.0.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d] to required type [System.Type] :
4.Cannot convert property value of type [System.String] to required type [System.Type] for property ''.
5.while resolving 'constructor argument with name dbmetadata' to '(inner object)' defined in 'assembly [Spring.Data, Version=1.1.2.20125, Culture=neutral, PublicKeyToken=65e474d141e25e07], resource [Spring.Data.Common.dbproviders.xml]'
另外这个版本一定要与上面的mysql.data.dll版本相同。
3. 数据库SQL
CREATE TABLE `account` (
`id` varchar(45) NOT NULL,
`name` varchar(45) DEFAULT NULL,
`code` varchar(45) DEFAULT NULL,
`balance` double DEFAULT NULL,
`exchange` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
4. 实体与映射文件
Account
namespace NHibernateDemo
{
/// <summary>
/// 用户账户
/// </summary>
public class Account
{
public virtual string Id { get; set; }
/// <summary>
/// 账户名称
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// 账户编码
/// </summary>
public virtual string Code { get; set; }
/// <summary>
/// 账户当前余额
/// </summary>
public virtual double Balance { get; set; }
/// <summary>
/// 交易所
/// </summary>
public virtual string Exchange { get; set; }
}
}
Account.hbm.xml
要设置为嵌入的资源
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemo">
<class name="NHibernateDemo.Account" table="account" lazy="false" >
<id name="Id" unsaved-value="null" column="id" type="string" />
<property name="Name" column="name" length="40" not-null="true" />
<property name="Code" column="code" length="30" not-null="false"/>
<property name="Balance" column="balance" length="30" not-null="false"/>
<property name="Exchange" column="exchange" length="60" not-null="false"/>
</class>
</hibernate-mapping>
5. DAO
IAccountDao
using System.Collections.Generic;
namespace NHibernateDemo
{
public interface IAccountDao
{
IList<Account> GetAll();
}
}
AccountDaoImpl
using Spring.Data.NHibernate;
using System;
using System.Collections.Generic;
namespace NHibernateDemo
{
[Spring.Stereotype.Repository]
public class AccountDaoImpl : IAccountDao
{
public HibernateTemplate HibernateTemplate { set; get; }
public IList<Account> GetAll()
{
try
{
Account entity = new Account();
entity.Id = Guid.NewGuid().ToString();
entity.Balance = 0;
entity.Code = "a";
entity.Exchange = "b";
entity.Name = "c";
this.HibernateTemplate.Save(entity);
var result = this.HibernateTemplate.LoadAll(typeof(Account));
foreach (Account item in result)
{
Console.WriteLine(item.Name);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return null;
}
}
}
6. BLL
SpringFactory
using NHibernate;
namespace NHibernateDemo
{
public sealed class SpringFactory
{
public static IAccountDao GetAccountDao()
{
return SpringHelper<IAccountDao>.GetObject("AccountDao");
}
}
}
SpringHelper
namespace NHibernateDemo
{
using Common.Logging;
using Spring.Context;
using Spring.Context.Support;
using System;
using System.Reflection;
public sealed class SpringHelper<T>
where T : class
{
#region Static Fields
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#endregion
#region Public Methods and Operators
/// <summary>
/// 传入objId 通过Spring得到对应实体
/// </summary>
/// <param name="objId"></param>
/// <param name="withLog"></param>
/// <returns></returns>
public static T GetObject(string objId, bool withLog = true)
{
if (string.IsNullOrEmpty(objId))
{
return default(T);
}
try
{
IApplicationContext ctx = ContextRegistry.GetContext();
return ctx.GetObject(objId) as T;
}
catch (Exception ex)
{
if (withLog)
{
Log.Error("", ex);
}
return default(T);
}
}
#endregion
}
}
7.配置文件
App.config
<?xml version="1.0" encoding="utf-8" ?>
<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"/>
</sectionGroup>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net">
<arg key="configType" value="FILE-WATCH"/>
<arg key="configFile" value="config/Log4Net.xml"/>
</factoryAdapter>
</logging>
</common>
<spring>
<context>
<resource uri="config/ApplicationContext.xml"/>
</context>
</spring>
</configuration>
ApplicationContext.xml
<?xml version="1.0" ?>
<objects default-autowire="byName" default-lazy-init="true" xmlns:db="http://www.springframework.net/database" xmlns:tx="http://www.springframework.net/tx" xmlns="http://www.springframework.net">
<!--描述-->
<description>
数据访问的配置信息 包括:DbProvider NHibernate
</description>
<!-- 通过主应用程序的上下文配置文件引用 -->
<object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
<property name="ConfigSections" value="spring/databaseSettings"/>
</object>
<object id="HibernateTransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate30">
<property name="DbProvider" ref="DbProvider"/>
<property name="SessionFactory" ref="NHibernateSessionFactory"/>
</object>
<object id="HibernateTemplate" type="Spring.Data.NHibernate.HibernateTemplate">
<property name="SessionFactory" ref="NHibernateSessionFactory"/>
<property name="TemplateFlushMode" value="Auto"/>
<property name="CacheQueries" value="true"/>
</object>
<!-- 数据库的配置 -->
<db:provider connectionString="Data Source=localhost;User Id=root;Password=password;database=test" id="DbProvider" provider="MySql-5.1"/>
<!-- NHibernate 配置 -->
<!-- 可以通过 name 为其指定别名 name="SessionFactory" -->
<object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject,Spring.Data.NHibernate30">
<!-- 关于数据库连接的配置,直接使用 DbProvider 中的设置,这样,不需要为 Hibernate 再提供连接串和驱动 -->
<property name="DbProvider" ref="DbProvider"/>
<!-- 包含有映射文件的程序集,需要分析的hbm程序集名称 -->
<property name="MappingAssemblies">
<list>
<value>NHibernateDemo</value>
</list>
</property>
<!-- 其他的参数 -->
<property name="HibernateProperties">
<dictionary>
<!-- 方言 -->
<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="show_sql" value="true"/>
</dictionary>
</property>
<!-- 必须增加此项说明,与 Spring 的声明式事务集成 -->
<property name="ExposeTransactionAwareSessionFactory" value="true"/>
</object>
<object id="AccountDao" type="NHibernateDemo.AccountDaoImpl,NHibernateDemo">
<property name="HibernateTemplate" ref="HibernateTemplate"></property>
</object>
</objects>
Log4Net.xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a"/>
</configSections>
<log4net>
<!-- Console部分log输出格式的设定 -->
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level [%file] [ %line行 ] - %message%newline"/>
</layout>
</appender>
<!-- 日志文件部分log输出格式的设定 -->
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<file value="log.txt"/>
<appendToFile value="true"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="1MB"/>
<rollingStyle value="Size"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<header value=""/>
<footer value=""/>
<ConversionPattern value="%date %-5level [%file] [%line行] - %message%newline"/>
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<root>
<level value="ALL"/>
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingLogFileAppender"/>
</root>
</log4net>
</configuration>
8.调用代码
using System;
namespace NHibernateDemo
{
class Program
{
static void Main(string[] args)
{
IAccountDao dao = SpringFactory.GetAccountDao();
dao.GetAll();
Console.Read();
}
}
}