【问题标题】:Ehcache - Not fetching value from CacheEhcache - 不从缓存中获取值
【发布时间】:2015-08-23 10:05:31
【问题描述】:

我正在寻找一些将 ehcache 与 dao 一起使用的示例(我不使用任何框架,它的自定义 jdbc dao)我有一堆 dao,我需要缓存它们,因为它们的值不会经常更改。

我在 dao 中以列表的形式获取数据,如何将这些数据放入缓存中并检索它?我们通常将缓存类放在DAO实现类还是控制器类中?我只想在缓存中找不到项目时才调用 db,所以我认为 dao 类最适合它。感谢对此的一些想法。

好的,我有一些带有 ehcache 的游乐场代码,但由于某些原因,它永远不会进入缓存层来获取值。

这是我的 dao 代码,我知道它从 db 获取值。

public class GetCitiesbyStateCode {

    private static final Logger logger = LogManager.getLogger(GetCitiesbyStateCode.class);
    private Connection dbConnection = null;
    ResultSet rs;

    public GetCitiesbyStateCode() throws SQLException {

        try {
            dbConnection = CreateConnection.getConnection();
        } catch (Exception e) {
            logger.error("Error getting DB Connection" + e);
        }

    }
//SELECT Distinct(city) FROM `cities_extended` WHERE state_code='AL' 

    public List<BnGetCitiesbyStateCodeBn> GetCitiesbyStateCode(String state_code) throws SQLException {
        List<BnGetCitiesbyStateCodeBn> citiesDAO = new LinkedList<>();
        if (dbConnection != null) {
            Statement stmt = dbConnection.createStatement();
            try {
                logger.info("state code in dao class is " + state_code);
                try {
                    rs = stmt.executeQuery("select Distinct city,state_code from cities_extended WHERE state_code ='" + state_code + "'");
                } catch (SQLException ex) {
                    logger.error("SQL Exception executing query" + ex);
                }
                while (rs.next()) {
                    BnGetCitiesbyStateCodeBn city = new BnGetCitiesbyStateCodeBn();
                    city.setCity(rs.getString("city"));
                    city.setState_code(rs.getString("state_code"));                                   
                    citiesDAO.add(city);
                  }
            } catch (SQLException | IllegalArgumentException | IllegalStateException e) {
                logger.error("Error retreving Cities " + e);
            }                 
     }
        return citiesDAO;

    }

}

这是我的缓存服务层,(这段代码永远不会从缓存中获取值,每次调用都去db,所以我需要有人来看看这个类),

我正在使用 db 中的此代码检索近 1000 个城市,ehcache xml 如下所示,

 <cache name="citiesCache"  maxEntriesLocalHeap="1000" eternal="true"  memoryStoreEvictionPolicy="FIFO"> </cache>

公共类 CitiesServicesEhCache {

private static final Logger logger = LogManager.getLogger(CitiesServicesEhCache.class);

public List<BnGetCitiesbyStateCodeBn> getcities(String state_code) throws Exception {
    logger.info("State Code from request at Cache service is " + state_code);
    List<BnGetCitiesbyStateCodeBn> CacheCities = new LinkedList<>();
//    BnGetCitiesbyStateCodeBn CacheCities = null;
    Cache cache = EhCacheManager.getCache();
    Element element = cache.get(CacheCities);
    if (element == null) {
        logger.info("Missed the Cache");
        GetCitiesbyStateCode citiesDao = new GetCitiesbyStateCode();
        try {
            CacheCities = citiesDao.GetCitiesbyStateCode(state_code);
        } catch (SQLException ex) {
            logger.error("Got the SQL Exception" + ex);
        }
        try {
            cache.put(new Element(CacheCities,CacheCities));
        } catch (IllegalArgumentException | IllegalStateException | CacheException ex) {
            logger.error("Failed to put object in cache" + ex);
        }
    } else {
        logger.info("I hit Cache layer");
        CacheCities =  (List<BnGetCitiesbyStateCodeBn>) element.getObjectValue();
    }

    return CacheCities;
}

}

这是我的 Struts 2 动作类。实际上,这段代码是为了让我开始在我的应用程序上获取缓存,因此在我实际在我的应用程序上实现代码之前,它更像是测试我的代码的游乐场。

public class S2 extends ActionSupport {

    private static final long serialVersionUID = 5686197289029560661L;
    private static final Logger logger = LogManager.getLogger(S2.class);
    private String state_code;
    private String t;
    private List <BnGetCitiesbyStateCodeBn> cities;

//    private static final String EHCACHE_CONFIG = "src/main/resources/ehcache.xml";
//    private static final String CACHE_NAME = "citiesCache";
//    CacheManager manager = new CacheManager(EHCACHE_CONFIG);
//    Ehcache cache = manager.getCache(CACHE_NAME);

    public S2() {

    }

    /**
     * @param state_code the state_code to set
     */
    public void setState_code(String state_code) {
        this.state_code = state_code;
    }

    /**
     * @return the t
     */
    public String getT() {
        return t;
    }

    /**
     * @param t the t to set
     */
    public void setT(String t) {
        this.t = t;
    }

       /**
     * @return the state_code
     */
    public String getState_code() {
        logger.info("State code is " + state_code);
        return state_code;
    }

    @Override
    public String execute() {
//        try {
//            GetCitiesbyStateCode citydao = new GetCitiesbyStateCode();
//            cities = citydao.GetCitiesbyStateCode(state_code);
//        } catch (SQLException ex) {
//            logger.error(ex);
//        }
        CitiesServicesEhCache service = new CitiesServicesEhCache();
        try {
            cities = service.getcities(state_code);
        } catch (Exception e) {
            logger.error("Got the Exception" + e);
        }       
        return "success";
    }

    /**
     * @return the cities
     */
    public Object getCities() {
        return cities;
    }

    /**
     * @param cities the cities to set
     */
    public void setCities(Object cities) {
        this.cities = (List<BnGetCitiesbyStateCodeBn>) cities;
    }



}

这是我的模型/实体类,

public class BnGetCitiesbyStateCodeBn implements Serializable {
    private String city;
    private String state_code;


    /**
     * @return the city
     */
    public String getCity() {
        return city;
    }

    /**
     * @param city the city to set
     */
    public void setCity(String city) {
        this.city = city;
    }

    /**
     * @return the state_code
     */
    public String getState_code() {
        return state_code;
    }

    /**
     * @param state_code the state_code to set
     */
    public void setState_code(String state_code) {
        this.state_code = state_code;
    }
   @Override
    public String toString() {
        return "BnGetCitiesbyStateCodeBn [city=" + city + ", state_code=" + state_code + "]";
    }

}

这是我用来检查缓存统计信息的代码,我可以看到它将数据添加到缓存中,但不幸的是它添加了两次而不是一次,所以我需要一些眼睛来看看我的 put 操作有什么问题,为什么是不是添加了两次,甚至一次都没有从缓存中获取。请任何人。

@WebServlet(name = "GetCacheStats", urlPatterns = {"/GetCacheStats"})
public class GetCacheStats extends HttpServlet {

    Cache cache = EhCacheManager.getCache();
    SampledCache sampledCache;

    public GetCacheStats() throws NotCompliantMBeanException {
        this.sampledCache = new SampledCache(cache);
    }

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet GetCacheStats</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1> Size of Cache: " + cache.getSize() + "</h1>");
            out.println("<h1> Cache Status: " + cache.getStatus() + "</h1>");
            out.println("<h1> Name of cache is " + cache.getName() + "</h1>");
            out.println("<h1> Guid of cache: " + cache.getGuid() + "</h1>");
            out.println("<h1> Cache put count is : " + sampledCache.getPutCount() + "</h1>");
            out.println("<h1> Cache missed count is: " + sampledCache.getCacheMissCount() + "</h1>");
            out.println("<h1> Cache Hit count is: " + sampledCache.getCacheHitCount() + "</h1>");
//            out.println("<h1> getMemoryStoreEvictionPolicy()  at " +   cache.getKeysNoDuplicateCheck() + "</h1>");
//            out.println("<h1> getKeysWithExpiryCheck()  at " +   cache.getKeysWithExpiryCheck() + "</h1>");
            out.println("<h1> GetKeys : " + cache.getKeys() + "</h1>");

            out.println("</body>");
            out.println("</html>");
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Servlet to get Ehcache Cache Stats";
    }// </editor-fold>

}

【问题讨论】:

  • 如果使用none框架,在dao中做,先检查缓存,如果没有找到,调用jdbc放入缓存。
  • Thorynque 先生,我添加了一些代码,请检查为什么我没有从缓存层获取值。它总是错过缓存。
  • 你做错了,缓存是一个对象的集合,用于在发出请求时替换真实的对象。但你没有使用这种东西。
  • 你能详细说明一下 Roman。如果没有缓存元素,我正在创建一个,然后向它添加数据。直到这里看起来不错。但是当我添加然后获取时,它给了我空指针和这就是问题

标签: java jdbc struts ehcache


【解决方案1】:

如果您没有使用缓存中的 get 方法获取数据,只需将“implements Serializable”添加到您存储数据的自定义类中即可。

【讨论】:

    【解决方案2】:

    在 DAO 中

    公共类 GetCitiesbyStateCode {

    private static final Logger logger =        LogManager.getLogger(GetCitiesbyStateCode.class);
    private Connection dbConnection = null;
    ResultSet rs;
    

    缓存缓存; 公共 GetCitiesbyStateCode() 抛出 SQLException {

        try {
            dbConnection = CreateConnection.getConnection();
            cache = EhCacheManager.getCache("citiesCache");
    
        } catch (Exception e) {
            logger.error("Error getting DB Connection" + e);
        }
    
    }
    

    //SELECT Distinct(city) FROM cities_extended WHERE state_code='AL'

    public List<BnGetCitiesbyStateCodeBn> GetCitiesbyStateCode(String state_code) throws SQLException {
        //check cache first
        Element el = cache.get(state_code);
        if (el != null){
           return el.getObjectValue();
        }
        List<BnGetCitiesbyStateCodeBn> citiesDAO = new LinkedList<>();
        if (dbConnection != null) {
            Statement stmt = dbConnection.createStatement();
            try {
                logger.info("state code in dao class is " + state_code);
                try {
                    rs = stmt.executeQuery("select Distinct city,state_code from cities_extended WHERE state_code ='" + state_code + "'");
                } catch (SQLException ex) {
                    logger.error("SQL Exception executing query" + ex);
                }
                while (rs.next()) {
                    BnGetCitiesbyStateCodeBn city = new BnGetCitiesbyStateCodeBn();
                    city.setCity(rs.getString("city"));
                    city.setState_code(rs.getString("state_code"));                                   
                    citiesDAO.add(city);
                  }
            } catch (SQLException | IllegalArgumentException | IllegalStateException e) {
                logger.error("Error retreving Cities " + e);
            }                 
     }
      cache.set(state_code,citiesDAO);
        return citiesDAO;
    
    }
    

    }

    管理异常,仅此而已

    【讨论】:

    • 感谢 Thorynque 的回复。所以基本上你希望我首先在 DAO 类中检查缓存,然后将我的缓存代码移动到 DAO。之前我有单独的缓存和 dao 类,我用它来进行检查。我可以改变它。让我检查并回来。谢谢
    猜你喜欢
    • 2023-03-15
    • 2018-10-26
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多