Java 需要hibernate二级缓存的清晰性

Java 需要hibernate二级缓存的清晰性,java,hibernate,caching,memcached,Java,Hibernate,Caching,Memcached,我需要一些关于Hibernate二级缓存的说明 hibernate二级缓存是如何工作的 它是否从JavaEE环境中服务器启动时的实体类中有@Cacheable注释(关于hibernate注释)的表中加载所有数据 当这些表上有更新时,缓存是否会同步?如何同步 最后一个问题是,当我感兴趣的某个表上有更新时,有什么方法可以通知我的DAO代码?(寻找任何可以更新表的侦听器) 这是一个太宽泛的问题,在这里无法回答 否。它会惰性地填充缓存。每次使用hibernate API或查询从数据库获取可缓存的实体时,

我需要一些关于Hibernate二级缓存的说明

  • hibernate二级缓存是如何工作的

  • 它是否从JavaEE环境中服务器启动时的实体类中有@Cacheable注释(关于hibernate注释)的表中加载所有数据

  • 当这些表上有更新时,缓存是否会同步?如何同步

  • 最后一个问题是,当我感兴趣的某个表上有更新时,有什么方法可以通知我的DAO代码?(寻找任何可以更新表的侦听器)

  • 这是一个太宽泛的问题,在这里无法回答

  • 否。它会惰性地填充缓存。每次使用hibernate API或查询从数据库获取可缓存的实体时,该实体都存储在缓存中。稍后,当使用缓存中实体的ID调用
    session.get()
    时,不需要数据库查询

  • 如果通过Hibernate进行更新,则会更新缓存。如果是使用外部应用程序、SQL查询、甚至是批量更新HQL查询完成的,则缓存不知道更新。这就是为什么您需要注意哪些实体是可计算的,哪些时间是您选择的,等等。有时候,返回过时的值没有问题,有时候是不可接受的

  • 没有

  • hibernate二级缓存是如何工作的

    当实体标记为可缓存时,如果已配置二级缓存,则hibernate将在第一次读取后将实体缓存到二级缓存

    Hibernate提供了插入遵循Hibernate规范的任何缓存实现的灵活性。有关二级缓存和配置选项的更多详细信息,请参阅

  • 它是否从JavaEE环境中服务器启动时的实体类中有@Cacheable注释(关于hibernate注释)的表中加载所有数据

    我不认为有任何配置可以实现这一点。您可以通过在启动时读取整个表间接地实现这一点,这可能会对系统启动时间产生不利影响。(我不喜欢这个)。如果实体在外部被修改,那么hibernate无法同步它,最终会得到过时的数据

  • 当这些表上有更新时,缓存是否会同步?如何同步

    缓存不会在表更新后立即更新。获取更新记录的后续调用将进入数据库,hibernate通过使用会话时间戳在内部实现这一点

  • 最后一个问题是,当我感兴趣的某个表上有更新时,有什么方法可以通知我的DAO代码?(寻找任何可以更新表的侦听器)

    不,hibernate不支持这个


  • 谢谢你的详细回答。所以应该有明确的时间从表中读取更新的数据,并在内部hibernate intern更新缓存?我在应用程序中使用二级缓存,在cfg.xml文件中使用“Show_SQL=true”,每当我多次调用同一方法时,它都会打印查询。这是否意味着它只是在控制台上打印查询,但从缓存中获取数据?是否有任何方法来验证或检查从何处获取数据(无论是从db还是缓存)?如果它显示SQL,则它正在执行它。如果您正在执行查询,而不仅仅是调用
    Session.get()
    或导航一个toOne关联,那么它将始终执行SQL查询,除非查询本身是可缓存的并且查询缓存已启用。我在应用程序中没有启用查询缓存,我主要使用的是hql查询。每次我调用同一个方法时,它都会执行查询——这意味着每次它访问数据库以获取数据r8t?但是当我打印每次迭代所花费的时间时,它会不断减少。这就是为什么我对数据是从DB还是缓存中提取感到困惑的原因是,每次数据都会进入数据库。但是数据库速度很快,因为它们还具有缓存、优化等功能。这就是为什么您会看到时间缩短的原因。如果您将“hibernate.show_sql”设置为“true”,您将始终看到打印的查询。为了验证数据是否来自缓存/数据库,您可能需要通过JMX依赖缓存统计信息。1.在cahce中启用统计信息,请参阅。2.在平台MBean服务器中注册CacheStatistics,请参阅。感谢您的回答。只有当我在第二次尝试从缓存而不是数据库获取数据时,才按ID进行查询?我在应用程序中使用二级缓存,在cfg.xml文件中使用“Show_SQL=true”,每当我多次调用同一方法时,它都会打印查询。这是否意味着它只是在控制台上打印查询,但从缓存中获取数据?是否有任何方法可以验证或检查从何处获取数据(无论是从db还是缓存)?是的,只有通过ID(使用
    session.get()
    或通过toOne关联导航)访问实体时,才会使用缓存