Redis之實戰篇(與Mybatis整合)

具體步驟以下:java

1,準備好ssm工程,若是有不會的,能夠參考mysql

springmvc+mybatis整合web

2,準備好Redis服務器redis

3,構建 pom.xml 文件,這個pom文件和以前ssm的基本同樣,只是添加了redis的支持spring

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.demo</groupId>
	<artifactId>demo</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo Maven Webapp</name>
	<properties>
		<!-- spring版本號 -->
		<spring.version>4.2.2.RELEASE</spring.version>
		<!-- mybatis版本號 -->
		<mybatis.version>3.3.0</mybatis.version>
		<!-- log4j日誌文件管理包版本 -->
		<slf4j.version>1.7.7</slf4j.version>
		<log4j.version>1.2.17</log4j.version>
	</properties>

	<dependencies>
		<dependency>
		    <groupId>jdk.tools</groupId>
		    <artifactId>jdk.tools</artifactId>
		    <version>1.7</version>
		    <scope>system</scope>
		    <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<!-- 表示開發的時候引入,發佈的時候不會加載此包 -->
			<scope>test</scope>
		</dependency>
		<!-- spring核心包 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- mybatis核心包 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>
		<!-- mybatis/spring包 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.2.2</version>
		</dependency>
		<!-- 導入java ee jar 包 -->
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-api</artifactId>
			<version>7.0</version>
		</dependency>
		<!-- 導入Mysql數據庫連接jar包 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.30</version>
		</dependency>
		<!-- 導入dbcp的jar包,用來在applicationContext.xml中配置數據庫 -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.2</version>
		</dependency>
		<!-- JSTL標籤類 -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- 日誌文件管理包 -->
		<!-- log start -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
		</dependency>

		<!-- 格式化對象,方便輸出日誌 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.1.41</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<!-- log end -->
		<!-- 映入JSON -->
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>1.9.13</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.1.0</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.1.0</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.1.0</version>
		</dependency>
		<!-- 上傳組件包 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
		</dependency>
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.9</version>
		</dependency>
		
		<dependency>
		  <groupId>redis.clients</groupId>
		  <artifactId>jedis</artifactId>
		  <version>2.8.0</version>
		</dependency>
		<dependency>
		  <groupId>commons-pool</groupId>
		  <artifactId>commons-pool</artifactId>
		  <version>1.6</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>${project.artifactId}</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>${java-version}</source>
					<target>${java-version}</target>
					<encoding>utf8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

 

4,編寫Redis須要用的2個工具類   RedisUtil.java和SerializeUtil.java。這個在前一篇已經有過,這裏再也不重複貼代碼了。sql

5,新增一個Cache類,須要實現 org.apache.ibatis.cache.Cache 接口數據庫

package demo.cache;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import demo.utils.RedisUtil;
import demo.utils.SerializeUtil;

public class MybatisRedisCache implements Cache {
	private static Logger logger = LoggerFactory.getLogger(MybatisRedisCache.class); 
	/** The ReadWriteLock. */ 
	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	
	private String id;
	
	public MybatisRedisCache(final String id) {  
		if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
		logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>MybatisRedisCache:id="+id);
        this.id = id;
    }  
	
	public String getId() {
		return this.id;
	}

	public void putObject(Object key, Object value) {
		logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>putObject:"+key+"="+value);
		RedisUtil.getJedis().set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value));
	}

	public Object getObject(Object key) {
		Object value = SerializeUtil.unserialize(RedisUtil.getJedis().get(SerializeUtil.serialize(key.toString())));
		logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>getObject:"+key+"="+value);
		return value;
	}

	public Object removeObject(Object key) {
		return RedisUtil.getJedis().expire(SerializeUtil.serialize(key.toString()),0);
	}

	public void clear() {
		RedisUtil.getJedis().flushDB();
	}

	public int getSize() {
		return Integer.valueOf(RedisUtil.getJedis().dbSize().toString());
	}

	public ReadWriteLock getReadWriteLock() {
		return readWriteLock;
	}
	
}

 

