使用调用处理程序打开和关闭SQL会话

时间:2015-06-16 08:41:43

标签: java mybatis invocationhandler

我正在使用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 个答案:

答案 0 :(得分:0)

我解决了这个问题所以我将回答我自己的问题,使用调用处理程序打开和关闭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);