redis作为缓存的简单读写例子

时间:2020-12-27 20:47:47

当数据库的读写压力特别大,而读写分离也分担不了写的压力时,可以使用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;

public class Main {
    
    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);
        }
     }
}