在使用Hibernate时,获得的query有setCacheable方法,可以设置使用缓存,但当使用JPA时,javaxpersistenceQuery并没有setCacheable方法,此时如果JPA的实现是Hibernate时,可以将其进行如下转化,再调用setCacheable方法
if (query instanceof orghibernateejbQueryImpl) {
((orghibernateejbQueryImpl) query)getHibernateQuery()setCacheable(true);
}
其实,这一种说法是不完全正确的。首先第一点,mysql的query_cache的键值并不是简单的query,而是query加databasename加flag。这个从源码中就可以看出。在这里不做重点描述,后续可以针对于这一点再具体分析。重要的是第二点,是不是加了空格,mysql就认为是不同的查询呢?实际上这个是要分情况而言的,要看这个空格加在哪。 如果空格是加在query之前,比如是在query的起始处加了空格,这样是丝毫不影响query cache的结果的,mysql认为这是一条query, 而如果空格是在query中,那会影响query cache的结果,mysql会认为是不同的query。 下面我们通过实验及源码具体分析。首先,我们先试验一下: 首先,我们看一下mysql query_cache的状态: 首先,我们可以确认,mysql的query_cache功能是打开的。 其次,我们看一下状态: 因为这个db是新的db,所以hits,inset都为0,现在我们执行一条select语句: 状态变为: 可以看到,执行一条select后,现在的qcache状态为,insert+1,这样我们就可以推断出,现在刚才那条select语句已经加入了qcache中。那我们现在再将刚才那条sql前面加上空格,看看会怎样呢? 请注意,这条sql,比刚才那条sql前面多了一个空格。 按照网上的理论,这条sql应该会作为另一个键而插入另一个cache,不会复用先前的cache,但结果呢? 我们可以看到,hits变为了1,而inserts根本没变,这就说明了,这条在前面加了空格的query命中了没有空格的query的结果集。从这,我们就可以得出结论,网上先前流传的说法,是不严谨的。 那究竟是怎么回事呢?到底应该如何呢?为什么前面有空格的会命中了没有空格的query的结果集。其实,这些我们可以通过源码获得答案。 翻看下mysql的源码,我这翻看的是5_buffer_length); thd->convert_buffer_buffer_length); return FALSE; } 这个方法在一开始就会对query进行处理(代码第4行),将开头和末尾的garbage remove掉。 看到这里,我们基本已经明了了,mysql会对输入的query进行预处理,将空格等东西给处理掉,所以不会开头的空格不会影响到query_cache,因为对mysql来说,就是一条query。
以上就是关于query.setCacheable(true); 具体是什么意思啊全部的内容,包括:query.setCacheable(true); 具体是什么意思啊、linux系统下怎么解决packet for query is too large you c、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)