系统当中有很多位置需要下拉列表,每一次需要下拉列表都要从数据库中查询吗?有没有什么好的方案?
答:
下拉列表中的数据有这样的几个特点:
第一:数据量较小
第二:所有用户共享
第三:一般不会轻易的修改
当满足以上的三个条件的时候,可以考虑将其存储到application域当中。
application域可以看做是一个缓存:cache。
使用缓存机制,减少IO操作,是提高程序执行效率的重要手段。
在实际开发中,遇到优化瓶颈的时候,首先要想到缓存机制。
将字典值查询出来,存储到一个什么样数据结构当中,application域当中存储什么?
application.setAttribute("appellationList" , appellationList);
application.setAttribute("clueStateList" , clueStateList);
.....
<c:forEach items="${appellationList}" var="字典值对象">
<option value="${字典值对象.value}">${字典值对象.text}</option>
</c:forEach>
写一个监听器,在服务器启动阶段,调用service返回一个Map集合,然后遍历Map集合,将数据存储到application域当中。
Map<String,List<DicValue>>
key value
----------------------------------------
"appellationList" appellationList
"clueStateList" clueStateList
以下是监听器:
package com.wkcto.crm.web.listener;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.wkcto.crm.settings.domain.DicValue;
import com.wkcto.crm.settings.service.DicValueService;
import com.wkcto.crm.settings.service.impl.DicValueServiceImpl;
import com.wkcto.crm.utils.TransactionHandler;
public class SystemInitListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("-----------------------------------System Init Begin!---------------------------------------------");
ServletContext application = sce.getServletContext();
// 调用service获取所有的字典值
DicValueService dvs = (DicValueService)new TransactionHandler(new DicValueServiceImpl()).getProxy();
Map<String,List<DicValue>> dvMap = dvs.getAll();
Set<String> keys = dvMap.keySet();
for(String key : keys){
application.setAttribute(key, dvMap.get(key));
}
// 读取资源文件
ResourceBundle bundle = ResourceBundle.getBundle("com.wkcto.crm.resources.Stage2Possibility");
Enumeration<String> keys2 = bundle.getKeys();
Map<String,String> pMap = new HashMap<>();
while(keys2.hasMoreElements()){
String key = keys2.nextElement();
String value = bundle.getString(key);
pMap.put(key, value);
}
application.setAttribute("pMap", pMap);
System.out.println("-----------------------------------System Init Over!---------------------------------------------");
}
}
业务层代码:
package com.wkcto.crm.settings.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.wkcto.crm.settings.dao.DicTypeDao;
import com.wkcto.crm.settings.dao.DicValueDao;
import com.wkcto.crm.settings.domain.DicType;
import com.wkcto.crm.settings.domain.DicValue;
import com.wkcto.crm.settings.service.DicValueService;
import com.wkcto.crm.utils.SqlSessionUtil;
public class DicValueServiceImpl implements DicValueService {
private DicValueDao dvd = SqlSessionUtil.getCurrentSqlSession().getMapper(DicValueDao.class);
private DicTypeDao dtd = SqlSessionUtil.getCurrentSqlSession().getMapper(DicTypeDao.class);
@Override
public boolean checkValueUniqueByTypeCode(String typeCode, String value) {
return dvd.getByValueAndTypeCode(typeCode , value) == null;
}
@Override
public boolean save(DicValue dv) {
return dvd.save(dv) == 1;
}
@Override
public Map<String, List<DicValue>> getAll() {
Map<String, List<DicValue>> dvMap = new HashMap<>();
// 获取所有的字典类型
List<DicType> dtList = dtd.getAll();
// 遍历字典类型,取出code
for(DicType dt : dtList){
String code = dt.getCode();
List<DicValue> dvList = dvd.getByTypeCode(code);
dvMap.put(code + "List", dvList);
}
return dvMap;
}
}