Building blocks of NHibernate
Now that we know that using an ORM is not essentially a bad idea but can actually be a very productive way of writing code that interacts with the database, let's turn our attention back to NHibernate.
NHibernate stands on three important building blocks. To understand these building blocks is essential to understand and use NHibernate effectively. We are going to explore these building blocks in detail in the coming chapters, but I would like to give you a brief introduction to these now.
Mappings
NHibernate uses mappings to find out which class maps to which database table and which property on the class maps to which column on the table. Every time your application tries to interact with the database, NHibernate refers to the mappings in order to generate the appropriate SQL to be sent to the database for execution.
There are three different ways that you can tell NHibernate about the mappings. One of the ways is based on traditional XML, whereas the other two are based on the code and provide a fluent API to express the mappings. In Chapter 3, Let's Tell NHibernate About Our Database, I will talk about these ways in enough detail. However, mappings that we will use in the other chapters will only be explained using a code-based API, also called mapping by code.
I have simplified mappings for the sake of introduction, but mappings offer a lot of advanced features that go beyond the basics such as mapping tables and columns. These advanced features impact the generation of SQL, performance of the application, and resilience of the data access layer. Hence, it is important to understand and master the mappings in order to use NHibernate most effectively.
Configuration
NHibernate lets you specify via configuration a lot of details that it uses at runtime. These details affect what NHibernate does and how NHibernate does a particular thing. Although configuration is a small thing, it is important to master it. On most projects, you will deal with configuration in the initial phase, and once everything is settled, you will rarely come back to it. The only times that you will come back to it are when you need to turn on or off something and knowing how to do this will save you some time. The NHibernate configuration lets you control the following:
- which database you want to connect to (MS SQL Server, Oracle, and so on)
- where is that database (read connection strings)
- which SQL driver to use (or which SQL client library should NHibernate use)
- where are the class mappings
- should NHibernate log important information
- should NHibernate cache entities by default
- how should NHibernate manage sessions
- should NHibernate use second-level cache
- where is the second-level cache
As you can see, there are some useful configuration options there. We will see the details of these options and how to configure them in Chapter 4, NHibernate Warmup.
Configuration is not just about providing the defaults for a few NHibernate settings. Configuration can be loaded in the memory, and you can do some amazing things with it. One of such commonly done things is the use of the configuration to generate database scripts. Once you define your mappings and build your configuration, you can generate a SQL script to build all database schemas, tables, relations, constraints, indexes and so on. We are going to cover this in detail in Chapter 4, NHibernate Warmup. For now, it is worth noting how important and powerful the NHibernate configuration is.
Session
Session is the most commonly used object from NHibernate. Any database interaction that your application needs to do using NHibernate, it must do so by using a Session
object. Think of a Session
object as a wrapper around the pipe to the database, which is an SQL connection. The
Session
object not only manages the connection to the database but also exposes methods (some directly and the others indirectly through extension methods) that let you write code to interact with the database in the form of queries and create, update, and delete operations. The Session
object also exposes the API for transaction management. Further, the Session
object implements a form of caching that boosts the performance of queries. This list can go on as there are so many features that the Session
object offers. However, let's leave those features to later chapters where we will look at them in detail.
Because of the rich set of features that the Session
object offers, the Session
object is the most commonly used NHibernate type. Since Session
is so commonly used, NHibernate has implemented it in such a way that creating a new Session
object is a very cheap operation. However, this does not mean that you should freely create new instances of the Session
object. There is some penalty that you will have to pay directly or indirectly when you create a large number of session objects randomly. There are some rules that if you play with, you can gain all the benefits of cheap Session
objects. We will cover all of these rules at appropriate times in different chapters of this book.