spring mybatis每次訪問資料庫都要創建資料庫鏈接?

業餘時間自己搞個小項目。發現一個table顯示的非常慢。後來閱讀日誌發現,是因為每次訪問資料庫都要新建一個sqlsession,然後再銷毀。於是就上了druid,但是情況並沒有好轉。sqlsession還是照樣新建無誤,不過ConnectionProxyImpl並沒有每次都要新建 。問身邊小夥伴都不知為何,故又來問問知乎

以連續的兩次訪問資料庫為例:

//第一次

Creating a new SqlSession

SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4474cc30] was not registered for synchronization because synchronization is not active

JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@3881726d] will not be managed by Spring

//select * from dual

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4474cc30]

//第二次

Creating a new SqlSession

SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@151d520e] was not registered for synchronization because synchronization is not active

JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@3881726d] will not be managed by Spring

//select * from dual

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@151d520e]

可以看到每次訪問資料庫仍然會新建一個SqlSession。dataSource配置已經確保無誤。mybatis中也配置了&

。不知道還有沒有其他需要配置的地方。

* mysql-connector-java:6.0.5

* druid:1.0.29

* org.springframework:4.3.6.RELEASE

* mybatis-spring:1.3.1

* mybatis :3.4.2

* tomcat:8.5.11

* jdk:8

謝謝


樓上瞎說,因為你沒有把事務交給Spring管理啊。。。

如果你喜歡Java註解的話:

@Configuration
@EnableTransactionManagement // 看這句
@MapperScan("com.mybatis3.mapper")
public class MyBatisConfig {
...
}

如果你喜歡XML:

&

上面兩種做法是等價的,就是讓Spring管理事務,不然就像你這樣,自己管理,怎麼死的都不知道

然後要給Spring配一個事務管理器,我就給個JavaConfig的方式,XML的方式自己對就好了。我這裡用的是 org.springfrmaework-jdbc 的。

@Bean
public DataSourceTransactionManager dataSourceTransactionManager(
DataSource dataSource) {
DataSourceTransactionManager manager = new DataSourceTransactionManager();
manager.setDataSource(dataSource);
return manager;
}

最後一步,在你所有的服務類上加上@Transactional註解。貌似加在服務介面上也行的?忘了

@Service
@Transactional
public class MyExampleService {
...
}


可以把你的配置文件貼出來看看。

sqlsession不是connection,這是兩個概念。如果datasource用的是druid 的話,那麼每次進行資料庫操作,都是從pool中拿一個connection而已。當然,這也要看你是不是配置了事務,不過從日誌看應該是沒有配置。


SqlSessionTemplate should always be used instead of default MyBatis implementation DefaultSqlSession because the template can participate in Spring transactions and is thread safe for use by multiple injected mapper classes.

並且,spring bean默認scope是singleton,所以如下即可:

&
&
&

public class UserDaoImpl implements UserDao {
@Autowire
private SqlSession sqlSession;

public void setSqlSession(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}

public User getUser(String userId) {
return (User) sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
}
}

Ref:

Using an SqlSession

歡迎關註:
http://github.com/zzt93
http://tonyz93.blogspot.com
http://stackoverflow.com/users/2870532/tony


推薦閱讀:

如何在mybatis中調試查看生成的sql語句?
mybatis和hibernate區別大不大?

TAG:資料庫 | 程序員 | Java | Spring | MyBatis |