【问题标题】:NHibernate - How to log Named Parameterised Query with parameter values?NHibernate - 如何使用参数值记录命名参数化查询?
【发布时间】:2019-06-08 11:28:47
【问题描述】:

我有一个这样的参数化命名查询:

Query moveOutQuery = session.createSQLQuery(moveOutQueryStr.toString())
                .addEntity(MyClass.class)
                .setParameter("assignmentStatus", Constants.CHECKED_OUT)

我想查看填充参数的实际 SQL 查询。但是在调试时我只得到以下查询:

Select * from my_assignment WHERE assignment_status in ( :assignmentStatus )

为什么assignmentStatus 没有被替换为它的真正价值?

【问题讨论】:

    标签: nhibernate named-query parameterized-query


    【解决方案1】:

    为什么没有用 assignmentStatus 代替它的实际值?

    这是因为 NHibernate 使用查询参数来输入值。这在 许多 情况下是有效的,也有助于抵御 SQL 注入攻击。参数单独发送。如果按照下面的说明记录了 SQL,您可以在底部找到它们。


    您可以将每个 SQL 记录到文件中,如下所述。

    这是通过log4net.dll实现的;您需要添加参考。

    如下添加命名空间:

    using log4net;
    using log4net.Appender;
    using log4net.Core;
    using log4net.Layout;
    using log4net.Repository.Hierarchy;
    

    在NHibernate中配置log4net如下:

    Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
    hierarchy.Root.RemoveAllAppenders();
    
    FileAppender fileAppender = new FileAppender();
    fileAppender.Name = "NHFileAppender";
    fileAppender.File = logFilePath;
    fileAppender.AppendToFile = true;
    fileAppender.LockingModel = new FileAppender.MinimalLock();
    fileAppender.Layout = new PatternLayout("%d{yyyy-MM-dd HH:mm:ss}:%m%n%n");
    fileAppender.ActivateOptions();
    
    Logger logger = hierarchy.GetLogger("NHibernate.SQL") as Logger;
    logger.Additivity = false;
    logger.Level = Level.Debug;
    logger.AddAppender(fileAppender);
    
    hierarchy.Configured = true;
    

    配置时还需要设置ShowSql

    configuration.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true");
    configuration.SetProperty(NHibernate.Cfg.Environment.FormatSql, "true");
    

    您需要在应用程序启动时调用此代码一次。输出日志也包括参数值。

    以下是代码:

    session.CreateSQLQuery("SELECT * FROM MyEntity WHERE MyProperty = :MyProperty")
                .AddEntity(typeof(MyEntity))
                .SetParameter("MyProperty", "filterValue")
                .UniqueResult<MyEntity>();
    

    以下是记录的查询:

    2020-01-09 14:25:39:
        SELECT
            * 
        FROM
            MyEntity 
        WHERE
            MyProperty = @p0;
        @p0 = 'filterValue' [Type: String (4000:0:0)]
    

    如你所见,参数值filterValue列在底部。

    这适用于所有查询 API,例如 IQueryOverIQueryISQLQuery 等。

    这会记录成功和失败的语句。您可以使用FileAppenderLogger 类来满足您的额外要求。

    另请参阅 PatternLayoutdocumentation。更多细节也可以在hereherehere找到。 This Q/A 讨论了同样的问题。

    以下问答也可能有所帮助:

    如您所见,这会在查询底部记录参数值。如果您希望将这些记录嵌入到查询中,请参阅this 文章。

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多