6,開啓mybatis對緩存的支持,在本項目中,是修改 spring-mybatis.xml 文件apache

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<!-- 自動掃描mapping.xml文件 -->
		<property name="mapperLocations" value="classpath:demo/mapping/*.xml"></property>
		<property name="configurationProperties">
			<props>
				<prop key="cacheEnabled">true</prop> 
				<prop key="lazyLoadingEnabled">false</prop> 
				<prop key="aggressiveLazyLoading">true</prop>
			</props>
		</property>
	</bean>

 

其中:json

<prop key="cacheEnabled">true</prop>

 

是開啓的關鍵。api

7,在相關的 mapper.xml 添加所須要用的緩存類,咱們這裏是在 TUserMapper.xml 中添加

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="demo.dao.TUserMapper">

	<cache type="demo.cache.MybatisRedisCache" />
	
	<resultMap id="BaseResultMap" type="demo.domain.TUser">
		<id column="id" property="id" jdbcType="INTEGER" />
		<result column="username" property="username" jdbcType="VARCHAR" />
		<result column="password" property="password" jdbcType="VARCHAR" />
		<result column="createtime" property="createtime" jdbcType="TIMESTAMP" />
	</resultMap>
	<sql id="Base_Column_List">
		id, username, password, createtime
	</sql>
	<select id="selectByPrimaryKey" resultMap="BaseResultMap"
		parameterType="java.lang.Integer">
		select <include refid="Base_Column_List" /> from t_user where id = #{id,jdbcType=INTEGER}
	</select>
	<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
		delete from t_user
		where id = #{id,jdbcType=INTEGER}
	</delete>
	<insert id="insert" parameterType="demo.domain.TUser">
		insert into t_user (id, username, password,
		createtime)
		values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR},
		#{password,jdbcType=VARCHAR},
		#{createtime,jdbcType=TIMESTAMP})
	</insert>
	<insert id="insertSelective" parameterType="demo.domain.TUser">
		insert into t_user
		<trim prefix="(" suffix=")" suffixOverrides=",">
			<if test="id != null">
				id,
			</if>
			<if test="username != null">
				username,
			</if>
			<if test="password != null">
				password,
			</if>
			<if test="createtime != null">
				createtime,
			</if>
		</trim>
		<trim prefix="values (" suffix=")" suffixOverrides=",">
			<if test="id != null">
				#{id,jdbcType=INTEGER},
			</if>
			<if test="username != null">
				#{username,jdbcType=VARCHAR},
			</if>
			<if test="password != null">
				#{password,jdbcType=VARCHAR},
			</if>
			<if test="createtime != null">
				#{createtime,jdbcType=TIMESTAMP},
			</if>
		</trim>
	</insert>
	<update id="updateByPrimaryKeySelective" parameterType="demo.domain.TUser">
		update t_user
		<set>
			<if test="username != null">
				username = #{username,jdbcType=VARCHAR},
			</if>
			<if test="password != null">
				password = #{password,jdbcType=VARCHAR},
			</if>
			<if test="createtime != null">
				createtime = #{createtime,jdbcType=TIMESTAMP},
			</if>
		</set>
		where id = #{id,jdbcType=INTEGER}
	</update>
	<update id="updateByPrimaryKey" parameterType="demo.domain.TUser">
		update t_user
		set username = #{username,jdbcType=VARCHAR},
		password = #{password,jdbcType=VARCHAR},
		createtime = #{createtime,jdbcType=TIMESTAMP}
		where id = #{id,jdbcType=INTEGER}
	</update>


	<select id="selectAll" resultMap="BaseResultMap">
		select <include refid="Base_Column_List" /> from t_user
	</select>
</mapper>

 

其中:

<cache type="demo.cache.MybatisRedisCache" />

 

是關鍵。

而後就能夠在本身寫的測試類或者controller中作測試了,測試的時候能夠把日誌級別設置爲debug級別,這樣能夠看到Mybatis的sql語句。當走緩存的時候,是不會打印sql語句的,反之會出現sql語句。

例如,咱們在原有的數據裏,新加了一條數據,這時緩存數據和數據庫數據就對應不上,能夠看到日誌裏有sql語句打印

