redis(带联接池)结合关系数据库

原创 2016年08月29日 15:22:40

首先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



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Redis对关系数据库的优势

丰富的数据结构使得redis的设计非常的有趣。不像关系型数据库那样,DEV和DBA需要深度沟通,review每行sql语句,也不像memcached那样,不需要DBA的参与。redis的DBA需要熟悉...
  • Luo_da
  • Luo_da
  • 2016-09-11 09:34
  • 1075

关系数据库标准语言SQL

  • 2015-09-21 16:44
  • 656KB
  • 下载

关系数据库 OMRLite

package com.example.ormlite; import java.sql.SQLException; import java.util.List; import com.j256....

关系数据库标准语言SQL

  • 2015-09-22 16:39
  • 1.77MB
  • 下载

关系数据库讲义

  • 2015-05-13 13:51
  • 1.68MB
  • 下载

关系数据库的第一第二第三范式

关系数据库的第一第二第三范式简单理解..

关系数据库设计

  • 2014-12-18 11:24
  • 1.73MB
  • 下载

关系数据库设计理念

  • 2014-11-19 21:01
  • 2.11MB
  • 下载

对象关系数据库

使用面向对象方法学可以定义任何一种DBMS数据库,即网络型、层次型、关系型、面向对象型均可,甚至文件系统设计可以遵循面向对象的思路。对象-关系数据库正是把面向对象方法学与关系数据库系统技术相结合的产物...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)