Spring.NET 1.3.2 integrates NHibernate 3.2 – 4 – to implement basic data access

A week has passed in the blink of an eye, and I haven’t actually accessed the database yet, so I need to work harder.

Tall buildings rise from the ground, and we start step by step.

1. Prepare data

Data access naturally requires data. Here we use the sample database in the book “Microsoft SQL Server 2008 Technical Insider: T-SQL Language Basics”. The detailed introduction of this book can be found here.

A very good book. Some of the content in it cannot be found elsewhere, such as the query processing process and the introduction to locks in SQL Server. Unfortunately, the address of the sample code provided in the book is blocked. , I uploaded a copy in the blog garden.

Download address: https://files.cnblogs.com/haogj/TSQLFundamentals2008.rar

You must have installed SQL Server 2008, any version is acceptable. In the Query Analyzer window, directly execute the downloaded script to complete the creation of the database. The completed database is as shown in the figure.

Next we will access the Sales.Customers table. The structure of this table is as follows:

2. Create solutions

Open Visual Studio 2010 and create a new website project.

1. Create entity project

In the solution, add a new class library project, here named Forbetter.Domain.

Delete the Class1.cs automatically added in the template, add a class file Customer.cs in it, and modify the code in it to the following content.

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

namespace Forbetter.Domain
{
    public classCustomer
    {
        public virtual int Id { get; private set; }
        public virtual string CompanyName { get; set; }
        public virtual string ContactName { get; set; }
        public virtual string ContactTitle { get; set; }
        public virtual string Address { get; set; }
        public virtual string City { get; set; }
        public virtual string Region { get; set; }
        public virtual string PostalCode { get; set; }
        public virtual string Country { get; set; }
        public virtual string Phone { get; set; }
        public virtual string Fax { get; set; }
    }
}

In the future, our access to the Customer table in the database will be through this class.

It should be noted that the properties are all modified with virtual. This is a requirement of NHibernate.

In order to express the mapping relationship between this class and the relationship, object-relational mapping needs to be defined in NHibernate. There are many mapping methods, the most common of which is to use xml configuration files.

Add an xml file named Customer.hbm.xml to the project. The extension of this file must be hbm.xml. In the future, NHibernate can automatically look for files with this extension to find mapping relationships.

In the properties window, set the generation operation of this file to: Embedded Resource, so that this file will be embedded into the generated dll file by the compiler.

The contents of this file are as follows:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Forbetter.Domain">

  <class name="Forbetter.Domain.Customer" table="Sales.Customers" lazy="false" >
    
    <id name="Id" unsaved-value="null" column="custid" type="int" >
      <generator class="identity" />
    </id>
    
    <property name="CompanyName" column="CompanyName" length="40" not-null="true" index="CompanyName"/>
    <property name="ContactName" length="30" not-null="false"/>
    <property name="ContactTitle" length="30" not-null="false"/>
    <property name="Address" length="60" not-null="false"/>
    <property name="City" length="15" not-null="false" index="City"/>
    <property name="Region" length="15" not-null="false" index="Region"/>
    <property name="PostalCode" length="10" not-null="false" index="PostalCode"/>
    <property name="Country" type="String" length="15" not-null="false"/>
    <property name="Phone" length="24" not-null="false"/>
    <property name="Fax" length="24" not-null="false"/>
  </class>
</hibernate-mapping>

Now, the content of this project should be as follows.

2. Create data access project

Add a third project to the solution,

A reference to Forbetter.Domain needs to be added to the project.

Let’s start using NHibernate here and add a reference to NHibernate to the project. Two assemblies are involved here: NHibernate.dll and Iesi.Collectionss.dll. Spring.NET features are also used in the project, so a reference to Spring.Core.dll needs to be added.

There will be a total of four assembly references.

Add a folder Config to this project, and then add an xml file named dataAccess.xml. The generation attributes of this file also need to be defined as embedded resources, with the following contents:

