【问题标题】:Fetching Entities from DB in a PropertyEditor在 PropertyEditor 中从数据库中获取实体
【发布时间】:2011-08-01 09:41:11
【问题描述】:

在 Spring MVC 中使用 PropertyEditor 时让它们从数据库中获取实体是不是很糟糕?我是否应该创建一个空实体并设置其 ID。

例如实体Employee:

@Entity
@Table(name = "employee")
public class Employee implements GenericEntity<Integer>{

    @Id
    @GeneratedValue
    @Column(name = "employee_id")
    public Integer getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;
    }

    /** More properties here **/
}

使用以下 GenericEntityEditor 在下面的 PropertyEditor 中获取实体是不是一个坏主意:

public class GenericEntityEditor<ENTITY extends GenericEntity<Integer>> extends PropertyEditorSupport {

    private GenericDao<ENTITY, Integer> genericDao;

    public GenericEntityEditor(GenericDao<ENTITY, Integer> genericDao) {
        this.genericDao = genericDao;
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        setValue(genericDao.findById(Integer.valueOf(text)));
    }

    @SuppressWarnings("unchecked")
    @Override
    public String getAsText() {
        ENTITY entity = (ENTITY) getValue();
        if(entity == null) {
            return null;
        } 

        return String.valueOf(entity.getId());
    }
}

可以在控制器中绑定的:

@Controller
public class EmployeeController {
    /** Some Service-layer resources **/

    @Resource
    private EmployeeDao employeeDao; // implements GenericDao<ENTITY, Integer> genericDao

    @SuppressWarnings("unchecked")
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Employee.class, new GenericEntityEditor(employeeDao));
    }

    /** Some request mapped methods **/

}

是否更倾向于对 EmployeeEditor 使用更具体的方法,让它只实例化一个 Employee 实体并设置其 id:

public class EmployeeEditor extends PropertyEditorSupport {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        Employee employee = new Employee();
        employee.setId(Integer.valueOf(text));
    }

    @SuppressWarnings("unchecked")
    @Override
    public String getAsText() {
        Employee employee = (Employee) getValue();
        if(employee == null) {
            return null;
        } 

        return String.valueOf(employee.getId());
    }
}

这样我们就不会每次在表单上存在员工时都往返于数据库,但我不确定这是否与 Hibernate 一样正常工作?

【问题讨论】:

    标签: java spring hibernate spring-mvc


    【解决方案1】:

    我认为这是合法的。这个技术我用了一段时间,效果很好。

    但是 Spring 3.0 有一个更好的概念。所谓Converter(参考章节5.5 Spring 3 Type Conversion

    此转换器的工作方式类似于单向属性编辑器。但是它们是无状态的,并且由于这种性能更高,并且可以重复使用!


    添加: Spring 3.0.>3 有一个not (yet) documented 特性:org.springframework.core.convert.support.IdToEntityConverter

    ConcersationServiceFactory 自动在 ConversationService 中注册。

    这个 IdToEntityConverter 会自动将一切(对象)转换为实体,如果实体!有一个静态方法find&lt;entityName&gt;,它有一个参数,返回类型是实体的类型。

    /**
     * Converts an entity identifier to a entity reference by calling a static finder method
     * on the target entity type.
     *
     * <p>For this converter to match, the finder method must be public, static, have the signature
     * <code>find[EntityName]([IdType])</code>, and return an instance of the desired entity type.
     *
     * @author Keith Donald
     * @since 3.0
     */
    

    如果您怀疑如何在您的实体中实现这样的静态查找器方法。然后看看 Spring Roo 生成的实体。

    【讨论】:

    • 一如既往的好答案(+1),但你不断地发明单词(执行,重用)。你知道大多数浏览器都有拼写检查器吗? :-)
    • @Sean Patrick Floyd:我的浏览器拼写检查器用于德语。但我想我应该把它改成英文。
    • 我建议您这样做,因为您的德语拼写比英语拼写好很多。或者只为 SO 使用专用浏览器 :-)
    • 谢谢!很好的答案@Ralph。我们目前使用的是 Spring 2.5.6,但我已经尝试过使用 3.0.5,并且在进行此升级时似乎没有什么问题,因此这是进行切换的另一个原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 2015-08-18
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多