实现memcache 二级缓存的步骤

第一步:配置memcache服务:

一、Windows下安装Memcache(具体可以参考视频)

第二步:准备所需要的程序集

log4net(要引用log4net,否则Memcached.ClientLibrary.SockIOPool无法实例化)

NHibernate

Memcached.ClientLibrary

NHibernate.Caches.MemCache

 

第三步:App.config 配置文件:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   
 4   <configSections>
 5     <!-- 1.0 配置memcache节点-->
 6     <section name="memcache" type="NHibernate.Caches.MemCache.MemCacheSectionHandler,NHibernate.Caches.MemCache"/>
 7   </configSections>
 8   <!-- 2.0 配置memcache端口节点-->
 9   <memcache>
10     <memcached host="127.0.0.1" port="11211" weight="2"/>
11     <!--<memcached host="{主机}" port="{端口}" weight="{权重}"/>-->
12   </memcache>
13   <startup>
14     
15     
16     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
17   </startup>
18 </configuration>

第四步:设置hibernate.cfg.xml缓存相关参数


<!-- 第三方缓存插件-->
<property name="cache.provider_class">NHibernate.Caches.MemCache.MemCacheProvider,NHibernate.Caches.MemCache</property>
<!--启用二级缓存 -->
<property name="cache.use_second_level_cache">true</property>
<!--启用查询缓存 -->
<property name="cache.use_query_cache">true</property>
<!--设置缓存过期时间-->
<property name="cache.default_expiration">300</property>
<!-- 设置加载影射文件.xml <mapping assembly="{程序集名称}"/>-->
<mapping assembly="NH01"/>
<!--3.配置映射的二级缓存类-->
<class-cache class="NH01.Domain.EmployeeInfo,NH01" usage="read-write"/>
<!--<class-cache class="{类全名称},{程序集名称}" usage="{缓存策略}"/>-->

 

完整hibernate.cfg.xm配置文件:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
 3   <session-factory>
 4     <property name="connection.provider">
 5       NHibernate.Connection.DriverConnectionProvider
 6     </property>
 7     <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
 8     <property name="connection.driver_class">
 9       NHibernate.Driver.SqlClientDriver
10     </property>
11     <property name="show_sql">true</property>
12     <property name="connection.connection_string">server=127.0.0.1;database=Company;uid=sa;pwd=123;</property>
13 
14 
15     <!--配置二级缓存-->
16     <!-- 第三方缓存插件 MemCache <property name="cache.provider_class">NHibernate.Caches.MemCache.MemCacheProvider,NHibernate.Caches.MemCache</property>-->
17     <property name="cache.provider_class">NHibernate.Caches.MemCache.MemCacheProvider,NHibernate.Caches.MemCache</property>
18     <!--自带缓存 <property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider</property>--> 
19     <!--<property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider</property>-->
20     <!--启用级缓存  <property name="cache.use_second_level_cache">{true/false}</property>-->
21     <property name="cache.use_second_level_cache">true</property>
22     <!--打开查询缓存   <property name="cache.use_query_cache">{true/false}</property>-->
23     <property name="cache.use_query_cache">true</property>
24     <!--设置缓存过期时间  <property name="cache.default_expiration">{过期时间}</property>-->
25     <property name="cache.default_expiration">300</property>
26     <!-- 设置加载影射文件.xml  <mapping assembly="{程序集名称}"/>-->
27     <mapping assembly="NH01"/>
28     <!--3.配置映射的二级缓存类-->
29     <class-cache class="NH01.Domain.EmployeeInfo,NH01" usage="read-write"/>
30     <!--<class-cache class="{类全名称},{程序集名称}" usage="{缓存策略}"/>-->
31   </session-factory>
32 </hibernate-configuration>
33 
34 
35 
36 <!--下面对几个重要的key值说明一下:
37 hibernate.connection.provider
38 连接提供者,取值必须是实现了IConnectionProvider接口的类的全名,当前版本只能取值NHibernate.Connection.DriverConnectionProvider;
39 hibernate.connection.driver_class
40 数据驱动类,取值必须是实现了IDriver接口的类的全名,常用的选择有NHibernate.Driver.SqlClientDriver, NHibernate.Driver.OleDbDriver等;
41 hibernate.dialect
42 数据库方言,取值必须是继承之Dialect的类的全名,最常用的就是NHibernate.Dialect.MsSql2000Dialect/NHibernate.Dialect.MsSql2008Dialect了, 其它的没用过,不清楚能不能正常使用;
43 hibernate.connection.connection_string
44 连接字符串(如:server=127.0.0.1;database=Company;uid=sa;pwd=123;),取值与driver_class对应即可;
45 hibernate.show_sql
46 指明是否在log4net日志中显示sql语句,主要用于调试,取值为true或false;-->
完整配置文件

 

