实现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
浙公网安备 33010602011771号