0

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

私の質問は、アプリケーションがスレッドセーフのままであることを念頭に置いて、呼び出しハンドラーを適切に作成して呼び出すにはどうすればよいですか?

4

1 に答える 1

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);
于 2015-06-24T13:11:54.877 に答える