Mybatis使用Redis做二级缓存

由于redis是非关系型数据库,数据是储存到内存中的,而从内存中读取数据要比从硬盘中读取数据的速度要快很多,并且redis可以持久性化数据,所以可以用redis做数据的缓存。

首先导入jar包:Spring-data-redis.jar

配置文件:

redis.host=192.168.81.128
redis.port=6379
redis.pass=redis
redis.maxIdle=300
redis.timeout=5000
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true

配置Spring.xml:

    
    <bean id="config" 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">
        <property name="hostName" value="${redis.host}"/>
        <property name="port" value="${redis.port}"/>
        <property name="password" value="${redis.pass}"/>
        <property name="timeout" value="${redis.timeout}"/>
        <property name="poolConfig" ref="config"/>
      bean>

    

     <bean id="redisUtil" class="com.chinaedu.back.util.RedisUtil">
        <property name="jedisConnectionFactory" ref="connectionFactory"/>
     bean>

     <bean id="redisCacheTransfer" class="com.chinaedu.back.util.RedisCacheTransfer">
        <property name="connectionFactory" ref="connectionFactory"/>
     bean>

配置完之后你可以测试一下是否能够连接上redis:
测试代码:

    @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring.xml")
public class TestRedis {

    @Autowired
    private JedisConnectionFactory connectionFactory;

    @Test
    public void testSetValue(){
        RedisConnection connection = connectionFactory.getConnection();
        Jedis jedis= connectionFactory.getShardInfo().createResource();
        jedis.set("name","小明");
    }
    @Test
    public void testGetValue(){
        RedisConnection connection = connectionFactory.getConnection();
        Jedis jedis= connectionFactory.getShardInfo().createResource();
        String name = jedis.get("name");
        System.out.println(name);
    }
}

如果测试成功则进行下面的步骤:
mybatis.xml:

  

<configuration>
    
    <settings>

        
        <setting name="cacheEnabled" value="true"/>

        
        <setting name="lazyLoadingEnabled" value="false"/>

        
        <setting name="multipleResultSetsEnabled" value="true"/>

        
        <setting name="useColumnLabel" value="true"/>

        
        <setting name="useGeneratedKeys" value="false"/>

        
        <setting name="autoMappingBehavior" value="PARTIAL"/>

        
        

        
        

        
        <setting name="safeRowBoundsEnabled" value="false"/>

        
        <setting name="mapUnderscoreToCamelCase" value="true"/>

        
        <setting name="localCacheScope" value="SESSION"/>

        
        <setting name="jdbcTypeForNull" value="OTHER"/>

        
        <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>

        
        <setting name="aggressiveLazyLoading" value="true"/>

    settings>

configuration>

mapper.xml:



<mapper namespace="com.chinaedu.back.dao.UserDao">

//自定义的cache
<cache  type="com.chinaedu.back.cache.RedisCache" />

    

    <sql id="usersql">
        select f_user_id userId, f_real_name realName,f_role_id
        roleId,f_name name,f_pwd pwd,f_eamil email,f_phone phone,f_state state
        from t_user
    sql>

    <select id="queryByCase" resultType="User">
        <include refid="usersql">include>
        <where>
            <if test="userId != null">
                f_user_id = #{userId}
            if>
            <if test="name != null">
                and f_name = #{name}
            if>
        where>
    select>
mapper>   

实现cache接口:

package com.chinaedu.back.cache;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

import redis.clients.jedis.exceptions.JedisConnectionException;

/**
 * 自定义cache
 * 
 * @author Administrator
 *
 */
public class RedisCache implements Cache {

    private static JedisConnectionFactory connectionFactory;

    private final String id;

    /**
     * The {@code ReadWriteLock}.
     */
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public RedisCache(final String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.id = id;
    }

    @Override
    public String getId() {
        // TODO Auto-generated method stub
        return this.id;
    }

