如何避免在Java中使用相同的方法主体但返回类型不同的重复代码?

问题描述

想法:

当我使用休眠模式时,我看到每次必须编写某种代码。所以我将它们移到了另一个包装方法。在哪里有功能接口作为参数,以便我可以在这些上下文方法中附加一些代码

问题:

这是我的两种方法一个返回Object,而另一个返回List。我该如何精确地将这两种方法合而为一,以便避免代码重复。

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,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,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();
        }
    }
}

稍后我在BaseDaoImpl.java中扩展了QueryExecutionContext。所以我需要知道两件事。

  1. 我的批准方式是否可以。我正在使用纯休眠模式,仅此而已。这里没有弹簧靴。
  2. 如果是,那么告诉我如何解决objectReturnContext()和listReturnContext()方法中的代码重复。

谢谢!

解决方法

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
});

然后UObject

如果您这样称呼:

List<T> list = returnContext(s -> {
    ...
    return new ArrayList<T>(); // just an example
});

然后UArrayList<T>