[org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession
[org.mybatis.spring.SqlSessionUtils] - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1005765] was not registered for synchronization because synchronization is not active
[demo.cache.MybatisRedisCache] - >>>>>>>>>>>>>>>>>>>>>>>>getObject:-1445659396:380449231:demo.dao.TUserMapper.selectAll:0:2147483647:select  
		id, username, password, createtime
	  from t_user:SqlSessionFactoryBean=null
[demo.dao.TUserMapper] - Cache Hit Ratio [demo.dao.TUserMapper]: 0.0
[org.springframework.jdbc.datasource.DataSourceUtils] - Fetching JDBC Connection from DataSource
[org.mybatis.spring.transaction.SpringManagedTransaction] - JDBC Connection [jdbc:mysql://127.0.0.1:3306/demo, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
[demo.dao.TUserMapper.selectAll] - ==>  Preparing: select id, username, password, createtime from t_user 
[demo.dao.TUserMapper.selectAll] - ==> Parameters: 
[demo.dao.TUserMapper.selectAll] - <==      Total: 9
[demo.cache.MybatisRedisCache] - >>>>>>>>>>>>>>>>>>>>>>>>putObject:-1445659396:380449231:demo.dao.TUserMapper.selectAll:0:2147483647:select  
		id, username, password, createtime
	  from t_user:SqlSessionFactoryBean=[demo.domain.TUser@4f6d47, demo.domain.TUser@8f7ea3, demo.domain.TUser@c309e0, demo.domain.TUser@bd7ea6, demo.domain.TUser@c5fc10, demo.domain.TUser@2784fd, demo.domain.TUser@8c0b75, demo.domain.TUser@443aea, demo.domain.TUser@177e204]

 

一旦這個執行過一次後,再執行(再也不有數據變動),能夠看到,也就再也不有sql語句的打印了。

[org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession
[org.mybatis.spring.SqlSessionUtils] - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@b14a45] was not registered for synchronization because synchronization is not active
[demo.cache.MybatisRedisCache] - >>>>>>>>>>>>>>>>>>>>>>>>getObject:-1445659396:380449231:demo.dao.TUserMapper.selectAll:0:2147483647:select  
		id, username, password, createtime
	  from t_user:SqlSessionFactoryBean=[demo.domain.TUser@78471b, demo.domain.TUser@847332, demo.domain.TUser@1a6f080, demo.domain.TUser@f78840, demo.domain.TUser@11232a8, demo.domain.TUser@1bbe24e, demo.domain.TUser@672d9, demo.domain.TUser@15e2565, demo.domain.TUser@1e93ee7]
[demo.dao.TUserMapper] - Cache Hit Ratio [demo.dao.TUserMapper]: 0.6666666666666666
[org.mybatis.spring.SqlSessionUtils] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@b14a45]
[demo.domain.TUser@78471b, demo.domain.TUser@847332, demo.domain.TUser@1a6f080, demo.domain.TUser@f78840, demo.domain.TUser@11232a8, demo.domain.TUser@1bbe24e, demo.domain.TUser@672d9, demo.domain.TUser@15e2565, demo.domain.TUser@1e93ee7]

 

 

備註:在網上看到有些人說mybatis和redis整合的時候,數據庫使用mysql老是加載第一頁的數據,不會顯示之後的數據,經測試,能夠正確加載指定頁數的數據,分頁也是採用常規的分頁方法,這裏就再也不作描述了。

 

-------------------------------2016-5-12更新SerializeUtil.java------------------------

public class SerializeUtil {
    /**
     * 序列化
     * @param object
     */
    public static byte[] serialize(Object object) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            // 序列化
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {
        	e.printStackTrace();
        }
        return null;
    }

    /**
     * 反序列化
     * @param bytes
     */
    public static Object unserialize(byte[] bytes) {
        ByteArrayInputStream bais = null;
        try {
            // 反序列化
            bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {
        	e.printStackTrace();
        }
        return null;
    }
}
相關文章
相關標籤/搜索