    @Override
    public void putObject(Object key, Object value) {
        // TODO Auto-generated method stub
        RedisConnection connection = null;
        try {
            connection = connectionFactory.getConnection();
            RedisSerializer redisSerializer = new JdkSerializationRedisSerializer(); // 借用spring_data_redis.jar中的JdkSerializationRedisSerializer.class
            connection.set(redisSerializer.serialize(key),
                    redisSerializer.serialize(value));// 利用其序列化方法将数据写入redis服务的缓存中
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    @Override
    public Object getObject(Object key) {
        // TODO Auto-generated method stub
        Object result = null;
        RedisConnection connection = null;
        try {
            connection = connectionFactory.getConnection();
            RedisSerializer serializer = new JdkSerializationRedisSerializer();
            result = serializer.deserialize(connection.get(serializer
                    .serialize(key)));  //利用其反序列化方法获取值
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }

    @Override
    public Object removeObject(Object key) {
        // TODO Auto-generated method stub
        RedisConnection connection = null;
        System.out.println("key:" + key);
        Object result = null;
        try {
            connection = connectionFactory.getConnection();
            RedisSerializer redisSerializer = new JdkSerializationRedisSerializer(); // 借用spring_data_redis.jar中的JdkSerializationRedisSerializer.class
            result = connection.expire(redisSerializer.serialize(key), 0);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }

    @Override
    public void clear() {
        // TODO Auto-generated method stub
        RedisConnection connection = null;
        try {
            connection = connectionFactory.getConnection();
            connection.flushDb();
            connection.flushAll();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    @Override
    public int getSize() {
        // TODO Auto-generated method stub
        RedisConnection connection = null;
        int size = 0;
        try {
            connection = connectionFactory.getConnection();
            size = Integer.parseInt(connection.dbSize().toString());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }

        return size;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        // TODO Auto-generated method stub
        return this.readWriteLock;
    }

    public static void setConnectionFactory(
            JedisConnectionFactory jedisConnectionFactory) {
        RedisCache.connectionFactory = jedisConnectionFactory;
    }

}

接下来就是测试了:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring.xml")
public class TestRedisCache {

    @Autowired
    private UserService userService;

    @Test
    public void query(){
        User user = new User();
        user.setUserId(1);
        long start= System.currentTimeMillis();  
        System.out.println(start);// new Date()为获取当前系统时间
        List queryByCase = userService.queryByCase(user);
        long end= System.currentTimeMillis();  
        System.out.println(end);// new Date()为获取当前系统时间
        for (User user2 : queryByCase) {
            System.out.println(user2);
        }
        System.out.println(end-start);
    }
    @Test
    public void delete(){
        userService.delete(2);
    }
}

日志调成debug级别
第一次查询的时候会有sql语句打印出来
第二次则没有

然后再通过redis的客户端查询,命令为:
keys *:结果为:
127.0.0.1:6379> keys *
1) “\xac\xed\x00\x05sr\x00 org.apache.ibatis.cache.CacheKey\x0f\xe9\xd5\xb4\xcd3\xa8\x82\x02\x00\x05J\x00\bchecksumI\x00\x05countI\x00\bhashcodeI\x00\nmultiplierL\x00\nupdateListt\x00\x10Ljava/util/List;xp\x00\x00\x00\x004\xdb{X\x00\x00\x00\x05s\xe8{J\x00\x00\x00%sr\x00\x13java.util.ArrayListx\x81\xd2\x1d\x99\xc7a\x9d\x03\x00\x01I\x00\x04sizexp\x00\x00\x00\x05w\x04\x00\x00\x00\x05t\x00)com.chinaedu.back.dao.UserDao.queryByCasesr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x00sq\x00~\x00\x06\x7f\xff\xff\xfft\x00\xa8select f_user_id userId, f_real_name realName,f_role_id\n\t\troleId,f_name name,f_pwd pwd,f_eamil email,f_phone phone,f_state state\n\t\tfrom t_user\n\t \n\t\t WHERE f_user_id = ?sq\x00~\x00\x06\x00\x00\x00\x01x”

你可能感兴趣的:(redis缓存)