首页 > 解决方案 > Hibernate JPA 简化了 update()、delete()、add() 的代码

问题描述

我创建了使用 JPA 的 update() 方法。它看起来像这样:

public boolean update(Programy program) throws Exception {
        try {
            entityManagerFactory = Persistence.createEntityManagerFactory("firebird_config_file");
            entityManager = entityManagerFactory.createEntityManager();

            entityManager.getTransaction().begin();
            entityManager.merge(program);
            entityManager.getTransaction().commit();

            entityManager.close();
            entityManagerFactory.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

在我的 save() 和 delete 方法中,我只更改一件事 - merge() -> persist() 或 delete()。其余部分代码与此处类似。我如何重构这段代码来简化它?

标签: javahibernatejparefactoring

解决方案


对于称为模板方法的模式,这是一个非常好的用例。

例如,您可以创建一个抽象类,它将所有样板代码包装在perform方法中:

abstract public class HibernateAction<T> {
    private EntityManagerFactory entityManagerFactory;
    //I'm passing EntityManagerFactory, because it should be singleton and you shouldn't
    //probably create it from scratch everytime
    public HibernateAction(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    protected abstract T action(EntityManager entityManager, T entity);

    public boolean perform(T entity) throws Exception {
        try {
            var entityManager = entityManagerFactory.createEntityManager();
            entityManager.getTransaction().begin();
            action(entityManager, entity); //call to action which need to be overriden
            entityManager.getTransaction().commit();
            entityManager.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }   
    }
}

那么你可以创建一个继承的类HibernateAction

public class UpdateAction extends HibernateAction<Program> {

    public UpdateAction(EntityManagerFactory entityManagerFactory) {
        super(entityManagerFactory);
    }

    @Override
    protected Program action(EntityManager entityManager, Program entity) {
        return entityManager.merge(entity);
    }
}

最后你可以像这样使用它:

public boolean update(Program program) throws Exception {
    return updateAction.perform(program);
}

但是由于 Java 支持匿名方法(自 Java 8 起),您也可以使用高阶函数以稍微不那么冗长的方式重写它:

public class HibernateAction2{ // no longer abstract

    private EntityManagerFactory entityManagerFactory;

    public HibernateAction2(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    //we expect a user to pass lambda function, which would tell us what to do with an entity manager
    public boolean perform (Consumer<EntityManager> action) throws Exception {
        try {
            var entityManager = entityManagerFactory.createEntityManager();
            entityManager.getTransaction().begin();
            action.accept(entityManager);
            entityManager.getTransaction().commit();
            entityManager.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

然后你可以像这样使用它:

hibernateAction2.perform(em -> em.merge(program)); //for merge

hibernateAction2.perform(em -> em.persist(program)); //for persist, etc.

这称为贷款模式贷款模式(或FP 语言中的括号),因为您从 hibernateAction2 “贷款”实体管理器以使用它来执行某种操作,但它处理所有其他事情,例如创建对象或关闭连接。


推荐阅读