2

在我现有的项目中,我有 aprox。数据库中有 70 多个表,我使用 Hibernate 作为数据访问层,所以每个查询都是通过使用标准 API/HQL/命名查询来完成的。现在我们在 40 多个表(事务表)中添加一列,称为isDeletedwhich is trueor false

现在在我当前的项目中,我必须通过在该表上添加额外的Restrictions\来获取记录,这需要更多时间。Where Clause

有什么方法可以拦截每个数据库查询(标准 API/HQL/命名查询),以便我可以添加where clause相应的模型/表。

Hibernate Session----->HQL/Named(native) Query---->Interceptor----->将添加where clauseREQUIRED TABLES---->将其进一步发送到 DB

4

1 回答 1

1

是的,您可以将动态过滤器与拦截器结合使用。

http://nhforge.org/wikis/howtonh/contextual-data-using-nhibernate-filters.aspx

对于所有具有这种 isDeleted 属性的实体,我会让它们实现定义该属性的某个接口。例如:

interface ISoftDeletable
{
   bool IsDeleted { get; }
}

class SomeEntity : ISoftDeletable {}

(请注意,我使用 C# 来解释我的观点,但我想它在 java 中会非常相似)

然后,您可以在创建 Hibernate 配置时定义过滤器定义:

var softDeleteFilterParametersType = new Dictionary<string, NHibernate.Type.IType> (1);
softDeleteFilterParametersType.Add ("p_isDeleted", NHibernateUtil.Bool);

cfg.AddFilterDefinition (new FilterDefinition("SoftDeleteFilter", ":p_isDeleted = isDeleted", softDeleteFilterParametersType, false);

然后,您应该将过滤器添加到实现 ISoftDeletable 接口的每个映射类:

foreach( var m in cfg.ClassMappings )
{
    if( typeof(ISoftDeletable).IsAssignableFrom (m.MappedClass) )
    {
        Property delColumn = m.GetProperty ("IsDeleted");

        m.AddFilter ("SoftDeleteFilter", ":p_isDeleted = " + delColumn.ColumnIterator.First().Name);
    }
}

然后,您仍然需要创建一个拦截器,将参数的值设置为 true 或 false,具体取决于您要执行的操作。

也许你甚至可以在你的过滤子句中硬编码参数的值(如果你总是想检索未删除的项目),我猜这会使上面的代码更简单。

于 2013-04-30T13:51:57.393 回答