⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objectcache.java

📁 云网论坛CWBBS 源码,内容丰富,学习,参考,教学的好资料,具体见内说明,
💻 JAVA
字号:
package com.cloudwebsoft.framework.base;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import cn.js.fan.cache.jcs.ICacheMgr;
import cn.js.fan.cache.jcs.RMCache;
import cn.js.fan.db.KeyUnit;
import cn.js.fan.db.PrimaryKey;
import cn.js.fan.resource.Constant;
import cn.js.fan.security.SecurityUtil;
import cn.js.fan.web.Global;
import com.cloudwebsoft.framework.db.Connection;
import org.apache.log4j.Logger;

public class ObjectCache implements ICacheMgr, java.io.Serializable {
    public String group;
    public String COUNT_GROUP_NAME;

    public transient Logger logger;
    public transient RMCache rmCache;
    public String connname = "";

    public ObjectDb objectDb;

    public ObjectCache() {
        init();
        regist();
    }

    public ObjectCache(ObjectDb obj) {
        this.objectDb = obj;
        init();
        regist();
    }

    public void renew() {
        if (logger==null)
            logger = Logger.getLogger(this.getClass().getName());
        if (rmCache==null)
            rmCache = RMCache.getInstance();
    }

    public void init() {
        logger = Logger.getLogger(this.getClass().getName());
        connname = Global.defaultDB;
        if (connname.equals(""))
            logger.info(Constant.DB_NAME_NOT_FOUND);
        rmCache = RMCache.getInstance();
        setGroup();
        setGroupCount();
    }

    public void setGroup() {
        group = this.getClass().getName();
    }

    public void setGroupCount() {
        this.COUNT_GROUP_NAME = group + ".Count";
    }

    /**
     * 定时刷新缓存
     */
    public void timer() {
/*      // 刷新全文检索
        curFulltextLife--;
        if (curFulltextLife<=0) {
            refreshFulltext();
            curFulltextLife = FULLTEXTMAXLIFE;
        }
*/
    }

    /**
     * regist in RMCache
     */
    public void regist() {
/*        if (!isRegisted) {
            rmCache.regist(this);
            isRegisted = true;
        }
 */
    }

    public void setObjectDb(ObjectDb objectDb) {
        this.objectDb = objectDb;
    }

    public void setObjCachable(boolean objCachable) {
        this.objCachable = objCachable;
    }

    public void setListCachable(boolean listCachable) {
        this.listCachable = listCachable;
    }

    public void refreshCreate() {
        if (!listCachable)
            return;
        refreshList();
    }

