‘壹’ Redis作为Hibernate的二级缓存问题,怎么解决
<!-- entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa."
depends-on="cacheManagerFactory">
...
<property name="jpaProperties">
<props>
...
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<!-- <prop key="hibernate.cache.use_query_cache">true</prop> -->
<prop key="hibernate.cache.region.factory_class">xxx.xxx.framework.cache.hibernate.CacheRegionFactory</prop>
...
</props>
</property>
</bean>
<!
‘贰’ mybatis二级缓存redis,update数据库表的时候,为什么会清空redis数据库
redis做缓存的时候需要自己写缓存逻辑, 把缓存逻辑贴出来看看
‘叁’ redis怎么设置作为hibernate的二级缓存吗
redis是一个key-value存储系统和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。
与memcached一样,为了保证效率,数据都是缓存在内存中。
区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
‘肆’ 到底如何在spring中使用redis
1. Redis使用场景
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
我们都知道,在日常的应用中,数据库瓶颈是最容易出现的。数据量太大和频繁的查询,由于磁盘IO性能的局限性,导致项目的性能越来越低。
这时候,基于内存的缓存框架,就能解决我们很多问题。例如Memcache,Redis等。将一些频繁使用的数据放入缓存读取,大大降低了数据库的负担。提升了系统的性能。
其实,对于hibernate的二级缓存,是同样的道理。利用内存高速的读写速度,来解决硬盘的瓶颈。
2. 配置使用redis
首先,我们需要引入基本的jar包。maven中的基本引用如下:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.2</version>
</dependency>
然后,在applicationContext中配置如下:
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxTotal" value="${redis.maxActive}" />
<property name="maxWaitMillis" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
p:pool-config-ref="poolConfig" />
<bean id="stringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<!-- 开启事务,可以通过transcational注解控制 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="keySerializer" ref="stringSerializer" />
<property name="enableTransactionSupport" value="true" />
</bean>
对于hibernate的配置可知,第一个poolconfig是对连接池的配置。包括最大连接数,队列数,存活时间,最大等待时间等等,还有一些额外的配置,请直接点击JedisPoolConfig类源码,进行查看。
这些配置的意思如果不明白的话,一定要去把线程池好好学习下。
第一个配置是连接工厂,顾名思义,最基本的使用一定是对连接的打开和关闭。我们需要为其配置redis服务器的账户密码,端口号。(这里还可以配置数据库的index,但是我使用时候一直使用redis的默认数据库,也就是第0个)
最后一个配置特别重要。这个类似于spring提供的HibernateDaoSupport。
接下来,全部讲解都将围绕这个类展开。
3. RedisTemplate的使用
这个类作为一个模版类,提供了很多快速使用redis的api,而不需要自己来维护连接,事务。
最初的时候,我创建的BaseRedisDao是继承自这个类的。继承的好处是我的每个Dao中,都可以自由的控制序列化器,自由的控制自己是否需要事务,这个先不需要了解,跟着我目前的这种配置方法来即可。
template提供了一系列的operation,比如valueOperation,HashOperation,ListOperation,SetOperation等,用来操作不同数据类型的Redis。
并且,RedisTemplate还提供了对应的*OperationsEditor,用来通过RedisTemplate直接注入对应的Operation。我们暂时不讲这个。
对于下面的test1方法,我们暂时不用考虑,先了解通过RedisTemplate来使用connection操作Redis。
Test代码如下:
package cn.test.spjedis;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework..DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.cn.redis2..IncrDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class TestRedis {
@Resource(name = "redisTemplate")
private RedisTemplate<String, String> template; // inject the template as ListOperations
//至于这个为什么可以注入。需要参考AbstractBeanFactory doGetBean
//super.setValue(((RedisOperations) value).opsForValue());就这一行代码 依靠一个editor
@Resource(name = "redisTemplate")
private ValueOperations<String, Object> vOps;
public void testSet(){
template.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
byte [] key = "tempkey".getBytes();
byte[] value = "tempvalue".getBytes();
connection.set(key, value);
return true;
}
});
}
public void testSet1(){
vOps.set("tempkey", "tempvalue");
}
@Autowired
private IncrDao incr;
@Test
public void addLink() {
System.out.println(incr.incr(13));
System.out.println(incr.get(13));
}
}
这个是对String类型插入的两个测试。test方法中,使用了模版类提交回调(RedisCallBack)的方法来使用jedis connection操作数据。这一部分,有没有似曾相识呢?
HibernateTemplate的HibernateCallback,以及Hibernate Session类中的doWork以及doReturningWork方法,都是使用了这样的机制,方便对于连接或者session的统一管理。
public int excuteHqlUpdate(final String hql,final Object ...params){
return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
@Override
@SuppressWarnings("unchecked")
public Integer doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(hql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
queryObject.setParameter(i, params[i]);
}
}
return queryObject.executeUpdate();
}
});
}
‘伍’ redis mybatis 二级缓存 为什么必须要有 <property name="connectionfactory" ref
1、mybatis的二级缓存的范围是命名空间(namespace)
2、只要这个命名空间下有一个 insert、update、delete mybatis 就会把这个命名空间下的二级缓清空。
3、如果同一个sql在不同的命名空间下,就会出现脏数据,因为一个insert、update、deleted 了另一个可能还使用者缓存数据,这样就会出现数据的不一致性。
4、如果更新、删除、插入的频率比较高的话,就会删除所有缓存在添加所有缓存在删除,这样缓存的命中率很低或者说根本就起不到缓存作用而且会消耗资源。
所以在没解决这个问题的前提下,还是不提倡使用二级缓存。
‘陆’ mybatis自带一级和二级缓存,为什么还要用redis
二级缓存是namespace区域内的,所以不同的namespace下操作同一张表,会导致数据不一致,个人从未使用过二级缓存,redis更灵活,功能更丰富
‘柒’ redis怎么设置作为hibernate的二级缓存
hibernate框架中就带着一个很好用的缓存,想不通你是为使用缓存而用缓存还是未了使用redis而用缓存?
真想用,实现一下二级缓存需要的接口,对接到redis上,再配置到缓存中即可。
‘捌’ 如何用redis做hibernate4的二级缓存,求实践过的人解答
在向大家详细介绍Hibernate二级缓存之前,首先让大家了解下一级缓存,然后全面介绍Hibernate二级缓存。 Hibernate中提供了两级Cache,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。
‘玖’ redis作为mybatis的二级缓存,此时二级缓存可以作为高并发缓存吗
1)对该表的操作与查询都在同一个namespace下,其他的namespace如果有操作,就会发生数据过时。 2)对关联表的查询,关联的所有表的操作都必须在同一个namespace。 总之,操作与查询在同一个namespace下的查询才能缓存,其他namespace下的查询都