redis(帶聯接池)結合關係數據庫

首先Maven導入

    <!--spring整合redis -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.4.2.RELEASE</version>
        </dependency>

<!-- redis緩存 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.4.2</version>
        </dependency>


再配置spring.xml文件,我這是已經整合好Spring,Mybatis和struts2的xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx    http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop 	http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/jee 	http://www.springframework.org/schema/jee/spring-jee.xsd">

	<context:component-scan base-package="com.microblog"></context:component-scan>
	<tx:annotation-driven transaction-manager="txManager" />

	<!-- 配置數據庫連接腳本 -->
	<bean id="a"
		class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
		<property name="locations" value="classpath:jdbc.properties"></property>
	</bean>

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${mysql.driverName}"></property>
		<property name="url" value="${mysql.url}"></property>
		<property name="username" value="${mysql.uname}"></property>
		<property name="password" value="${mysql.pwd}"></property>
	</bean>

	<!-- 事物觸發器 -->
	<bean id="txManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="typeAliasesPackage" value="com.microblog.bean"></property>
		<property name="mapperLocations" value="classpath:com/microblog/dao/mapper/*.xml" ></property>
		<property name="configurationProperties">
			<props>
				<prop key="logImpl">LOG4J</prop>
			</props>
		</property>
	</bean>

	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg ref="sqlSessionFactory"></constructor-arg>
	</bean>
	
	<!-- 創建redis工廠 -->
	<bean id="jedisFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
		<property name="hostName" value="localhost" />
		<property name="port" value="6379" />
		<property name="usePool" value="true" />
	</bean>

	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="jedisFactory" />
		<property name="keySerializer">
			<bean
				class="org.springframework.data.redis.serializer.StringRedisSerializer" />
		</property>
		<property name="valueSerializer">
			<bean
				class="org.springframework.data.redis.serializer.StringRedisSerializer" />
		</property>
	</bean>
	
</beans>

沒整合的也可只需加入創建redis工廠部分即可。如果用的聯接池則也不需要配置redis工廠

DAO層接口加入一些redis常用方法

//redis   start
	/**
	 * 存
	 * @param key
	 * @param value
	 */
	public void setKey( String key,  String value);
	/**
	 * 根據鍵取值
	 * @param key
	 * @return
	 */
	public Object getKey( String key);
	/**
	 * 自增
	 * @param key
	 */
	public void incr( String key);
	/**
	 * 自減
	 * @param key
	 */
	public void decr( String key);
	/**
	 * 在上一個元素的左邊存
	 * @param key
	 * @param value
	 */
	//public void lPush( String key, String value);
	/**
	 * 查看是否有這個鍵
	 * @param key
	 * @return
	 */
	//public boolean checkKey( String key);
	/**
	 * 按鍵取
	 * @param key
	 * @return
	 */
	//public Object lIndex( String key);
	/**
	 * 求長度
	 * @param key
	 * @return
	 */
	//public Long lLength( String key);
	/**
	 * 從上一個元素的左邊取值
	 * @param key
	 * @return
	 */
	//public String lPop( String key);
	/**
	 * 按正則表達式匹配的鍵取值
	 * @param pattern
	 * @return
	 */
	//public Set<String> getKeys( String pattern);
	//redis  end

DaoImpl實現類進行實現:
private RedisCache client = new RedisCache();
//redis數據庫方法 start
	@Override
	public void setKey(String key, String value) {
		this.client.set(key, value);
	}

	@Override
	public Object getKey(String key) {
		if(this.client.get(key)==null){
			return null;
		}
		return this.client.get(key);
	}

	@Override
	public void incr(String key) {
		this.client.increment(key);
	}
	
	@Override
	public void decr(String key) {
		this.client.decr(key);
		
	}
<pre name="code" class="java">//redis數據庫方法 end


因爲加入了聯接池,所以一些自增自減的方法需要在RedisCache類中進行重寫

package com.microblog.dao.mybatis.cache;

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

import org.apache.ibatis.cache.Cache;
import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;

import com.microblog.dao.redis.RedisPool;

public class RedisCache implements Cache {

	/*
	 * 日誌對象
	 */
	private static Logger logger = org.apache.log4j.Logger
			.getLogger(RedisCache.class);