第五步:

配置映实体类 EmployeeInfo.cs

 1 using System;
 2 using System.Text;
 3 using System.Collections.Generic;
 4 namespace NH01.Domain
 5 {
 6     public class EmployeeInfo
 7     {     
 8         public virtual int EmpNo { get; set; }
 9         public virtual string EmpName { get; set; }
10         public virtual decimal Salary { get; set; }
11         public virtual string DeptName { get; set; }
12         public virtual string Designation { get; set; }
13     }
14 }

 

配置映射.hbm.xml文件(注意:生成操作设置为:嵌入的资源)

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <hibernate-mapping assembly="NH01" namespace="NH01.Domain" xmlns="urn:nhibernate-mapping-2.2">
 3   <!--<hibernate-mapping assembly="{程序集名称}" namespace="{命名空间}" xmlns="urn:nhibernate-mapping-2.2">-->
 4   <class name="EmployeeInfo" table="EmployeeInfo" lazy="true" >
 5     <cache usage="read-write"/>
 6     <!--<class name="{类名}" table="{数据库表名}" lazy="{是否延迟加载true/false}" >--> 
 7     <id name="EmpNo" column="Emp_No">
 8       <!--<id name="{类属性名字}" column="{数据为表属性名}">-->
 9       <generator class="identity" />
10       <!--<generator class="identity" />  identity:用于MySql数据库。特点:递增-->
11     </id>
12     <property name="EmpName">
13       <column name="Emp_Name" sql-type="varchar" not-null="true" />
14     </property>
15     <!--<property name="{类属性名}">
16       <column name="{数据为表属性名称}" sql-type="{类型:如:decimal、varchar...}" not-null="{是否可以为NULL:true/false}" />
17     </property>-->
18     <property name="Salary">
19       <column name="Salary" sql-type="decimal" not-null="true" />
20     </property>
21     <property name="DeptName">
22       <column name="Dept_Name" sql-type="varchar" not-null="true" />
23     </property>
24     <property name="Designation">
25       <column name="Designation" sql-type="varchar" not-null="true" />
26     </property>
27   </class>
28 </hibernate-mapping>

 

