Резьба безопасности MyBatis Mapper с впрыском Guice - PullRequest
0 голосов
/ 01 октября 2019

MyBatis-Guice предполагает, что вместо непосредственного использования SqlSession мы можем вместо этого ввести Mapper. From https://mybatis.org/guice/injections.html

@Singleton
public class FooServiceMapperImpl implements FooService {
    @Inject
    private UserMapper userMapper;

    @Transactional
    public User doSomeBusinessStuff(String userId) {
        return this.userMapper.getUser(userId);
    }
}

Это не похоже на потокобезопасность, так как mapper создается из одного экземпляра SqlSession, который не является потокобезопасным. (Ссылка: https://mybatis.org/mybatis-3/getting-started.html)

Чтобы сделать это потокобезопасным, это лучший подход?

/** Thread safe implementation **/
@Singleton
public class FooServiceMapperImpl implements FooService {
    @Inject
    private SqlSessionFactory sqlSessionFactory;

    @Transactional
    public User doSomeBusinessStuff(String userId) {
        try (SqlSession session = sqlSessionFactory.openSession()) {
           UserMapper mapper = session.getMapper(UserMapper.class);
           return userMapper.getUser(userId);
        }
    }
}

1 Ответ

0 голосов
/ 25 октября 2019

Да. Вы должны иметь возможность просто использовать

@Inject SqlSession session;

со следующим

bind(SqlSessionManager.class).toProvider(SqlSessionManagerProvider.class).in(Scopes.SINGLETON);
bind(SqlSession.class).to(SqlSessionManager.class).in(Scopes.SINGLETON);

, который создаст SqlSession и свяжет его с локальным потоком. Вам также не следует открывать сеанс вручную, если вы используете @Transactional, который уже должен был открыть сеанс для вас.

...