	private String id;

	private Jedis redisClient = createRedis();

	// 用於同步的鎖
	private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

	public RedisCache(String id) {
		if (id == null) {
			throw new IllegalArgumentException("Cache instance requires an Id");
		}
		logger.debug("create an cache instance with id:" + id);
		this.id = id;
	}

	public RedisCache() {
	}

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

	// 將緩存中的數據刪除
	public void clear() {
		logger.debug("clear redis cache");
		this.redisClient.flushDB();
	}

	// 通過key到緩存redis中取值
	public Object getObject(Object key) {
		// 緩存穿透.
		byte[] values = this.redisClient.get(SerializableUtil.serialize(key));
		// System.out.println( values );
		if (values == null) {
			// this.putObject( SerializableUtil.serialize(key) , null);
			return null;
		}
		Object obj = SerializableUtil.unSerialize(values);
		logger.debug("get data:" + key + " from cache,result is:" + obj);
		return obj;
	}

	public ReadWriteLock getReadWriteLock() {
		return readWriteLock;
	}

	public int getSize() {
		Long size = this.redisClient.dbSize();
		int s = Integer.valueOf(size + "");
		return s;
	}

	public void putObject(Object key, Object value) {
		byte[] keybyte = SerializableUtil.serialize(key);
		byte[] valuebyte = SerializableUtil.serialize(value);
		this.redisClient.set(keybyte, valuebyte);
	}

	public Object removeObject(Object key) {
		byte[] keybyte = SerializableUtil.serialize(key);
		return this.redisClient.expire(keybyte, 0);
	}

	/**
	 * TODO:jedis從聯接池中取
	 * 
	 * @return
	 */
	protected static Jedis createRedis() {
		// TODO: 獲取jedis實例 -> 這個地址要變
		// Jedis jedis = new Jedis("192.168.137.128");
		Jedis jedis = RedisPool.getPool().getResource();
		return jedis;
	}

	public void set(String key, String value) {
		this.redisClient.set(key, value);
	}

	public Object get(String key) {
		return this.redisClient.get(key);
	}

	public void increment(String key) {
		this.redisClient.incr(key);
	}

	public void decr(String key) {
		this.redisClient.decr(key);
	}

}

將對象序列化的類

