mybatis中同一个mapper中的多个查询为什么是启用多个sqlSession来处理的?

@Autowired
private UserMapper userMapper;

@Test
public void testGetUserById() {
        System.out.println("------------------------------1");
        User user = userMapper.getUserById(1);
        System.out.println("------------------------------2");
        User user2 = userMapper.getUserById(1);
        System.out.println("------------------------------3");
        User user3 = userMapper.getUserById(1);

        Assert.assertArrayEquals(new int[] { user.getId() }, new int[] { 1 });
}
------------------------------1
2017-04-11 08:57:50,655 DEBUG [SqlSessionUtils.java:97] Creating a new SqlSession
2017-04-11 08:57:50,656 DEBUG [SqlSessionUtils.java:148] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@54144b42] was not registered for synchronization because synchronization is not active
2017-04-11 08:57:50,656 DEBUG [DataSourceUtils.java:110] Fetching JDBC Connection from DataSource
2017-04-11 08:57:50,657 DEBUG [SpringManagedTransaction.java:87] JDBC Connection [com.mysql.jdbc.JDBC4Connection@62d6b944] will not be managed by Spring
2017-04-11 08:57:50,657 DEBUG [BaseJdbcLogger.java:181] ==>  Preparing: SELECT * FROM user WHERE id = ? 
2017-04-11 08:57:50,657 DEBUG [BaseJdbcLogger.java:181] ==> Parameters: 1(Integer)
2017-04-11 08:57:50,661 DEBUG [BaseJdbcLogger.java:181] <==      Total: 1
2017-04-11 08:57:50,661 DEBUG [SqlSessionUtils.java:191] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@54144b42]
2017-04-11 08:57:50,661 DEBUG [DataSourceUtils.java:327] Returning JDBC Connection to DataSource
------------------------------2
2017-04-11 08:57:50,662 DEBUG [SqlSessionUtils.java:97] Creating a new SqlSession
2017-04-11 08:57:50,662 DEBUG [SqlSessionUtils.java:148] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@54630f2f] was not registered for synchronization because synchronization is not active
2017-04-11 08:57:50,662 DEBUG [DataSourceUtils.java:110] Fetching JDBC Connection from DataSource
2017-04-11 08:57:50,662 DEBUG [SpringManagedTransaction.java:87] JDBC Connection [com.mysql.jdbc.JDBC4Connection@62d6b944] will not be managed by Spring
2017-04-11 08:57:50,663 DEBUG [BaseJdbcLogger.java:181] ==>  Preparing: SELECT * FROM user WHERE id = ? 
2017-04-11 08:57:50,664 DEBUG [BaseJdbcLogger.java:181] ==> Parameters: 1(Integer)
2017-04-11 08:57:50,666 DEBUG [BaseJdbcLogger.java:181] <==      Total: 1
2017-04-11 08:57:50,667 DEBUG [SqlSessionUtils.java:191] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@54630f2f]
2017-04-11 08:57:50,667 DEBUG [DataSourceUtils.java:327] Returning JDBC Connection to DataSource
------------------------------3
2017-04-11 08:57:50,667 DEBUG [SqlSessionUtils.java:97] Creating a new SqlSession
2017-04-11 08:57:50,668 DEBUG [SqlSessionUtils.java:148] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e5f0b0] was not registered for synchronization because synchronization is not active
2017-04-11 08:57:50,668 DEBUG [DataSourceUtils.java:110] Fetching JDBC Connection from DataSource
2017-04-11 08:57:50,668 DEBUG [SpringManagedTransaction.java:87] JDBC Connection [com.mysql.jdbc.JDBC4Connection@62d6b944] will not be managed by Spring
2017-04-11 08:57:50,669 DEBUG [BaseJdbcLogger.java:181] ==>  Preparing: SELECT * FROM user WHERE id = ? 
2017-04-11 08:57:50,670 DEBUG [BaseJdbcLogger.java:181] ==> Parameters: 1(Integer)
2017-04-11 08:57:50,672 DEBUG [BaseJdbcLogger.java:181] <==      Total: 1
2017-04-11 08:57:50,672 DEBUG [SqlSessionUtils.java:191] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5e5f0b0]
2017-04-11 08:57:50,672 DEBUG [DataSourceUtils.java:327] Returning JDBC Connection to DataSource

如上代码,多次调用userMapper.getUserById(1);方法,但每次都创建了一个sqlSession来处理请求,并不走一级缓存,这是为什么呢?要怎么处理才能让它走一级缓存呢?

阅读 19.5k
2 个回答
新手上路,请多包涵

因为你的userMapper不是从同一个sqlSession得到,所以不能一级缓存,

SqlSession sqlSession = sqlSessionFactory.openSession();//
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
先通过同一个sqlSeesion获取UserMapper的代理对象,再使用代理对象调用方法,这样在执行相同sql语句是就不会创建多个SqlSesssion

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进