NHibernate level cache (tenth article)
NHibernate first-level cache, the noun seems to be very cow B, difficult. is actually the ISession cache. stored in the operating cycle of the ISession. The level two cache is stored in the isessionfactory.
first, ISession level cache test
ISession first-level cache is turned on by default, no configuration is required. The ISession cache can be used after the ISession is created, and each time the data is manipulated through this isession, the ISession detects whether or not it is slow to have the corresponding data, and if so, returns directly. If not, the database is queried for return and cached to ISession. When the ISession instance is freed, the cache is automatically destroyed.
Example:
First we start by opening the Show_sql node in the configuration file:
<name= "Show_sql">true</Property> //Open this has no effect on this cache test, just look at the effect
PersonDao.cs
Class Persondao { new Configuration (). Configure (). Buildsessionfactory (); ISession session; public Persondao () {session = sessionfactory.opensession ();}
Public Personmodel Getpersonbyid (int Id) {Personmodel p = session. get<personmodel>return p;}}
Program.cs
Classprogram {Staticvoid Main (string[] args) {Persondao dao = new Persondao (); // first read personmodel P1 = dao. Getpersonbyid (3" + P1. Name); // second read personmodel P2 = dao. Getpersonbyid (3" + P2. Name); Console.readkey (); } }
Output:
We saw that only the first query executed the SQL statement, and the second time no statements were executed. This can also be monitored from the SQL Server Profiler.
Get the same instance in two sessions
Below we put
Sessionfactory.opensession ();
What happens when this line of code is put into a method?
Public Personmodel Getpersonbyid (int Id) { ISession session = sessionfactory.opensession (); Personmodel p = Session. Get<personmodel>(Id); return p;}
The output results are as follows:
Notice that every opensession once, the cache is gone. Opensession once, NHibernate will automatically release the original ISession object.
When you see this, you should be aware of your code.
ii. differences between Isession.get () and Isession.load ()
Don't want to talk nonsense, more than 10 lines of code to explain the problem:
Staticvoid Main (String[] args) {Isessionfactory sessionfactory =NewConfiguration (). Configure (). Buildsessionfactory (); ISession session =Sessionfactory.opensession (); Console.WriteLine ("Get before"); Personmodel Pget = session. Get<personmodel> (1); Console.WriteLine ("After get"); Console.WriteLine ("Read name "+ Pget.name); Console.WriteLine ( "================================ ===== "); Console.WriteLine ( "load before "); Personmodel pload = session. Load<personmodel> (2 "load "); Console.WriteLine ( " Read the name "+ Pload.name); Console.readkey (); }
The output results are as follows:
Note that when get () executes, it is immediately read to the database. While load () is delayed loading, to be used, take the database to read without reading.
No get<> or load<> can be cached
Now let's change Persondao to this:
Class Persondao { new Configuration (). Configure (). Buildsessionfactory (); ISession session; public Persondao () {session = Publicilist<personmodel>return session. Queryover<personmodel>(). List (); } }
Program.cs
void Main (string[] args) { new Persondao (); ilist<personmodel> PersonList1 = dao. Getpersonlist (); Console.WriteLine (personlist1[0]. Name); ilist<personmodel> PersonList2 = dao. Getpersonlist (); Console.WriteLine (personlist1[0]. Name); Console.readkey (); }
Output:
Note that two SQL statements have been executed. It appears that only get () or load () can use NHibernate's first-level cache.
Management of 三、一级 cache
What if we don't want to use a first-level cache when we use get () or load ()? Answer, using
As we go back to the first example of this article, we only change the following bold code:
Class Persondao { new Configuration (). Configure (). Buildsessionfactory (); public Persondao () {session = PublicPersonmodel getpersonbyid (int Id) {Personmodel p = sess Ion. get<personmodel>return p;}}
Program.cs
Staticvoid Main (string[] args) {Persondao dao = new Persondao ();
//
first read personmodel P1 = dao. Getpersonbyid (3" + P1. Name); // second read personmodel P2 = dao. Getpersonbyid (3" + P2. Name); Console.readkey (); }
The output results are as follows:
You can see NHibernate or honestly execute two SQL statements.
NHibernate provides the following three ways to manage a first-level cache.
- Isession.evict (object): Deletes the specified instance from the cache.
- Isession.clear (): empties the cache.
- Isession.contains (object): Checks whether the cache contains the specified instance.
- Isession.refresh (object): Refreshes a single instance in the cache.
An example illustrates the problem:
Staticvoid Main (String[] args) {Isessionfactory sessionfactory =NewConfiguration (). Configure (). Buildsessionfactory (); ISession session =Sessionfactory.opensession (); Personmodel P1 = Session. Get<personmodel> (1); Personmodel P2 = session. Get<personmodel> (2); Personmodel P3 =New Personmodel (); Console.WriteLine (session. Contains (p1)); // output True Console.WriteLine (session. Contains (p2)); // output true session. Evict (p1); // remove P1 from the first-level cache to see if you still con contains Console.WriteLine ( Session. Contains (p1)); // output False Console.WriteLine (session. Contains (p2)); // output true session. Clear (); // All empty, see you still con not CONTAINSP2 Console.WriteLine (session. Contains (p2)); // output False
The output results are as follows:
Refresh cache:
void Main (string[] args) { new Configuration (). Configure (). Buildsessionfactory (); ISession session = sessionfactory.opensession (); Personmodel P1 = Session. Get<personmodel> (1); Thread.Sleep (+); Console.WriteLine ("----------------after 3 seconds"); Session. Refresh (p1); Console.readkey (); }
Output Result:
You can see that after 3 seconds, NHibernate re-queried the database to get the latest objects.
NHibernate level cache (tenth article)