<?xml version="1.0" ?>
<objects xmlns="http://www.springframework.net"
         xmlns:db="http://www.springframework.net/database"
         xmlns:tx="http://www.springframework.net/tx"
         >
  <!--Description-->
  <description>
    Data access configuration information
    Includes: DbProvider
          NHibernate
  </description>

  <!-- Referenced via the main application's context configuration file -->
  <object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">
    <property name="ConfigSections" value="spring/databaseSettings"/>
  </object>

  <!-- Database configuration -->
  <db:provider id="DbProvider"
                   provider="SqlServer-2.0"
                   connectionString="Data Source=${db.server};Database=${db.database};Integrated Security=true;"
               />

  <!-- NHibernate configuration -->

  <!-- You can specify an alias name="SessionFactory" -->
  <object id="NHibernateSessionFactory"
          type="Spring.Data.NHibernate.LocalSessionFactoryObject,Spring.Data.NHibernate32"
          >

    <!-- Regarding the configuration of the database connection, use the settings in DbProvider directly. In this way, there is no need to provide a connection string and driver for Hibernate -->
    <property name="DbProvider" ref="DbProvider"/>

    <!-- The assembly containing the mapping file, the name of the hbm assembly that needs to be analyzed -->
    <property name="MappingAssemblies">
      <list>
        <value>Forbetter.Domain</value>
      </list>
    </property>

    <!-- Other parameters -->
    <property name="HibernateProperties">
      <dictionary>
        <!-- Dialect -->
        <entry key="dialect" value="NHibernate.Dialect.MsSql2008Dialect"/>
        <entry key="use_proxy_validator" value="false" />
        <entry key="show_sql" value="true"/>
        
      </dictionary>
    </property>
    
    <!-- This description must be added to integrate with Spring's declarative transaction -->
    <property name="ExposeTransactionAwareSessionFactory" value="true" />

  </object>
  
</objects>

What needs to be noted here is that in the database connection string, a method similar to ${db.server} is used. db.server here is the variable name defined in the configuration file. We will define it in the configuration file of the main program. These variables are used here by name. When you need to modify the database connection information in the future, you can find this configuration file differently and modify it directly in the configuration file of the main program.

In the second file, the interface for accessing the database using NHibernate is defined. Since all Dao objects need to access the current session object through SessionFactory, the interface INHibernateSessionFactory is defined.

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

namespace Forbetter.Dao
{
    interface INHibernateSessionFactory
    {
        NHibernate.ISessionFactory SessionFactory { set; get; }
    }
}

Then, add a third file, ICustomerDao.cs, which is an interface definition file. In Spring.NET, various parts are coupled through interfaces. This is also a feature of the Spring.NET proxy.

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

namespace Forbetter.Dao
{
    public interface ICustomerDao
    {
        IQueryable<Domain.Customer> GetAllCustomers();
    }
}

The fourth file is CustomerDao.cs, which implements these two interfaces.

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

usingNHibernate.Linq;

namespace Forbetter.Dao
{
    [Spring.Stereotype.Repository]
    public classCustomerDao
        : ICustomerDao, INHibernateSessionFactory
    {
        // Nhibernate session support
        public NHibernate.ISessionFactory SessionFactory { set; get; }

        public IQueryable<Domain.Customer> GetAllCustomers()
        {
            NHibernate.ISession session = this.SessionFactory.GetCurrentSession();

            var query = session.Query<Domain.Customer>();

            var result = from customer in query
                         orderby customer.CompanyName
                         select customer;
            return result;
        }
    }
}

The SessionFactory is injected using Spring.NET below.

Add a fifth file, objects.xml, where you use Spring.NET to define data access objects and inject them. Note that the generation method also needs to be an embedded resource.

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

  <object id="CustomerDaoImpl" type="ForBetter.Dao.CustomerDao, ForBetter.Dao" >
    <!-- ref represents the referenced object -->
    <property name="SessionFactory" ref="NHibernateSessionFactory" />
  </object>

</objects>

Now that the project is complete, compile it. The content in the project should look like this:

3. Add services

Usually we also need a business layer, here we create a Service project to represent it.

This project needs to reference more content, including the Domain project, the Dao project, and the three Spring.NET assemblies. Spring.Core, Spring.Data, Spring.Aop.

Also define a service interface in the project.

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

namespace Forbetter.Service
{
    public interface ICustomerService
    {
        Forbetter.Dao.ICustomerDao CustomerDao { set; get; }
        IList<Domain.Customer> GetAllCustomers();
    }
}

Then comes the implementation of the service.

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

namespace Forbetter.Service
{
    [Spring.Stereotype.Service]
    [Spring.Transaction.Interceptor.Transaction(ReadOnly=true)]
    public classCustomerService
        :ICustomerService
    {
        public Forbetter.Dao.ICustomerDao CustomerDao { set; get; }

        public IList<Domain.Customer> GetAllCustomers()
        {
            IQueryable<Domain.Customer> query = this.CustomerDao.GetAllCustomers();
            return query.ToList<Domain.Customer>();
        }
    }
}

Add a folder named Config to the project and add an object definition file objects.xml in it.

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
  
  <object id="CustomerServiceImpl" type="Forbetter.Service.CustomerService" >
    <!-- ref represents the referenced object -->
    <property name="CustomerDao" ref="CustomerDaoImpl" />
  </object>

</objects>

The completed project content is as follows.

4. Define Web Project

The work of Spring.NET and NHibernate is finally ready to use. We have created the Web project at the beginning, and now we need to add some content.

First, you need to add many references, including references to the service project, references to the Domain project, and references to NHibernate and Spring.NET. There are also log references.

Note the use of Spring.Data.NHibernate32, which is Spring.NET’s support for NHibernate.

