java - 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()。其余部分代码与此处类似。我如何重构这段代码来简化它?
解决方案
对于称为模板方法的模式,这是一个非常好的用例。
例如,您可以创建一个抽象类,它将所有样板代码包装在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 “贷款”实体管理器以使用它来执行某种操作,但它处理所有其他事情,例如创建对象或关闭连接。
推荐阅读
- node.js - SendGrid NodeJS - Client.request() 不是函数
- javascript - 如何创建一个查找 URL 的页面并创建一个引用该 URL 的文本?
- google-apps-script - Google 应用程序脚本 gmail 线程和线程行为中的消息
- python - 根据组标准 pandas 在组中删除值
- ionic-framework - 进行更改,保存,但 cordova 运行以前的代码
- java - 用户界面(UI)作为springboot中的不同微服务
- sql-server - SQL Server - 从选择创建文本表
- xcode - 在 Android Studio 和 Xcode 中运行 Flutter 应用程序时出错
- azure - 流分析查询(选择 * 进入输出)(排除特定列)
- html - css - 如果浏览器对齐 div 以占据全高