最近终于用HIBERNATE+SPRING做了一个项目(之所以说终于是因为之前一直习惯于裸写),看到很多万能DAO的实现,于是心血来潮(主要也是为了项目开发效率),自己设计了一个DAO和Controller。
自认为写的比较好的几点:
1.将分页封装进DAO
/**
* 无查询条件的查询
* @param pages
* @param sort
* @return
*/
@SuppressWarnings("unchecked")
public ResultPages getAllByPageAndResult(SearchPages pages, Sort sort){
ResultPages result = new ResultPages();
result.setResultList(getAll(pages, sort));
result.setTotalCount(getAllCount());
return result;
}
/**
* 无查询条件的查询LIST
* @param pages
* @param sort
* @return
*/
@SuppressWarnings("unchecked")
public List<T> getAll(SearchPages pages, Sort sort) {
Criteria cta = getEntityCriteria();
cta = processPageAndSort(cta, pages, sort);
return cta.list();
}
/**
* 无查询条件的查询COUNT
* @return
*/
public Integer getAllCount(){
Criteria criteria = getEntityCriteria();
return (Integer)criteria.setProjection(Projections.rowCount()).uniqueResult();
}
其中的ResultPages, SearchPages, Sort 是我自定义的类型。
SearchPages里就page(当前第几页)和rows(每页多少条)两个属性。
Sort里就sort(排序属性)和order(ASC或者DESC)两个属性。
ResultPages也很简单,就是一个返回的LIST和条件查询结果总数。
2.
/**
* 根据MAP处理里面的LIKE查询条件
* @param searchMap
* @param cta
*/
public Criteria processCtaByLikeMap(Map<String, Object> searchMap, Criteria cta){
Iterator iter1 = searchMap.keySet().iterator();
while(iter1.hasNext()){
String key = (String)iter1.next();
Object value = searchMap.get(key);
if(value instanceof List){
}else{
cta.add(Restrictions.like(key, (String)value, MatchMode.ANYWHERE));
}
}
return cta;
}
从这里看不出来什么,再看我的Controller中的。
/**
* 将所有的查询条件组装成一个MAP
* @param req
* @param classzz
* @return
* @throws Exception
*/
protected Map<String, Object> getAllSearchMap(HttpServletRequest req, Class classzz, int searchType)throws Exception{
Map<String, Object> searchMap = new HashMap<String, Object>();
if(ProjectConfig.ONLY_ALL_SEARCH_LIKE == searchType){
searchMap = bindLikeSearch(req, classzz, searchMap);
}else if(ProjectConfig.ONLY_ALL_SEARCH_BETWEEN == searchType){
searchMap = bindBetweenSearch(req, classzz, searchMap);
}else if(ProjectConfig.SEARCH_ALL_LIKE_AND_BETWEEN == searchType){
searchMap = bindLikeSearch(req, classzz, searchMap);
searchMap = bindBetweenSearch(req, classzz, searchMap);
}
return searchMap;
}
/**
* 利用反射得到所有的对应查询条件
* @param req
* @param classzz
* @param srcMap
* @return
* @throws Exception
*/
private Map<String, Object> bindLikeSearch(HttpServletRequest req, Class classzz, Map<String, Object> srcMap)throws Exception{
Field[] fields = getAllField(classzz);
for(Field field:fields){
String searchKey = field.getName();
if((searchKey != null) && (searchKey.length() > 0)){
String searchValue = req.getParameter(searchKey);
if((searchValue != null) && (searchValue.length() > 0)){
srcMap.put(searchKey, processType(field.getType().getName(), searchValue));
}
}
}
return srcMap;
}
/**
* 利用反射得到所有的BETWEEN查询条件
* @param req
* @param classzz
* @param srcMap
* @return
* @throws Exception
*/
private Map<String, Object> bindBetweenSearch(HttpServletRequest req, Class classzz, Map<String, Object> srcMap)throws Exception{
Field[] fields = getAllField(classzz);
for(Field field:fields){
String searchKey = field.getName();
if((searchKey != null) && (searchKey.length() > 0)){
String searchMinValue = req.getParameter("between" + searchKey + "Min");
String searchMaxValue = req.getParameter("between" + searchKey + "Max");
if((searchMinValue != null) && (searchMinValue.length() > 0) &&
(searchMaxValue != null) && (searchMaxValue.length() > 0)){
List<Object> betweenList = new ArrayList<Object>();
betweenList.add(processType(field.getType().getName(), searchMinValue));
betweenList.add(processType(field.getType().getName(), searchMinValue));
srcMap.put(searchKey, betweenList);
}
}
}
return srcMap;
}
看到了吗,DAO里查询的MAP是通过这里来生成的。(现在只做了模糊查询和BETWEEN的查询)
这样的话,只要前台查询时和MODEL里的属性保持一致,就不用去做任何的操作了。这里有个processType是处理数据类型,返回正确数据的。getAllField是用来得到类的所有FILED(这里为了效率,加入了缓存)
/**
* 对类型处理,得到正确的类型对象
* @param typeName
* @param value
* @return
* @throws Exception
*/
protected Object processType(String typeName, String value)throws Exception{
if(typeName.equals("java.lang.String")){
return new String(value.getBytes("iso8859-1"), "utf-8");
}else if(typeName.equals("java.lang.Integer")){
return Integer.parseInt(value);
}else if(typeName.equals("java.lang.Float")){
return Float.parseFloat(value);
}else if(typeName.equals("java.util.Date")){
return Date.parse(value);
}else if(typeName.equals("java.lang.Double")){
return Double.parseDouble(value);
}else if(typeName.equals("java.lang.Long")){
return Long.parseLong(value);
}
return null;
}
/**
* 得到给定对象的所有FIELD,如果有缓存,则用,没有则直接反射
* 同时存入缓存
* @param classzz
* @return
*/
protected Field[] getAllField(Class classzz){
String className = classzz.getName();
Field[] fields = ReflectClassCacheManager.getInstance().getReflectClass(className);
if(fields == null){
fields = classzz.getDeclaredFields();
ReflectClassCacheManager.getInstance().addReflectClass(className, fields);
}
return fields;
}
呵呵,在项目中感觉还是比较好用的,欢迎大家指点。