最后一步:创建工厂与调式

  1 using Newtonsoft.Json;
  2 using NH01.Domain;
  3 using NHibernate;
  4 using NHibernate.Cfg;
  5 using System;
  6 using System.Collections.Generic;
  7 using System.IO;
  8 using System.Linq;
  9 using System.Reflection;
 10 using System.Text;
 11 using System.Threading.Tasks;
 12 
 13 namespace NH01
 14 {
 15 
 16     //创建思路:工作 sessionFactory创建ISession   ISession操作数据库
 17     class Program
 18     {
 19 
 20         static  void Main(string[] args)
 21         {
 22              //测试一级缓存
 23            // TextSession();
 24             TextSecondCache();
 25        
 26         }
 27         public static void TextSession()
 28         {
 29             ISessionFactory sessionFactory = CreateISessionFactoryByXml();
 30             Console.WriteLine("第一个session开始");
 31             using (ISession session = sessionFactory.OpenSession())
 32             {
 33                 EmployeeInfo a = session.Get<EmployeeInfo>(1);
 34                 Console.WriteLine("-----session执行----");
 35                 EmployeeInfo b = session.Get<EmployeeInfo>(1);
 36                 EmployeeInfo c = session.Get<EmployeeInfo>(1);
 37                 EmployeeInfo d = session.Get<EmployeeInfo>(1);
 38                 Console.WriteLine("a " + a.EmpName);
 39                 Console.WriteLine("b " + b.EmpName);
 40                 Console.WriteLine("c " + c.EmpName);
 41                 Console.WriteLine("d " + d.EmpName);
 42             }
 43 
 44             Console.WriteLine();
 45             Console.WriteLine();
 46             Console.WriteLine("第一个session结束 第2个session开始");
 47             using (ISession session = sessionFactory.OpenSession())
 48             {
 49                 EmployeeInfo a = session.Get<EmployeeInfo>(1);
 50                 EmployeeInfo b = session.Get<EmployeeInfo>(1);
 51                 EmployeeInfo c = session.Get<EmployeeInfo>(1);
 52                 EmployeeInfo d = session.Get<EmployeeInfo>(1);
 53                 Console.WriteLine("a " + a.EmpName);
 54                 Console.WriteLine("b " + b.EmpName);
 55                 Console.WriteLine("c " + c.EmpName);
 56                 Console.WriteLine("d " + d.EmpName);
 57             }
 58 
 59         }
 60 
 61 
 62         public static void TextSecondCache()
 63         {
 64             ISessionFactory sessionFactory = CreateISessionFactoryByXml();
 65             Console.WriteLine("第一个session开始");
 66             using (ISession session = sessionFactory.OpenSession())
 67             {
 68                 EmployeeInfo a = session.Get<EmployeeInfo>(1);
 69                 Console.WriteLine("a " + a.EmpName);
 70              
 71             }
 72 
 73          
 74             Console.WriteLine("第一个session结束 第2个session开始");
 75             using (ISession session = sessionFactory.OpenSession())
 76             {
 77                 EmployeeInfo a = session.Get<EmployeeInfo>(1);
 78                 Console.WriteLine("a " + a.EmpName);
 79             }
 80 
 81         }
 82 
 83 
 84         static ISessionFactory CreateISessionFactoryByXml()
 85         {
 86             Configuration cfg = new Configuration().Configure(@"E:\NH2015\memcached\NH01\NH01\NHibernate\Configuration\hibernate.cfg.xml"); //读取xml文件
 87             //  cfg.AddDirectory(new DirectoryInfo(@"E:\NH2015\NH01\NH01\Domain\Mapping"));   //读取实体类的映射文件
 88             ISessionFactory sessionFactory = cfg.BuildSessionFactory();   //创建工厂
 89             return sessionFactory;
 90         }
 91 
 92 
 93         //测试同一个session
 94         /// <summary>
 95         /// 查询了二次数据库,因为using之后 session也会被清除,同时session管理的缓存也会清除,所以当第二次执行Get的时候没有缓存。因些再一次查询SQL
 96         /// </summary>
 97         /// <param name="sessionFactory"></param>
 98         static void DifferentSession(ISessionFactory sessionFactory)
 99         {
100             using (ISession session = sessionFactory.OpenSession())
101             {
102                 EmployeeInfo get = session.Get<EmployeeInfo>(1);
103                 get = session.Get<EmployeeInfo>(1);
104                 Console.WriteLine("读取名字" + get.EmpName);
105 
106 
107             }
108             using (ISession session = sessionFactory.OpenSession())
109             {
110                 EmployeeInfo get = session.Get<EmployeeInfo>(1);
111                 Console.WriteLine("读取名字" + get.EmpName);
112 
113             }
114         }
115 
116 
117         public static void Save(ISessionFactory sessionFactory)
118         {
119             ISession session = null;
120             ITransaction mTransaction = null;
121             if (session == null)
122             {
123                 session = sessionFactory.OpenSession();      //创建session会话
124             }
125             try
126             {
127                 EmployeeInfo info = new EmployeeInfo() { DeptName = "wiaaaase", EmpNo = 1, Designation = "jock", EmpName = "bia", Salary = 45 };
128                 mTransaction = session.BeginTransaction();       //打事事务
129 
130 
131                 EmployeeInfo employeeInfo2 = session.Get<EmployeeInfo>(1);
132                 EmployeeInfo employeeInfod = session.Get<EmployeeInfo>(1);
133                 EmployeeInfo a = session.Get<EmployeeInfo>(1);
134                 EmployeeInfo b = session.Get<EmployeeInfo>(1);
135                 EmployeeInfo c = session.Get<EmployeeInfo>(1);
136                 EmployeeInfo d = session.Get<EmployeeInfo>(1);
137 
138 
139 
140 
141                 Console.WriteLine(JsonConvert.SerializeObject(employeeInfo2));
142                 Console.WriteLine(JsonConvert.SerializeObject(employeeInfod));
143                 Console.WriteLine(JsonConvert.SerializeObject(a));
144                 Console.WriteLine(JsonConvert.SerializeObject(b));
145                 Console.WriteLine(JsonConvert.SerializeObject(c));
146                 Console.WriteLine(JsonConvert.SerializeObject(d));
147 
148                 session.Transaction.Commit(); //提交
149             }
150             catch (Exception ex)
151             {
152                 mTransaction.Rollback(); //事务回滚
153             }
154             finally
155             {
156                 if (session.IsOpen)  //判断会话是否打开
157                 {
158                     session.Close();    //关闭会话
159                 }
160             }
161 
162 
163 
164         }
165 
166 
167         /// <summary>
168         /// 第二步种实现方式:通过直接设置参数创建工厂
169         /// </summary>
170         /// <returns></returns>
171         static ISessionFactory CreateISessionFactory()
172         {
173             Configuration cfg = new Configuration();
174             cfg.SetProperty("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
175             cfg.SetProperty("dialect", "NHibernate.Dialect.MsSql2008Dialect");
176             cfg.SetProperty("show_sql", "true");//显示SQL语句
177             cfg.SetProperty("connection.driver_class", "NHibernate.Driver.SqlClientDriver");
178             cfg.SetProperty("connection.connection_string", "server=127.0.0.1;database=Company;uid=sa;pwd=123;");
179             cfg.AddAssembly(Assembly.GetCallingAssembly());   //加载言所属程序集的以XXX.hbm.xml格式的映射文件(关键:生成操作设置为:嵌入的资源)
180             // cfg.AddAssembly("Common");    public Configuration AddAssembly(string assemblyName); 程序集名称
181             ISessionFactory sessionFactory = cfg.BuildSessionFactory();
182             return sessionFactory;
183         }
184 
185         /// <summary>
186         /// 第-种 :通进读取外部文件创建工厂
187         /// </summary>
188         /// <returns></returns>
189 
190 
191         //测试同一个session
192         /// <summary>
193         /// 原理:查询:查询流程:查询session 管理的 一级缓存,因为当get的时候,会把第一个对象取出来同时保存一分在session管理的一级缓存中,当第二次 get2的时候,会在判断是否有一级缓存,如果有则直接取缓存使用,如果没有,则向数据库获取
194         /// </summary>
195         /// <param name="sessionFactory"></param>
196         static void TheSameSession(ISessionFactory sessionFactory)
197         {
198 
199             ISession session = sessionFactory.OpenSession();
200             EmployeeInfo get = session.Get<EmployeeInfo>(1);
201             EmployeeInfo get2 = session.Get<EmployeeInfo>(1);
202             EmployeeInfo get3 = session.Get<EmployeeInfo>(1);
203             Console.WriteLine("读取名字" + get.EmpName);
204             Console.WriteLine("读取名字" + get2.EmpName);
205             Console.WriteLine("读取名字" + get3.EmpName);
206 
207 
208         }
209 
210 
211 
212 
213 
214 
215 
216     }
217 }
创建工厂与调试

 

表生成

USE [Company]
GO

/****** Object:  Table [dbo].[EmployeeInfo]    Script Date: 01/11/2016 16:50:20 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[EmployeeInfo](
    [Emp_No] [int] IDENTITY(1,1) NOT NULL,
    [Emp_Name] [varchar](50) NOT NULL,
    [Salary] [decimal](18, 0) NOT NULL,
    [Dept_Name] [varchar](50) NOT NULL,
    [Designation] [varchar](50) NOT NULL,
 CONSTRAINT [PK_EmployeeInfo] PRIMARY KEY CLUSTERED 
(
    [Emp_No] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO
表生成SQL

 

posted on 2016-01-11 16:51  高达  阅读(450)  评论(0)    收藏  举报

导航