есть ли решение повторно использовать код и не повторять (копировать-вставлять) код в каждом методе?
.
"Мясо"вашей функции здесь
Query query = session.createQuery("SELECT u FROM User u WHERE u.id=:id");
query.setString("id", id);
User user = (User) query.uniqueResult();
Если вы очень щурились, вы можете увидеть, что это «функция», которая принимает Session
в качестве аргумента и возвращает User
.Затем вы можете сделать эту функцию аргументом для функции, которая выполняет всю обработку исключений.
В Java это обычно означает выражение функции как «объекта»
User MyCrazyFunctionThing::uniqueResult(Session session) {
Query query = session.createQuery(this.sql);
query.setString("id", this.id);
return query.uniqueResult();
}
User DatabaseGateway::execute(MyCrazyFunctionThing q) {
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.getTransaction();
try {
tx.begin();
User user = q.uniqueResult(session)
tx.commit();
return user;
} catch (...) {
// ...
}
}
Сразу же вы можете превратить это в логику, которая может быть запущена в любое время, когда вы пытаетесь извлечь уникального пользователя из сеанса.
Вы можете сделать это еще более общим с помощью обобщений
interface MyCrazyGenericThing<T> {
T uniqueResult(Session session);
}
class MyCrazyFunctionThing implements MyCrazyGenericThing<User> {
User uniqueResult(Session session) {
Query query = session.createQuery(this.sql);
query.setString("id", this.id);
return query.uniqueResult();
}
}
<T> T DatabaseGateway::execute(MyCrazyGenericThing<T> q) {
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.getTransaction();
try {
tx.begin();
T result = q.uniqueResult(session)
tx.commit();
return result;
} catch (...) {
// ...
}
}
То, что вы видите здесь, - это шаблон стратегии, используемый для указания того, какой код должен выполняться внутри логики транзакции.