In the project, add a folder named Customer, where our page for managing customer information will be saved.

In the folder, add a standard aspx page named index.aspx. The content of the page is as follows, defining a GridView to display data.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="Sprint_Web_1.Customer.index" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView runat="server" ID="gvCustomer"></asp:GridView>
    </div>
    </form>
</body>
</html>

Modify the code file to the following content. Here we use the CustomerService we defined in the service project to access the data. The properties will be injected through Spring.NET, where the service method is directly called to obtain the list of client objects. Then display it through the GridView on the page.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Sprint_Web_1.Customer
{
    public partial class index : System.Web.UI.Page
    {
        public Forbetter.Service.ICustomerService CustomerService { set; get; }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                IList<Forbetter.Domain.Customer> list = this.CustomerService.GetAllCustomers();
                this.gvCustomer.DataSource = list;
                this.gvCustomer.DataBind();
            }
        }
    }
}

Also add a Config folder to the project.

First add a file named objects.xml to define object injection.

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
  
  <object type="~/Customer/index.aspx">
    <property name="CustomerService" ref="CustomerServiceImpl"/>
  </object>

</objects>

Then add the log configuration file log4net.xml. This time we output the log to the Trace window through log4net.

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <root>
    <level value="OFF" />
    <appender-ref ref="TraceAppender" />
  </root>
  <logger name="NHibernate">
    <level value="DEBUG" />
  </logger>
  
  <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="?te [%thread] %-5level %logger %ndc - %message%newline" />
    </layout>
  </appender>
  
</log4net>

Finally, and the most important thing is the root configuration file web.config of the web project, which is the most important configuration file.

<?xml version="1.0" encoding="utf-8"?>

<!--
  For more information on how to configure an ASP.NET application, visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>

  <configSections>
    <!-- Spring configuration -->
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
      
      <!-- Database configuration parameters -->
      <section name="databaseSettings" type="System.Configuration.NameValueSectionHandler"/>
    </sectionGroup>

    <!-- Log configuration -->
    <sectionGroup name="common">
      <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
    </sectionGroup>
  </configSections>
  <spring>
    <context>
      <resource uri="~/Config/objects.xml"/>
      
      <!-- The configuration file embedded in the assembly, first the assembly name, then the namespace, and finally the file name, note that the case of the name must be exactly the same -->
      <resource uri="assembly://Forbetter.Dao/Forbetter.Dao.Config/dataAccess.xml"/>
      <resource uri="assembly://Forbetter.Dao/Forbetter.Dao.Config/objects.xml"/>
      <resource uri="assembly://Forbetter.Service/Forbetter.Service.Config/objects.xml"/>
    </context>
    
    <!--Database configuration server address-->
    <databaseSettings>
      <add key="db.server" value=".\sqlexpress"/>
      <add key="db.database" value="TSQLFundamentals2008"/>
      <add key="db.userid" value=""/>
      <add key="db.password" value=""/>
    </databaseSettings>
  </spring>

  <common>
    <logging>
      <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net">
        <!-- Use log4net configuration file -->
        <arg key="configType" value="FILE-WATCH" />
        <arg key="configFile" value="~/Config/log4net.xml" />
      </factoryAdapter>
    </logging>
  </common>

  <appSettings>
    <!-- Provide a name for the SessionFactory of OpenSessionInViewModule -->
    <add key="Spring.Data.NHibernate.Support.OpenSessionInViewModule.SessionFactoryObjectName" value="NHibernateSessionFactory"/>
  </appSettings>
  
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpModules>
      <!-- Module provided by Spring -->
      <add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>

      <!--
          To automatically open a session by Spring, a session factory named SessionFactory must be provided
          After use, you can use the GetCurrentSession method of SessionFactory to obtain the session
      -->
      <add name="OpenSessionInView"
           type="Spring.Data.NHibernate.Support.OpenSessionInViewModule, Spring.Data.NHibernate32"/>
    </httpModules>
    <httpHandlers>
      <!-- Handler provided by Spring -->
      <add verb="*" path="*.aspx" type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/>
      <!-- Cancel Spring.NET's processing of Web services -->
      <!--<add verb="*" path="*.asmx" type="Spring.Web.Services.WebServiceHandlerFactory, Spring.Web"/>-->
      <add verb="*" path="ContextMonitor.ashx" type="Spring.Web.Support.ContextMonitor, Spring.Web"/>
      <add verb="*" path="*.ashx" type="Spring.Web.Support.DefaultHandlerFactory, Spring.Web"/>
    </httpHandlers>
  </system.web>

</configuration>

The content of the file has been added with comments to explain it.

3. Source code download

The file is relatively large, and the maximum limit of the blog park is 10M, so it is divided into two files.

The source code for the entire project can be downloaded from here:

Project Document 1

Project Document 2

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 132103 people are learning the system