ibatis mysql 性能_Web应用中优化IBatis性能

在我的一个项目中应用了IBatis.Net这个工具作为数据访问层,因为项目规模不大,尽量根据实际应用情况作业一些简化。比如,我们将IBastis.Net作为DAO层,而如果是面向不同的数据库,则直接每个数据库编写特定的映射文件;中间层并未采用IoC机制,采用最直接的new来实例化业务逻辑对象。

IBatis.Net的使用,采用一个非常常见的封装格式:internal class MyMapper

{

private static volatile SqlMapper _Mapper;

///

/// static Configure constructor that can be

/// used for callback

///

///

protected static void Configure(object obj)

{

_Mapper = null;

}

///

/// Init the 'default' SqlMapper defined by the SqlMap.Config file.

///

protected static void InitMapper()

{

DomSqlMapBuilder builder = new DomSqlMapBuilder();

XmlDocument sqlMapConfig = Resources.GetEmbeddedResourceAsXmlDocument("gsh.Endow.SqlMap.config");

_Mapper = (SqlMapper) builder.Configure(sqlMapConfig);

_Mapper.SessionStore =new IBatisNet.DataMapper.SessionStore.HybridWebThreadSessionStore(_Mapper.Id);

string DBConnectstring = ConfigurationManager.ConnectionStrings[ConfigClass.Instance().ConnectionString].ConnectionString;

_Mapper.DataSource.ConnectionString = DBConnectstring;

}

///

/// Get the instance of the SqlMapper defined by the SqlMap.Config file.

///

/// A SqlMapper initalized via the SqlMap.Config file.

public static SqlMapper Instance()

{

if (_Mapper == null)

{

lock (typeof (SqlMapper))

{

if (_Mapper == null) // double-check

{

InitMapper();

}

}

}

return _Mapper;

}

///

/// Get the instance of the SqlMapper defined by the SqlMap.Config file. (Convenience form of Instance method.)

///

/// A SqlMapper initalized via the SqlMap.Config file.

public static SqlMapper Get()

{

return Instance();

}

}

未完成一个业务逻辑也许会多次调用MyMapper的实例方法,而在默认情况下,IBatis.Net会为每次调用单独维护一个数据库的连接。也就是调用方法时,首先打开连接,然后执行Sql语句,最后关闭连接。是一个典型的短连接的场景。///

/// Executes a Sql SELECT statement that returns that returns data

/// to populate a single object instance.

///

/// The parameter object is generally used to supply the input

/// data for the WHERE clause parameter(s) of the SELECT statement.

///

/// The name of the sql statement to execute.

/// The object used to set the parameters in the SQL.

/// The single result object populated with the result set data.

public T QueryForObject(string statementName, object parameterObject)

{

bool isSessionLocal = false;

ISqlMapSession session = _sessionStore.LocalSession;

T result;

if (session == null)

{

session = CreateSqlMapSession();

isSessionLocal = true;

}

try

{

IMappedStatement statement = GetMappedStatement(statementName);

result = statement.ExecuteQueryForObject(session, parameterObject);

}

catch

{

throw;

}

finally

{

if (isSessionLocal)

{

session.CloseConnection();

}

}

return result;

}

然而在访问量交大的时候,这种持续不断地连接、断开、再连接、再断开的场景对应用本身和数据库的性能都有一定的影响。因此我们能否在一个Http请求过程中只打开一个数据库连接呢?答案是肯定的,做起来也相当简单,我们可以做一个HttpModule,在BeginRequest中打开一个连接在EndRequest中关闭连接即可:public class MyMapperModule : IHttpModule

{

///

/// 您将需要在您网站的 web.config 文件中配置此模块,

/// 并向 IIS 注册此模块,然后才能使用。有关详细信息,

/// 请参见下面的链接: http://go.microsoft.com/?linkid=8101007

///

#region IHttpModule Members

public void Dispose()

{

//此处放置清除代码。

}

public void Init(HttpApplication context)

{

// 下面是如何处理 LogRequest 事件并为其

// 提供自定义日志记录实现的示例

//context.LogRequest += new EventHandler(OnLogRequest);

context.BeginRequest += new EventHandler(context_BeginRequest);

context.EndRequest += new EventHandler(context_EndRequest);

}

void context_EndRequest(object sender, EventArgs e)

{

if(MyMapper.Instance().LocalSession!=null)

MyMapper.Instance().CloseConnection();

}

void context_BeginRequest(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

HttpContext context = application.Context;

string filePath = context.Request.FilePath;

string fileExtension =

VirtualPathUtility.GetExtension(filePath);

if(fileExtension==".aspx" || fileExtension==".ascx" || fileExtension==".asxd" || fileExtension==".ashx")

MyMapper.Instance().OpenConnection();

}

#endregion

public void OnLogRequest(Object source, EventArgs e)

{

//可以在此放置自定义日志记录逻辑

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
09-Jun-2023 15:19:12.806 信息 [main] org.apache.catalina.core.StandardServer.await 通过关闭端口接收到有效的关闭命令。正在停止服务器实例。 09-Jun-2023 15:19:12.807 信息 [main] org.apache.coyote.AbstractProtocol.pause 暂停ProtocolHandler["http-nio-8080"] 09-Jun-2023 15:19:13.217 信息 [main] org.apache.catalina.core.StandardService.stopInternal 正在停止服务[Catalina] 09-Jun-2023 15:19:13.230 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web应用程序 [ROOT] 注册了JDBC驱动程序 [com.mysql.cj.jdbc.Driver],但在Web应用程序停止时无法注销它。 为防止内存泄漏,JDBC驱动程序已被强制取消注册。 09-Jun-2023 15:19:13.230 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web应用程序 [ROOT] 注册了JDBC驱动程序 [org.apache.ibatis.datasource.unpooled.UnpooledDataSource.DriverProxy],但在Web应用程序停止时无法注销它。 为防止内存泄漏,JDBC驱动程序已被强制取消注册。 09-Jun-2023 15:19:13.230 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[ROOT]似乎启动了一个名为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[ java.lang.Object.wait(Native Method) java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:91) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) java.lang.Thread.run(Thread.java:750)] 09-Jun-2023 15:19:13.241 信息 [main] org.apache.coyote.AbstractProtocol.stop 正在停止ProtocolHandler ["http-nio-8080"] 09-Jun-2023 15:19:13.252 信息 [main] org.apache.coyote.AbstractProtocol.destroy 正在摧毁协议处理器 ["http-nio-8080"] 是什么原因
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值