在Spring MVC(泛型,反射或其他)中处理通用实体的最佳方法是什么?

时间:2012-06-18 12:02:35

标签: java spring hibernate spring-mvc

我有一个名为Commercial的实体。我有一个类别实体,其中包含商业类别列表。对于每个类别,都有一个单独的实体扩展商业(如RestaurantCommercial,PhotoStudioCommercial等总计多达20个实体)和JOINED继承策略。

商业实体拥有某些公司商业的标题,文本联系人数等一般属性,而RestaurantCommercial和PhotoStudioCommercial持有与该类别相关的其他特定属性。

问题是为每个实体编写一个单独的dao和控制器有点大量的工作,所以我正在寻找一种巧妙的方法来处理这个问题。

我需要一个统一的控制器,可能是DAO,用于处理表单控件和持久化扩展商业实体的新实例。

这是我正在考虑的内容:

@RequestMapping(value={"/vendor/commercial/{categoryName}/new"}, method=RequestMethod.GET)
public String showNewCommercialForm(@PathVariable("categoryName") String categoryName,
                                    Map<String, Object> map) {
    Category category = categoryDAO.getCategoryByServiceName(categoryName);

    Class clazz = Class.forName(category.getClassName()); //here className is smth like domain.commercial.RestaurantCommercial

    map.put("commercialInstance", clazz.newInstance());
    //separate view for each category of commercial
    return "vendor/commercial/"+categoryName+"/new";
}

我正在考虑使用类似的控制器来保存表单数据,即使我必须为这些东西编写sperate binder。

所以问题是:如果你已经遇到过类似的需求(Generics,Reflection或者其他),你会建议你处理这个问题或者最佳做法是什么?或者,如果这是值得的,为什么? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

我为这种情况创建了一个Dao界面:

public interface Dao<T extends Commercial> {

    T getAll();
}

之后是一个抽象的Dao实现,例如基于hibernate:

public CommonHibernateDao<T extends Commercial> implements Dao<T> 
{
    private final Class<T> entityType;

    protected CommonHibernateDao(Class<T> entityType) {
        this.entityType = entityType;
    }

    public List<T> getAll() {
        // hibernate get all implementation
    }
}

和RestaurantCommercial Dao的界面和实施:

public interface RestaurantCommercialDao extends Dao<RestaurantCommercial> {

}

public class HibernateRestaurantCommercialDao extends CommonHibernateDao<RestaurantCommercial> implements RestaurantCommercialDao {

    public HibernateRestaurantCommercialDao() {
        super(RestaurantCommercial.class);
    }
}

所有实现goto CommonHibernateDao。在它的子类中只有构造函数调用neaded。基本上你可以用反射来做,但对我来说还不清楚。

对于控制器(类似RESTfull API):

@Controller
public class YourController() {

    @RequestMapping(value = "/restapi/{entityType}")
    public String postEntity(HttpServletRequest request, @PathVariable(value = "entityType") String entityType) {
        // If enetity name will be packegae + class name
        Object beanInstance = Class.forName(entityName);
        ServletRequestDataBinder binder = new ServletRequestDataBinder(beanInstance);
        binder.bind(request);

        // Here by type of entity you can get DAO and persist
    }
}

如果表单输入名称与bean名称相同 - 绑定将自动完成。