我在大量方法中出现了以下大量的页眉和页脚代码。有没有更清晰的方法来实现这个?
Session sess = factory.openSession();
Transaction tx;
try {
tx = sess.beginTransaction();
//do some work
...
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
sess.close();
}
有问题的类实际上是一个EJB 2.0 SessionBean,它看起来像:
public class PersonManagerBean implements SessionBean {
public void addPerson(String name) {
// boilerplate
// dostuff
// boilerplate
}
public void deletePerson(Long id) {
// boilerplate
// dostuff
// boilerplate
}
}
答案 0 :(得分:6)
如果您可以将// do some work
放入策略模式中,则可以创建一个包含样板代码的方法,将该操作作为参数传递;
void executeWork(WorkInterface work) {
Session sess = factory.openSession();
Transaction tx;
try {
tx = sess.beginTransaction();
work.execute();
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
sess.close();
}
只要您不必将许多参数传递到execute()
方法,此模式就适合。
答案 1 :(得分:2)
您可以引入一个抽象类来收集所有这些样板文件。优点:避免不必要的代码重复。这是一种方法:
public abstract AbstractBase {
public void doSomthing() {
Session sess = factory.openSession();
Transaction tx;
try {
tx = sess.beginTransaction();
doStuff();
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
sess.close();
}
}
public abstract void doStuff();
}
您的实现只是将AbstractBase
子类化并实现doStuff()
方法
答案 2 :(得分:1)
private void withTransactedSession(Runnable runnable)
{
Session sess = factory.openSession();
Transaction tx;
try {
tx = sess.beginTransaction();
runnable.run();
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
sess.close();
}
}
...
withTransactedSession(new Runnable()
{
public void run()
{
//do some work
...
}
});
如果您需要抛出特定的例外情况,可以使用自己的界面而不是Runnable
。
答案 3 :(得分:0)
您可能需要以下内容:
final Session sess = factory.openSession();
try {
boolean committed = false;
final Transaction tx = sess.beginTransaction();
try {
//do some work
...
tx.commit();
committed = true;
} finally {
if (!committed) {
tx.rollback();
}
}
} finally {
sess.close();
}
无论出现什么异常,我都可以自由回滚,并避免了关于要声明哪些已检查异常的问题。正如Vincent和Robert的回答所提到的那样,使用Execute Around成语可以让你编写一次代码(虽然它仍然非常冗长)。