package com.microblog.dao.mybatis.cache;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializableUtil {
    /**
     * 將對象序列化
     */
    public static byte[] serialize(Object obj) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        byte[] bs = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            bs = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bs;
    }

    public static Object unSerialize(byte[] bs) {
        ByteArrayInputStream bais = null;
        Object obj = null;

        try {
            bais = new ByteArrayInputStream(bs);
            ObjectInputStream ois = new ObjectInputStream(bais);
            obj = ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bais != null) {
                try {
                    bais.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return obj;
    }

}




然後是讀取聯接池的配置

package com.microblog.dao.redis;

import java.util.ResourceBundle;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 以單例模式創建一個jedis的聯接池
 */
public class RedisPool {

	private static JedisPool pool;


	public synchronized static JedisPool getPool() {
		if(  pool==null ){
			new RedisPool();
		}
		return pool;
	}

	private RedisPool() {
		ResourceBundle bundle = ResourceBundle.getBundle("redis");
		if (bundle == null) {
			throw new IllegalArgumentException(
					"[redis.properties] is not found!");
		}
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(Integer.valueOf(bundle
				.getString("redis.pool.maxActive")));
		config.setMaxIdle(Integer.valueOf(bundle
				.getString("redis.pool.maxIdle")));
		config.setMaxWaitMillis(Long.valueOf(bundle
				.getString("redis.pool.maxWait")));
		config.setTestOnBorrow(Boolean.valueOf(bundle
				.getString("redis.pool.testOnBorrow")));
		config.setTestOnReturn(Boolean.valueOf(bundle
				.getString("redis.pool.testOnReturn")));
		
		pool = new JedisPool(config, bundle.getString("redis.ip"),
				Integer.valueOf(bundle.getString("redis.port")));
	}

	

}

你需要一個redis.properties

redis.pool.maxActive=1024
redis.pool.maxIdle=200
redis.pool.maxWait=1000
redis.pool.testOnBorrow=true
redis.pool.testOnReturn=true
redis.ip=127.0.0.1
redis.password=123
redis.port=6379


再是業務層的實現

package com.microblog.biz.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import com.microblog.bean.Blog;
import com.microblog.biz.BlogBiz;
import com.microblog.dao.BaseDao;
import com.microblog.web.model.BlogModel;

@Service
@Transactional(readOnly = true)
public class BlogBizImpl implements BlogBiz {
	private BaseDao baseDao;

	@Resource(name = "baseDaoImpl")
	public void setBaseDao(BaseDao baseDao) {
		this.baseDao = baseDao;
	}

	/**
	 * 發佈微博存入數據庫
	 */
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = false, isolation = Isolation.DEFAULT, rollbackForClassName = "java.lang.RuntimeException", propagation = Propagation.REQUIRED)
	public void saveBlog(Blog blog) {
		this.baseDao.save(blog, "saveBlog");
	}

	// 得到總的微博
	public BlogModel findAllBlog(BlogModel hs) {
		// 查詢總記錄數
		int count = baseDao.getCount(Blog.class, "getBlogCount");
		// 計算總頁數
		int total = count % hs.getSizePage() == 0 ? count / hs.getSizePage()
				: count / hs.getSizePage() + 1;
		hs.setTotal(total);
		// 計算偏移量
		int off = (hs.getCurrPage() - 1) * hs.getSizePage();
		List<Blog> hh = this.baseDao.findList(Blog.class, null, "getBlog", off,
				hs.getSizePage());
		// 操作redis數據庫 整合關係數據庫
		for (Blog blog : hh) {
			Long id = blog.getId();
			// 獲取點贊數
			String parse = (String) this.baseDao.getKey("user:parse" + id);
			blog.setParse(parse);
			// 獲取轉發數
			String relay = (String) this.baseDao.getKey("user:relay" + id);
			blog.setRelay(relay);
		}
		hs.setBlogs(hh);
		return hs;
	}

	// 點贊(redis)
	@Override
	public String parse(Long id, int uid) {
		// 當用戶沒有點贊,則點贊數+1,redis中用戶字段+1;點了贊,則點贊數-1,redis中用戶字段-1
		if (id > 0 && uid > 0) {
			if (this.baseDao.getKey(id + "user:id" + uid) == null
					|| Integer.parseInt((String) this.baseDao.getKey(id
							+ "user:id" + uid)) == 0) {
				this.baseDao.incr("user:parse" + id);

				this.baseDao.incr(id + "user:id" + uid);
			} else {
				this.baseDao.decr("user:parse" + id);
				this.baseDao.decr(id + "user:id" + uid);
			}
			String num = (String) this.baseDao.getKey("user:parse" + id);
			return num;
		} else {
			return null;
		}

	}

	// 轉發(redis)

	@Override
	public String relay(Long id, int uid) {
		// 當用戶沒有轉發,則轉發數+1,redis中用戶字段+1;已轉發,則不允許轉發
		if (id > 0 && uid > 0) {
			if (this.baseDao.getKey(id + "user:relayid" + uid) == null
					|| Integer.parseInt((String) this.baseDao.getKey(id
							+ "user:relayid" + uid)) == 0) {
				this.baseDao.incr("user:relay" + id);
				this.baseDao.incr(id + "user:relayid" + uid);
				String num = (String) this.baseDao.getKey("user:relay" + id);
				return num;
			} else {
				return null;
			}
		} else {
			return null;
		}
	}

}

測試類

//測試redis點贊數的自增
	public void testApp09() {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"beans_mybatis.xml");
		BlogBiz ub=(BlogBiz) ac.getBean("blogBizImpl");
		System.out.println("當前點贊數"+ub.parse(2L,1));
	}
	//測試redis轉發數
		public void testApp10() {
			ApplicationContext ac = new ClassPathXmlApplicationContext(
					"beans_mybatis.xml");
			BlogBiz ub=(BlogBiz) ac.getBean("blogBizImpl");
			System.out.println("當前轉發數"+ub.relay(2L, 1));
		}

詳細項目 https://github.com/937129397/microBlog/tree/dev/microBlog


參考資料 http://blog.csdn.net/tanggao1314/article/details/51125199



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