spring boot +mybatis+redis集成

整體思路

之前已經有人做過mybatis+redis在spring環境的集成(http://blog.csdn.net/xiadi934/article/details/50786293)。 這裏我們試試在spring boot中的集成,其中的一些注意點是不同的。特別是spring boot 的對mybatis的集成時候可以非常簡單,但是在加入二級緩存時候,我們要考慮mybatis的配置。

pom 中加入依賴

<boot.version>1.3.1.RELEASE</boot.version> 
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.1.1</version>
</dependency>
<dependency>  
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
    <version>${boot.version}</version>
</dependency>

applicationContext-cache.xml中引入redis配置

<!-- redis數據源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
    <property name="maxIdle" value="${spring.redis.maxIdle}" />  
    <property name="maxTotal" value="${spring.redis.maxActive}" />  
    <property name="maxWaitMillis" value="${spring.redis.maxWait}" />  
    <property name="testOnBorrow" value="${spring.redis.testOnBorrow}" />  
</bean>
<!-- Spring-redis連接池管理工廠 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"  
    p:host-name="${spring.redis.host}" p:port="${spring.redis.port}" p:password="${spring.redis.password}"  p:pool-config-ref="poolConfig"/>  
<!-- 使用中間類解決RedisCache.jedisConnectionFactory的靜態注入,從而使MyBatis實現第三方緩存 -->
<bean id="redisCacheTransfer" class="com.wedo.stream.cache.RedisCacheTransfer">
    <property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
</bean>

實現Cache接口

這個和原來的完全一致。

RedisCache

public class RedisCache implements Cache {
    private static Logger LOGGER = LoggerFactory.getLogger(RedisCache.class);

    private static JedisConnectionFactory jedisConnectionFactory;

    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");
        }
        LOGGER.debug("MybatisRedisCache:id=" + id);
        this.id = id;
    }

    @Override
    public void clear() {
        JedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            connection.flushDb();
            connection.flushAll();
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public Object getObject(Object key) {
        Object result = null;
        JedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer<Object> 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 ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }

    @Override
    public int getSize() {
        int result = 0;
        JedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            result = Integer.valueOf(connection.dbSize().toString());
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }

    @Override
    public void putObject(Object key, Object value) {
        JedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
            connection.set(serializer.serialize(key), serializer.serialize(value));
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    @Override
    public Object removeObject(Object key) {
        JedisConnection connection = null;
        Object result = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
            result = connection.expire(serializer.serialize(key), 0);
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }

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

}

RedisCacheTransfer

public class RedisCacheTransfer 
{
    @Autowired
    public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory)     {
        RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
    }

}

配置文件application.yml 中添加

#Redis settings  
spring:
 redis:
  host: 127.0.0.1
  password: aaa
  port: 6379
mybatis:
 mapperLocations: classpath*:com/wedo/stream/dao/xml/*.xml
 typeAliasesPackage: com.wedo.stream.dao.entity
 configLocation: classpath:mybatis-config.xml

Mybatis全局配置mybatis-config.xml

注意這個原本是不需要的,並且mybatis 默認是打開二級緩存的。但是我們爲了在測試時候能關閉二級緩存還是加上了該配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <settings>
        <!-- 開啓駝峯匹配 -->
        <setting name="mapUnderscoreToCamelCase" value="true" />
        <!-- 這個配置使全局的映射器啓用或禁用緩存。系統默認值是true,設置只是爲了展示出    來 -->
        <setting name="cacheEnabled" value="true" />
        <!-- 全局啓用或禁用延遲加載。當禁用時,所有關聯對象都會即時加載。     系統默認值是true,設置只是爲了展示出來 -->
        <setting name="lazyLoadingEnabled" value="true" />
        <!-- 允許或不允許多種結果集從一個單獨的語句中返回(需要適合的驅動)。     系統默認值是true,設置只是爲了展示出來 -->
        <setting name="multipleResultSetsEnabled" value="true" />
        <!--使用列標籤代替列名。不同的驅動在這方便表現不同。參考驅動文檔或充分測試兩種方    法來決定所使用的驅動。 系統默認值是true,設置只是爲了展示出來 -->
        <setting name="useColumnLabel" value="true" />
        <!--允許 JDBC 支持生成的鍵。需要適合的驅動。如果設置爲 true     則這個設置強制生成的鍵被使用,儘管一些驅動拒絕兼容但仍然有效(比如 
            Derby)。 系統默認值是false,設置只是爲了展示出來 -->
        <setting name="useGeneratedKeys" value="false" />
        <!--配置默認的執行器。SIMPLE 執行器沒有什麼特別之處。REUSE     執行器重用預處理語句。BATCH 執行器重用語句和批量更新     系統默認值是SIMPLE,設置只是爲了展示出來 -->
        <setting name="defaultExecutorType" value="SIMPLE" />
        <!--設置超時時間,它決定驅動等待一個數據庫響應的時間。     系統默認值是null,設置只是爲了展示出來 -->
        <setting name="defaultStatementTimeout" value="25000" />
    </settings>
</configuration>

mapper中加入MyBatis二級緩存

<mapper namespace="com.wedo.stream.dao.mapper.SorterMapper" >
  <cache type="com.wedo.stream.cache.RedisCache" />
  .....
</mapper>  

實體類實現 Serializable

public class Sorter implements Serializable

測試

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/spring-dao.xml","/applicationContext-cache.xml"})
@ActiveProfiles(value="dev")
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
    DbUnitTestExecutionListener.class })
public class CacheTest {
    private static Logger LOGGER = LoggerFactory.getLogger(CacheTest.class);
    @Autowired
    private SorterMapper mapper;
    @Test
    public void test(){
        Date start = new Date();
        for(int i=0;i<100;i++){
            mapper.getall();
        }
        Date end = new Date();
        long duration = end.getTime()-start.getTime();
        LOGGER.info(duration);
    }
}

測試結果,如果打開二級緩存,用時363毫秒,如果關閉二級緩存用時6秒+,平均一次查詢50毫秒。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章