2012-07-28 131 views
0

我想修剪我的代碼,只使用一個函數進行過濾。 過濾應該使用3個不同的類:com.example.model.Category,com.example.model.Tag,java.util.Calendar。Spring中的泛型控制器/服務/存儲庫

這裏是我的控制器

@Controller 
@RequestMapping("/blog") 
public class BlogController 
{ 
    @Autowired 
    private ArticleService articleService; 

    @Autowired 
    private CategoryService categoryService; 

    @Autowired 
    private TagService tagService; 

    private static final int PER_PAGE = 5; 

    private static final int ARCHIVE_MONTHS = 12; 

    @ModelAttribute 
    public void addGlobalObjects(Map<String, Object> map) 
    { 
     map.put("section", "blog"); 

     SortedMap<Category, Integer> categories = new TreeMap<Category, Integer>(); 
     for (Category category : categoryService.list()) 
     { 
      categories.put(category, articleService.size(category, Category.class)); 
     } 

     Calendar cal = Calendar.getInstance(); 
     cal.set(Calendar.DAY_OF_MONTH, 1); 

     cal.add(Calendar.MONTH, ARCHIVE_MONTHS * -1); 

     SortedMap<Date, Integer> archive = new TreeMap<Date, Integer>(); 
     for (int i = 0; i < ARCHIVE_MONTHS; ++i) 
     { 
      cal.add(Calendar.MONTH, 1); 
      archive.put(cal.getTime(), articleService.size(cal, Calendar.class)); 
     } 

     SortedMap<Tag, Integer> tags = new TreeMap<Tag, Integer>(); 
     for (Tag tag : tagService.list()) 
     { 
      tags.put(tag, articleService.size(tag, Tag.class)); 
     } 

     map.put("categories", categories); 
     map.put("archive", archive); 
     map.put("tags", tags); 

     map.put("categoriesSize", categoryService.size()); 
     map.put("tagsSize", tagService.size()); 

     map.put("date", new Date()); 
    } 

    @RequestMapping("/index.html") 
    public String index(HttpServletRequest request, Map<String, Object> map) 
    { 
     return list(request, map, null, null); 
    } 

    @RequestMapping("/archive/{date}.html") 
    public String archive(@PathVariable("date") @DateTimeFormat(iso = ISO.DATE, style = "yyyy/MM") Date date, HttpServletRequest request, Map<String, Object> map) 
    { 
     Calendar cal = Calendar.getInstance(); 
     cal.setTime(date); 

     return list(request, map, cal, Calendar.class); 
    } 

    private <T> String list(HttpServletRequest request, Map<String, Object> map, Object filterObject, Class<T> clazz) 
    { 
     int page = ServletRequestUtils.getIntParameter(request, "page", 1); 
     map.put("articles", articleService.list(page * PER_PAGE - PER_PAGE, PER_PAGE, filterObject, clazz)); 
     map.put("numPages", Math.ceil(articleService.size()/PER_PAGE)); 
     map.put("currentPage", page); 
     return "articles"; 
    } 
} 

在我ArticleDAO我現在需要實現方法列表/尺寸:

@Repository 
public class ArticleDAO extends BaseDAO<Article> 
{ 
    public <T> List<Article> list(int offset, int limit, Object filterObject, Class<T> clazz) 
    { 
     Criteria c = doFilter(filterObject, clazz); 

     if (limit > 0) 
     { 
      c.setFirstResult(offset); 
      c.setMaxResults(limit); 
     } 

     return c.list(); 
    } 

    public <T> Integer size(Object filterObject, Class<T> clazz) 
    { 
     Number ret = (Number) doFilter(filterObject, clazz).setProjection(Projections.rowCount()).uniqueResult(); 
     return ret.intValue(); 
    } 

    private <T> Criteria doFilter(Object filterObject, Class<T> clazz) 
    { 
     Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Article.class); 

     if (filterObject != null && clazz != null) 
     { 
      T filter = clazz.cast(filterObject); 

      if (filter instanceof Calendar) 
      { 
       // The method set(int, int) is undefined for the type T 
       filter.set(Calendar.DAY_OF_MONTH, 1); 
       filter.set(Calendar.HOUR_OF_DAY, 0); 
       filter.set(Calendar.MINUTE, 0); 
       filter.set(Calendar.SECOND, 0); 
       // The method getTime() is undefined for the type T 
       Date d1 = filter.getTime(); 

       // The method getActualMaximum(int) is undefined for the type T 
       filter.set(Calendar.DAY_OF_MONTH, filter.getActualMaximum(Calendar.DAY_OF_MONTH)); 
       filter.set(Calendar.HOUR_OF_DAY, 23); 
       filter.set(Calendar.MINUTE, 59); 
       filter.set(Calendar.SECOND, 59); 
       Date d2 = filter.getTime(); 

       criteria.add(Restrictions.between("creationDate", d1, d2)); 
      } 

      if (filter instanceof Category) 
      { 
       // The method getId() is undefined for the type T 
       criteria.createCriteria("categories").add(Restrictions.eq("id", filter.getId())); 
      } 

      if (filter instanceof Tag) 
      { 
       // The method getId() is undefined for the type T 
       criteria.createCriteria("tags").add(Restrictions.eq("id", filter.getId())); 
      } 
     } 

     return criteria; 
    } 
} 

如何ArticleDAO.doFilter應該是什麼樣子?我想我不明白泛型的東西。

回答

2

我不認爲仿製藥在這裏購買任何東西。這甚至不會編譯b/c T是不知道的,你正試圖調用特定的方法(例如getId())。

有幾種方法可以做到這一點沒有泛型。最簡單的方法是

if (filterObject instanceof Calendar) { 
    Calendar filterCal = (Calendar) filterObject; 

    filterCal.set (Calendar.DAY_OF_MONTH, 1); // ... and so on 

如果你這樣做,你可以從你的方法中刪除clazz參數。你不需要clazz.cast()調用。

就泛型而言,當我在做同樣的事情時,無論類型如何,我都會發現自己使用泛型。例如,看起來您正在爲您的BaseDAO成功使用泛型。無論類型如何,BaseDAO都會保存,更新,刪除等等。在上面的例子中,您嘗試根據類型做一些不同的事情。它並不適用於泛型。事實上,每種類型做不同的事情通常意味着你可以用多態來很好地完成它。

相關問題