    public void refreshList() {
        if (!listCachable)
            return;
        try {
            // 当在修改OA中档案模块时,发现如果置用户为invalid,则在置用户职位时,因为user_sel.jsp中使用了getObjects,而当save时,并未刷新列表,就是因为未刷新列表
            // 因此添加此方法
            rmCache.invalidateGroup(COUNT_GROUP_NAME);
            rmCache.invalidateGroup(group);
        }
        catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    public void refreshSave(PrimaryKey pk) {
        if (objCachable)
            removeFromCache(pk);
    }

    public void refreshDel(PrimaryKey pk) {
        try {
            if (objCachable)
                removeFromCache(pk);
            if (listCachable)
                refreshList();
        }
        catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * 每个节点有两个Cache,一是本身,另一个是用于存储其孩子结点的cache
     * @param code String
     */
    public void removeFromCache(PrimaryKey pk) {
        if (objCachable) {
            try {
                rmCache.remove(pk.getValue(), group);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
    }

    public IObjectDb getObjectDb(PrimaryKey pk) {
        IObjectDb obj = null;
        if (objCachable) {
            try {
                obj = (ObjectDb) rmCache.getFromGroup(pk.getValue(), group);
            } catch (Exception e) {
                logger.error("getObjectDb:" + e.getMessage());
            }

            // logger.info("obj=" + obj + " pk=" + pk.getValue() + " group=" + group);
            if (obj == null) {
                obj = objectDb.getObjectRaw(pk);
                // 如果没能载入就不能放入缓存,否则放入缓存后,这个对象后来又生成了,
                // 比如SweetUserDb,就不会再从数据库中获取,就会被认为user未加入SweetUserDb对应的表中
                if (obj != null && obj.isLoaded()) {
                    try {
                        rmCache.putInGroup(pk.getValue(), group, obj);
                    } catch (Exception e) {
                        logger.error("getObjectDb1:" + e.getMessage());
                    }
                }
            } else {
                // logger.info("logger=" + obj.logger);
                obj.renew();
                // obj.logger.info("yes");
            }
        }
        else
            obj = objectDb.getObjectRaw(pk);

        return obj;
    }

    /**
     *
     * @param sql String
     * @return int -1 表示sql语句不合法
     */
    public int getObjectCount(String sql) {
        //根据sql语句得出计算总数的sql查询语句
        String query = cn.js.fan.db.SQLFilter.getCountSql(sql);
        if (!SecurityUtil.isValidSql(query))
            return -1;
        Integer count = null;
        if (listCachable) {
            try {
                count = (Integer) rmCache.getFromGroup(query, COUNT_GROUP_NAME);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
            // If already in cache, return the count.
            if (count != null) {
                return count.intValue();
            }
        }
        // Otherwise, we have to load the count from the db.
        int docCount = 0;
        Connection conn = new Connection(connname);
        ResultSet rs = null;
        try {
            rs = conn.executeQuery(query);
            if (rs.next())
                docCount = rs.getInt(1);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (Exception e) {}
                rs = null;
            }
            if (conn != null) {
                conn.close();
                conn = null;
            }
        }
        // Add the count to cache
        if (listCachable) {
            try {
                rmCache.putInGroup(query, COUNT_GROUP_NAME,
                                   new Integer(docCount));
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
        return docCount;
    }

    public Object[] getObjectBlock(String sql, int startIndex) {
        // First, discover what block number the results will be in.
        int blockSize = objectDb.getBlockSize();
        int blockID = startIndex / blockSize;
        int blockStart = blockID * blockSize;

        PrimaryKey primaryKey = objectDb.getPrimaryKey();
        // 取得根据主键的查询语句
        // String pk = primaryKey.getName();
        // String query = "select " + pk + " " + SQLFilter.getFromSql(sql); // 当为联合查询时,此句中的pk会带来问题,因为缺少表的别名作为前缀 2006.6.9
        // String query = "select " + objectDb.getTableName() + "." + pk + " " + SQLFilter.getFromSql(sql); // 加表名作为前缀在oracle中也不行
        String query = sql;

        // 缓存所用的key
        String key = query + blockID;

        Object[] objArray = null;
        // 如果使用列表缓存
        if (listCachable) {
            try {
                objArray = (Object[]) rmCache.getFromGroup(key,
                        group);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
            // If already in cache, return the block.
            if (objArray != null) {
                /**
                 * The actual block may be smaller than THREAD_BLOCK_SIZE. If that's
                 * the case, it means two things:
                 *  1) We're at the end boundary of all the results.
                 *  2) If the start index is greater than the length of the current
                 *     block, than there aren't really any results to return.
                 */
                Object[] objkeys = objArray;
                // 当startIndex过大时
                if (startIndex >= blockStart + objkeys.length) {
                    // Return an empty array
                    return ObjectDb.EMPTY_BLOCK;
                } else {
                    return objkeys;
                }
            }
        }
        // Otherwise, we have to load up the block from the database.

        Vector block = new Vector();
        ResultSet rs = null;
        Connection conn = new Connection(connname);
        try {
            // Set the maxium number of rows to end at the end of this block.
            conn.setMaxRows(blockSize * (blockID + 1));
            rs = conn.executeQuery(query);
            //logger.info("query=" + query);
            // Grab THREAD_BLOCK_ROWS rows at a time.
            conn.setFetchSize(blockSize);
            // Many JDBC drivers don't implement scrollable cursors the real
            // way, but instead load all results into memory. Looping through
            // the results ourselves is more efficient.
            for (int i = 0; i < blockStart; i++) {
                rs.next();
            }
            // Keep reading results until the result set is exaughsted or
            // we come to the end of the block.
            int count = 0;
            while (rs.next() && count < blockSize) {
                // 如果不是复合主键
                if (primaryKey.getKeyCount() == 1) {
                    if (primaryKey.getType() == primaryKey.TYPE_INT)
                        block.addElement(new Integer(rs.getInt(1)));
                    if (primaryKey.getType() == primaryKey.TYPE_STRING)
                        block.addElement(rs.getString(1));
                    if (primaryKey.getType() == primaryKey.TYPE_LONG)
                        block.addElement(new Long(rs.getLong(1)));
                } else if (primaryKey.getType() == primaryKey.TYPE_COMPOUND) { // 如果是复合主键
                    HashMap keys = ((PrimaryKey) primaryKey.clone()).getKeys();
                    Iterator ir = keys.keySet().iterator();
                    while (ir.hasNext()) {
                        String keyName = (String) ir.next();
                        KeyUnit ku = (KeyUnit) keys.get(keyName);
                        if (ku.getType() == primaryKey.TYPE_INT) {
                            ku.setValue(new Integer(rs.getInt(ku.getOrders() + 1)));
                        } else if (ku.getType() == primaryKey.TYPE_LONG) {
                            ku.setValue(new Long(rs.getLong(ku.getOrders() + 1)));
                        } else {
                            ku.setValue(rs.getString(ku.getOrders() + 1));
                        }
                    }
                    // 遗漏了下句,补于2005-8-22
                    block.addElement(keys);
                }
                count++;
            }
        } catch (SQLException sqle) {
            logger.error("getObjectBlock:" + sqle.getMessage());
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (Exception e) {}
                rs = null;
            }
            if (conn != null) {
                conn.close();
                conn = null;
            }
        }
        int len = block.size();
        Object[] objkeys = new Object[len];
        for (int i = 0; i < len; i++) {
            objkeys[i] = block.elementAt(i);
        }
        // 将block加至缓存,len为0时也加入至缓存,因为如果有新数据插入了表中,则相关操作应刷新缓存,此处缓存也能得到更新
        if (listCachable) {
            try {
                rmCache.putInGroup(key, group, objkeys);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
        /**
         * The actual block may be smaller than THREAD_BLOCK_SIZE. If that's
         * the case, it means two things:
         *  1) We're at the end boundary of all the results.
         *  2) If the start index is greater than the length of the current
         *     block, than there aren't really any results to return.
         */
        if (startIndex >= blockStart + objkeys.length) {
            // Return an empty array
            return ObjectDb.EMPTY_BLOCK;
        } else {
            return objkeys;
        }
    }

    public boolean isObjCachable() {
        return objCachable;
    }

    public boolean isListCachable() {
        return listCachable;
    }

    public boolean objCachable = true;
    public boolean listCachable = true;

}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -