【发布时间】: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。如果没有缓存元素,我正在创建一个,然后向它添加数据。直到这里看起来不错。但是当我添加然后获取时,它给了我空指针和这就是问题