#java #hibernate #oop #generics #code-duplication
#java #спящий режим #ооп #общие сведения #дублирование кода
Вопрос:
Идея:
Когда я использовал hibernate, я видел, что каждый раз мне приходилось писать какой-то код. Поэтому я переместил их в другой метод в качестве оболочки. Где в качестве аргумента будет функциональный интерфейс, чтобы я мог добавить некоторый код в эти контекстные методы.
Проблема:
Вот мои два метода. Один возвращает объект, а другой возвращает список. Как я могу точно обобщить и объединить эти два метода в один, чтобы избежать дублирования кода.
public Object objectReturnContext(Function<Session, Object> function) {
Object object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
public List<T> listReturnContext(Function<Session, List<T>> function) {
List<T> object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
Для лучшего понимания, это весь мой класс. Если кто-нибудь может посоветовать мне какой-либо лучший способ, я буду очень благодарен. Я занимался этим последние несколько дней.
package com.go_task.database;
import javax.persistence.Table;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import javax.persistence.NoResultException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public abstract class QueryExecutionContext <T> {
public Class<T> entity;
public String tableName;
public QueryExecutionContext(Class<T> entity) {
this.entity = entity;
this.tableName = entity.getAnnotation(Table.class).name();
}
public List<T> criteriaContext(CriteriaContextRunner<Session, Root<T>,
CriteriaQuery<T>, CriteriaBuilder, List<T>> runner) {
List<T> data = new ArrayList<>();
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery =
criteriaBuilder.createQuery(entity);
Root<T> root = criteriaQuery.from(entity);
data = runner.apply(session, root, criteriaQuery, criteriaBuilder);
transaction.commit();
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return data;
}
public Object singleCriteriaContext(CriteriaContextRunner<Session, Root<T>,
CriteriaQuery<T>, CriteriaBuilder, Object> runner) {
Object data = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery =
criteriaBuilder.createQuery(entity);
Root<T> root = criteriaQuery.from(entity);
data = runner.apply(session, root, criteriaQuery, criteriaBuilder);
transaction.commit();
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return data;
}
public Object objectReturnContext(Function<Session, Object> function) {
Object object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
public List<T> listReturnContext(Function<Session, List<T>> function) {
List<T> object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
public void noReturnContext(Consumer<Session> consumer) {
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
consumer.accept(session);
transaction.commit();
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
}
}
Я расширил QueryExecutionContext в моем BaseDaoImpl.java позже. Итак, мне нужно знать 2 вещи.
- Мой подход в порядке или нет. Я использую чистый спящий режим и ничего больше. Здесь нет загрузки spring.
- Если да, то скажите мне, как я могу решить проблему дублирования кода в objectReturnContext() и listReturnContext() метод.
Ответ №1:
Параметр Object
/ List<T>
может быть общим параметром U
:
public <U> U returnContext(Function<Session, U> function) {
U object = null;
Transaction transaction = null;
try {
Session session = HibernateUtil.sessionFactory().getCurrentSession();
transaction = session.beginTransaction();
object = function.apply(session);
transaction.commit();
} catch (NoResultException exception) {
if (transaction != null) transaction.rollback();
return object;
} catch (HibernateException exception) {
if (transaction != null) transaction.rollback();
exception.getStackTrace();
}
return object;
}
U
будет выведено в зависимости от того, что function
вы передаете в метод. Если вы вызываете это как:
Object o = returnContext(s -> {
...
return new Object(); // just an example
});
Тогда U
есть Object
.
Если вы вызываете это как:
List<T> list = returnContext(s -> {
...
return new ArrayList<T>(); // just an example
});
Тогда U
есть ArrayList<T>
.
Комментарии:
1. Большое вам спасибо. Я сделал именно так, как вы сказали. Теперь я счастлив в своей жизни:’)