Использование обработчика вызовов для открытия и закрытия сеанса SQL

Я использую Mybatis для создания приложения CRUD для базы данных, и поскольку все мои методы содержат повторяющийся код при открытии и закрытии сеанса SQL, я хотел бы использовать обработчик вызовов, чтобы минимизировать повторение кода. Почти все мои методы выглядят примерно так:

public int deleteDefDialog(DefDialog defDialog) {
    SqlSession sqlSession = ConnectionFactory.getSqlSessionFactory()
            .openSession();
    try {
        DialogMapper dialogMapper = sqlSession
                .getMapper(DialogMapper.class);
        int i = dialogMapper.deleteDefDialog(defDialog);
        sqlSession.commit();
        return i;
    } finally {
        sqlSession.close();
    }
}


public DefDialog selectDefDialog(BigDecimal i) {
    SqlSession sqlSession = ConnectionFactory.getSqlSessionFactory()
            .openSession();
    try {
        DialogMapper dialogMapper = sqlSession
                .getMapper(DialogMapper.class);

        return dialogMapper.selectDefDialog(i);
    } finally {
        sqlSession.close();
    }
}

Мой вопрос заключается в том, как правильно написать и вызвать обработчик вызова, имея в виду, что приложение остается поточно-ориентированным?

1 ответ

Решение

Я решил проблему, поэтому я отвечу на свой собственный вопрос. Правильный способ открыть и закрыть сеанс sql с помощью обработчика вызовов состоял в том, чтобы сохранить sqlSession в ThreadLocal.

ConnectionHandler.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.apache.ibatis.session.SqlSession;

public class ConnectionHandler implements InvocationHandler {

private Object obj;

private static final ThreadLocal<SqlSession> session = new ThreadLocal<SqlSession>();

public static SqlSession getSession(){
    return session.get();
}

public static Object newInstance(Object obj) {
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new ConnectionHandler(obj));
}

private ConnectionHandler(Object obj) {
    this.obj = obj;
}

@Override
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
    Object result = null;

    SqlSession sqlSession = ConnectionFactory.getSqlSessionFactory()
        .openSession(); 
    session.set(sqlSession);
    try {
        result = m.invoke(obj, args);
        sqlSession.commit();
    } catch (Exception e) {
        sqlSession.rollback();
        throw e;
    } finally {
        sqlSession.close();
    }
    return result;
}
}

и измените вышеуказанный класс на

DialogServiceImpl.java

public int deleteDefDialog(DefDialog defDialog) {
    DialogMapper dialogMapper = ConnectionHandler.getSession()
            .getMapper(DialogMapper.class);
    int i = dialogMapper.deleteDefDialog(defDialog);
    return i;
 }


public DefDialog selectDefDialog(BigDecimal i) {
    DialogMapper dialogMapper = ConnectionHandler.getSession()
            .getMapper(DialogMapper.class);
    return dialogMapper.selectDefDialog(i);
}

и вызвать функцию, как это

    DialogService ds = (DialogService) ConnectionHandler.newInstance(new DialogServiceImpl());
    ds.removeDefDialog(defDialog);
Другие вопросы по тегам