NHibernate - 如何使用参数值记录命名参数化查询?

标签 nhibernate named-query parameterized-query

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

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没有被替换为它的实际值?

最佳答案

Why isn't the assignmentStatus being substituted for its real value?

这是因为 NHibernate 使用查询参数来输入值。这在许多情况下都很有效,并且也有助于抵御 SQL 注入(inject)攻击。参数单独发送。如果按如下所述记录 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类以满足您的额外要求。

另请参阅PatternLayout来自documentation 。更多详情还可查看here , herehereThis Q/A 讨论了相同的内容。

以下问答也可能有帮助:

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

关于NHibernate - 如何使用参数值记录命名参数化查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54182141/

相关文章:

sql - JPQL IN 子句 : Java-Arrays (or Lists, 设置...)?

java - 将查询转换为 java jdbc 模板中的参数化准备语句

python - :TypeError: %d format: a number is required, 不是 str:在 python pandas 中给出了偶数

c# - NHibernate 使用子查询计算另一个实体?

c# - CreateSQLQuery 可以工作,但 QueryOver 不能与 NHibernate 一起使用

NHibernate 将地理类型传递给命名查询 SetParameter()

c# - 在大型 asp.net C# web 应用程序中修复 SQL 注入(inject)表单

c# - Nhibernate DetachedCriteria Left Outer Join 子查询

NHibernate 3.0 使用子字符串搜索

java - 通过 Hibernate 聚合将实体映射到 pojo