1

每次我从数据库加载某些值时,HashMap 都会从数据库中加载某些键和值,我如何使这个 HashMap 可用于所有其他类,而不必在每次调用时将值重复加载到 HashMap 中:

这是包含加载 HashMap 的方法的类:

public class Codes {
    List<CODES> List = null;
         private CodesDAO codesDAO = new CodesDAO(); //DAO Class

    public HashMap <MultiKey,String> fetchCodes(){

        MultiKey multiKey;
        HashMap <MultiKey,String> map = new HashMap<MultiKey,String>();
        List =  codesDAO.fetchGuiCodes();//fetches codes from DB

        for(CODES gui:List){
             multiKey = new MultiKey(gui.getCode(), gui.getKEY());
             map.put(multiKey,gui.getDESC());
        }
        return map;         
    }
}
4

5 回答 5

2

您可以将地图保存在静态字段中,并在static块中对其进行初始化。这种方式只执行一次:

public class Codes {
    private static Map<MultiKey, String> codes;
    static {
        CodesDAO codesDAO = new CodesDAO(); // DAO Class
        HashMap<MultiKey, String> map = new HashMap<MultiKey, String>();
        List<CODES> list = codesDAO.fetchGuiCodes();// fetches codes from DB
        for (CODES gui : list) {
            MultiKey multiKey = new MultiKey(gui.getCode(), gui.getKEY());
            map.put(multiKey, gui.getDESC());
        }
        codes = Collections.unmodifiableMap(map);
    }

    public static Map<MultiKey, String> fetchCodes() {
        return codes;
    }
}

然后您可以使用以下方法检索代码:

Codes.fetchCodes();
于 2013-04-02T13:09:26.793 回答
1

如果静态字段不是一个选项,您可以延迟初始化如下:

private HashMap<MultiKey, String> map = null;

public HashMap<MultiKey, String> fetchCodes() {

  if (map == null) {
    map = new HashMap<MultiKey, String>();
    list = codesDAO.fetchGuiCodes();// fetches codes from DB

    for (CODES gui : list) {
      MultiKey multiKey = new MultiKey(gui.getCode(), gui.getKEY());
      map.put(multiKey, gui.getDESC());
    }
  }
  return map;
}

注意:这不是线程安全的,但可能需要一些额外的同步。

于 2013-04-02T13:11:27.067 回答
0

可能只加载一次数据吗?使用番石榴的记忆(我会):

  Suppliers.memoize(//Implementation of Supplier<T>)
于 2013-04-02T13:06:22.223 回答
0

我不确定 OP 是如何设计他的 Java EE 应用程序的,以及是否使用了任何 3rd 方框架,但是在使用 EJB、CDI、JPA、事务等等的正确设计的标准 Java EE 应用程序中,数据库通常不是在静态上下文中可用。在这种情况下,建议静态初始化它的答案会严重误导和破坏。

规范的方法是只创建一个保存预初始化数据的实例,并在应用程序的整个生命周期中重复使用它。对于当前的 Java EE 标准,这可以通过在应用程序启动期间创建和初始化一次 bean 并将其存储在应用程序范围中来实现。例如,应用程序范围的 CDI bean:

@Named
@ApplicationScoped
public class Data {

    private List<Code> codes;

    @EJB
    private DataService service;

    @PostConstruct
    public void init() {
        codes = Collections.unmodifiableList(service.getAllCodes());
    }

    public List<Code> getCodes() {
        return codes;
    }

}

然后#{data.codes},应用程序中的其他任何地方都可以使用它。

于 2013-04-02T14:28:53.533 回答
0

如果您使用 Spring,您可以简单地声明一个 bean(单例)并实现 InitializingBean 接口。

您将被迫实现一个名为 afterPropertiesSet() 的方法并在那里加载您的地图。

如果你不使用 Spring,你可以像你一样在开始时初始化你的地图,然后把它放在 servletConext 中。此范围适用于所有会话。

这对于只读数据来说都是好事。如果您需要更新它,请小心,因为这不是线程安全的。你必须使它成为线程安全的。

希望有帮助

问候

于 2013-04-02T13:14:16.710 回答