可能题目有点不明确,。。我这样说好了:由于我的程序要大量访问数据库中的记录的,如果要读一条记录的话就要访问一次数据库,(数据库已使用了连接池)。所以如果我把一部分记录(20万条)放到内存里的话就可以大大减少读数据库中记录的次数,它在内存里找到有的话就直接从内存里取了,而不用再访问数据库。当然如果在程序里又能加以判断那些记录是经常要访问的,那些是很少访问的,然后就把那很少访问的记录自动删除掉的话,性能又更不错了。请问一下大家,这个用java要怎么实现,要使用那些类、那些方法比较好,先谢谢了!!数据库表users中的字段只有(id,name,password,membercode,status)。下面这图是刚刚画的操作数据库图,希望大家能看懂、、、

解决方案 »

  1.   

    你的想法是对的,可以先将一部分数据放到内存中,以减少数据库的访问,但是20万条都放到内存里就不太好了,一是加载的时候慢,二是占用的内存也比较多。
    可以少放一些。可以放到数组中。天狼工作室
    http://www.j2soft.cn
      

  2.   

    一个典型的 cache 应用吧,具体的不清楚,当然用 map, 或者数组也是可以的,但如何来判断经常,可能是个头痛的问题吧
      

  3.   

    我的简单解决方案是: 
    针对记录表,写一个对应的类。它的一条记录,对应一个对象。 
    这个类要重写hasCode方法,使得返回name的hasCode值。 
    写一个Cache类,扩展LinkedHashMap,重写removeEldestEntry方法。 
    Cache类里面的Key存放name,Value存放对象本身。 
    在构造器中,调用超类的构造方法时,选择三个参数的构造器,并且,第三个参数accessOrder要设置成true。 
    然后,protected boolean removeEldestEntry(Entry eldest) {
      if(size()<=cacheSize)return false;//cacheSize设置成20万
      return true;
    }超类的第二个参数,不要太小,要是不知道设置成多少,就设置成1f好了。 其他的部分,按照我的思路,楼主就可以完成了吧 ?
      

  4.   

    看看hibernate的源码,它里面有个缓存机制,你看看是不是你要的
      

  5.   

    直接用OSCache来做。你可以搜索一下看看关于它的介绍
      

  6.   

    某些数据库直接内置了这种方式,也就是说,数据库系统自己把部分数据读到内存里,然后你查询的时候,表面上还是从数据库里查询,但是实际上,数据库系统是从内存中读出这部分数据的(当然,内存里没有的还是要去数据库里读)。我记得Oracle支持这种方式。
      

  7.   

    首先同意1楼,内存里面放的别太多了。用map,逻辑大概就是,一下几点。
    1.以id为识别字段。
    2.当哪几个字段改变时,更新map中记录。
    3.加个时间字段,当时间大于多少时,更新map中的记录(这个比较次要也可以不做)。就这几点,其它想不到了。楼下补充。
      

  8.   

    算一下.. 就算1条数据按最大的 1k算的话..1000条才1M . 
    10000条10M
    1000000条1G.
    当然..几个字段肯定没有1K ..看来还是很可行的.. 但就是 全读到内存里面很费时间..
      

  9.   

    我的浏览器点了2次才发到贴,可一出来之后竟然发了2个贴了,呵呵!
    所以希望大家也关注一下这贴(我有回复了的):http://topic.csdn.net/u/20081010/15/ad7b4242-13b9-4372-8c40-c22f5cdddc50.html
      

  10.   

    在IBATIS里可以这样写
    <cacheModel id="categoryCache" type="LRU">
    <flushOnExecute statement="insert"/>
    <flushOnExecute statement="update"/>
    <flushOnExecute statement="delete"/>
    <property name="reference-type" value="WEAK"/>
    </cacheModel>
    <select
    id="getCategory" parameterClass="Category"
    resultClass="Category" cacheModel="categoryCache">
    SELECT *
    FROM Category
    WHERE categoryId=#categoryId#
    </select>
    type
    MEMORY       This model simply stores the cached data in memory
    until        the garbage collector removes it.
    FIFO         This is a fixed size model that uses a “first in, first out”
                   algorithm to remove items from memory.
    LRU          This is another fixed-size model that uses a “least
                 recently used” algorithm to remove items from memory.
    OSCACHE      This model uses the OpenSymphony (or OS) cache.在Hibernate里也应该有相应的配置,不过没有深入研究过。建议不要自己写,除非你的技术非常过硬,因为当你自己写时,要考虑的东西很多,最重要的就是数据的准备性,处理不好返尔事得其返。
      

  11.   

    axman老大,你msn怎么从来不上。真晕.........
      

  12.   


    LRU 可以把很少访问的删掉,在 Apache Commons Collections 中有个 org.apache.commons.collections.map.LRUMap
    这个类就是做这种事情的,初始化设定一个最大的容量值,在满了的时候会把
    最少用到的那一个删掉,用这个类可以设计你自己的缓存。不过可以肯定的一点是绝对不可能把 20 万数据全塞进去放内存中。不建议自己去设计一个缓存工具,可以用开源缓存框架,如 EhCache, OSCache 等等。
    http://www.open-open.com/13.htm
    上面有很多的。
      

  13.   

    使用开源的缓存框架就行了,种类很多想Oscache
    应该比较适合你,
    可以时候对象在缓存中的发呆时间,到了发呆时间就从缓存中删除掉了,也就是说缓存里面的数据都是活跃的。
    大量的数据缓存框架会存储到磁盘上,这也比从数据库大量的筛选要快的多了。
      

  14.   

    在这里先要感谢3楼的大侠,现在已基本实现了,只是不知道怎么控制HashMap的容量,再次请问一下大家,
    这里是返回hashmap的代码:public HashMap getHashmap(String sql){
    HashMap<Integer,UserInfo> hashmap = new HashMap<Integer,UserInfo>(200000);      //这里初始化200000没有作用啊!!!!
    SQLConnect sqlc = new SQLConnect();       
    ResultSet rs = null;
    try{
    rs = sqlc.query(sql);     //执行查询
    while(rs.next()){
    int id = Integer.parseInt(rs.getString(1));
    String name = rs.getString(2);
    String password = rs.getString(3);
    int status = Integer.parseInt(rs.getString(4));
    UserInfo ui = new UserInfo(id,name,password,status);   //记录封装在UserInfo类
    hashmap.put(id,ui);
    }
    }catch(Exception e){
    System.out.println(e.getMessage());
    }
    return hashmap;
    }HashMap<Integer,UserInfo> hashmap = new HashMap<Integer,UserInfo>(200000);      
    这一句控制容量的控制不了,(我把结果get出来了)结果是把一张表中50万条记录都保存到hashmap里去了,我只想要保存表中的20万啊!!请问这个要怎么实现啊!
      

  15.   

    lz一下从数据库里面取20万放map里面这种设计真是。。
    看楼主代码应该初涉及java不久,希望不要走弯路。
    我相信楼下会有人同意我的观点。
    正如12楼所说,要考虑的东西很多,处理不好返尔事得其返。 
    2年多开发经验,没听说过这种设计。
      

  16.   

    这样显然不能的HashMap有个默认加载因子,好像是可以自动扩容的,你用HashMap(int initialCapacity, float loadFactor)来构造看看,把loadFactor也就是加载因子设为0,看可不可以控制容量,我这网吧,不能试试.不过如20楼所说,干啥要这样呢,要这样也别自己写,除非你已是牛牛B的人,不然用现成的东西好.
      

  17.   

    赞同20楼那位兄弟的看法,以及火龙果的方案,
    如果有现成的更好的,数据库缓存方案,那就立刻使用,
    毕竟使用HashMap这种缓存方法,功能太过单一,使得以后对程序功能的添加造成过大的影响。如果楼主决定使用我在3楼所提供的那个HashMap方案。
    那么,请楼主仔细再阅读一下里面内容,理解我的目的。我在你的同名帖子里也有相关的恢复,请仔细看一下。
    我在网吧,我法把其中代码写个例子给你。现在,我再说明一下:针对你在19楼的回复,
    1. HashMap<Integer,UserInfo> hashmap = new HashMap<Integer,UserInfo>(200000);
      不要直接使用HashMap做为缓存,要自己写一个LinkedHashMap的扩展类
      (我暂时将其命名为CacheMap,扩展类就是你在声明的时候 public class CacheMap extends LinkedHashMap),
      因为LinkedHashMap类,可以实现按照访问顺序,将里面的元素进行排序。
      这样,我们就可以实现,当缓存已经满20万的时候,如果在田加数据,那么同时会优先删除缓存内不经常访问的对象。
      当然,实现这个功能,还要第二点的支持。
    2.CacheMap类要重写removeEldestEntry方法,这个方法,在你向其对象添加新元素的时候被调用。
      具体代码,我在3楼已经写了。
      目的就是保证CacheMap的对象,里面所存储的键值对,不超过20万个。
    3.既然要写个CacheMap类,那么,在构造器(构造函数)中的代码,记得要调用超类的构造方法,
      并且调用超类的构造方法时,选择三个参数的构造器,并且,第三个参数accessOrder要设置成true
      这样可以使的,其对象,在向里面添加键值对的时候,可以将键值对按照访问顺序排序。
    4.我在3楼所说的重写hasCode方法,就不用重写了。
    5。关于该方案缺点的几个声明
      A.说白了CacheMap还是Map接口的一个实现类,那么,<Key>元素,不能重复。
      B.UserInfo对象的查找也会存在问题,
        这些缓存中的数据(UserInfo对象),在查找的时候是按什么来查找?是id还是name,还是别的什么?
        如果是按照id查找,那就无所谓,key存放id就可以了。
        如果按name来查找,key就应该存放name,如果数据库允许name重复存在,
          那么,CacheMap这种缓存机制,就无法实现对UserInfo对象的快速查找定位,
          创建这种缓存,也就没有什么意义。