当数据库的读写压力特别大,而读写分离也分担不了写的压力时,可以使用redis作为数据库的缓存,所有读写都在redis操作,大幅降低对数据库的负荷,同时redis的内存操作使效率提升明显,下面是一个读写redis的小例子,一个是读redis,一个是定时更新队列,特比简单,可以作为入门参考用。
Main文件:
import java.util.List;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import net.sf.json.JSONObject;
import com.mysql.jdbc.ResultSet;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
static RedisMysqlManager db = new RedisMysqlManager();
static Connection conn = null;
static PreparedStatement ps = null;
public static void main(String[] args) {
// 查询
String value =selectUser("1001");
System.out.println(value);
// 更新
insert("1030");
// 循环执行,将队列的数据更新至数据库
TimerTask task=new TimerTask() {
@Override
public void run() {
try {
queue();
} catch (SQLException e) {
e.printStackTrace();
}
}
};
Timer timer =new Timer();
long time1 = 1 * 1000;
long timer2 = 1 * 5000;
//第一个参数,是 TimerTask 类,在包:import java.util.TimerTask .使用者要继承该类,并实现 public void run() 方法,因为 TimerTask 类 实现了 Runnable 接口。
//第二个参数的意思是,当你调用该方法后,该方法必然会调用 TimerTask 类 TimerTask 类 中的 run() 方法,这个参数就是这两者之间的差值,转换成汉语的意思就是说,用户调用 schedule() 方法后,要等待这么长的时间才可以第一次执行 run() 方法。
//第三个参数的意思就是,第一次调用之后,从第二次开始每隔多长的时间调用一次 run() 方法。
timer.schedule(task, time1,timer2);
}
// 查询用户
// 1,先查询redis
// 2,redis不存在,查询数据库,并将数据保存在redis,设置过期时间
public static String selectUser(String userid){
JedisPool pool =null;
Jedis jedis =null;
String value ="";
try {
pool =redisCon.getPool();
jedis =pool.getResource();
value =jedis.get(userid);
//用户在redis不存在,则查询数据库
if(value ==null){
JSONObject json=new JSONObject();
String sql = "select USERID,USERNAME,NICKNAME,PHONENUM from t_user where userid = '" +userid + "'";
conn = db.getConnection();
ps=conn.prepareStatement(sql);
ResultSet rs = (ResultSet) ps.executeQuery();
while (rs.next()) {
//1,查询出来的字段保存在json对象的属性中
json.put("USERID", rs.getString("USERID"));
json.put("USERNAME", rs.getString("USERNAME"));
json.put("NICKNAME", rs.getString("NICKNAME"));
json.put("PHONENUM", rs.getString("PHONENUM"));
json.put("STATUS","0");
//2,将json转化字符串型,并存入jedis
jedis.set(rs.getString("USERID"), json.toString());
//3,设置过期时间 7天
jedis.expire(rs.getString("USERID"), 60*60*24*7);
//4,将结果返回
value = json.toString();
}
}
} catch (Exception e) {
//释放redis对象
pool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
redisCon.returnResource(pool, jedis);
}
return value;
}
//给队列插入数据
public static void insert(String id){
JedisPool pool =null;
Jedis jedis =null;
try {
pool =redisCon.getPool();
jedis =pool.getResource();
JSONObject json=new JSONObject();
json.put("type", "insert");
json.put("table", "t_user");
json.put("userid", id);
json.put("password", "123456");
json.put("status","0");
//从末尾插入
jedis.rpush("queue", json.toString());
} catch (Exception e) {
//释放redis对象
pool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
redisCon.returnResource(pool, jedis);
}
}
// 更新队列数据到数据库
// 需要注意的是在更新时,同时也有数据插入,只需要删除更新的数据
// 1,将队列数据放入数组或者集合
// 2,循环并生成sql语句
// 3,更新数据库
// 4,将更新完成的数据从队列中删除
public static void queue() throws SQLException{
JedisPool pool =null;
Jedis jedis =null;
JSONObject json=new JSONObject();
List<String> list=new ArrayList<String>();
try {
pool =redisCon.getPool();
jedis =pool.getResource();
// 1,操作redis
//先将数据全部导入到list,避免在redis循环查询
List<String> ltdata = jedis.lrange("queue", 0 , -1);
//循环list数据
for(int i=0;i< ltdata.size() ;i++){
json = JSONObject.fromObject(ltdata.get(i));
if(json.get("type").equals("insert")){
list.add("insert into " +json.get("table") + " ( userid,password,status) " +" values (" + json.get("userid") + "," + json.get("password") + "," + json.get("status") + ")");
}
}
//2,操作数据库
conn = db.getConnection();
conn.setAutoCommit(false);
for(int i =0 ; i < list.size() ; i++){
ps=conn.prepareStatement(list.get(i));
ps.execute();
}
//3,更新redis和数据库
// 保留参数内的数据(新加入的数据),其他的数据(已经更新的数据)删除
jedis.ltrim("queue", ltdata.size(), -1);
// 提交事务
conn.commit();
} catch (Exception e) {
conn.rollback();
//释放redis对象
pool.returnBrokenResource(jedis);
e.printStackTrace();
} finally {
//返还到连接池
redisCon.returnResource(pool, jedis);
}
}
}
redisCon文件:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class redisCon {
private static JedisPool pool =null;
public static JedisPool getPool(){
if(pool==null){
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxActive(500);
config.setMaxIdle(5);
config.setMaxWait(3*1000);
config.setTestOnBorrow(true);
pool = new JedisPool(config,"10.1.2.249",6379,1000,"123456");
}
return pool;
}
public static void returnResource(JedisPool pool, Jedis redis) {
if (redis != null) {
pool.returnResource(redis);
}
}
}