新增UserMapper1.xml ,修改命名空间为com.rangers.dao.IUserDao1
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); User param = new User(); param.setId(1); SqlSession sqlSession1 = sqlSessionFactory.openSession(); IUserDao userDao1 = sqlSession1.getMapper(IUserDao.class); User user1 = userDao1.findOne(param); System.out.println("sqlSession1查询结果:"+user1); sqlSession1.close(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); param.setName("游骑兵"); param.setAddress("西安"); Boolean flag = sqlSession2.update("com.rangers.dao.IUserDao1.updateUser",param) > 0; System.out.println("执行更新操作结果:"+flag); sqlSession2.commit(); sqlSession2.close(); SqlSession sqlSession3 = sqlSessionFactory.openSession(); IUserDao userDao3 = sqlSession3.getMapper(IUserDao.class); User user3 = userDao3.findOne(param); sqlSession3.close(); System.out.println("sqlSession3查询结果:"+user3); 查看控制台输出,发现sqlSession2成功更新用户信息后,sqlSession3进行查询时二级缓存命中,依旧是sqlSession1中的结果,查询结果错误
15:33:54,792 DEBUG JdbcTransaction:137 - Opening JDBC Connection 15:33:55,164 DEBUG PooledDataSource:406 - Created connection 1165303897. 15:33:55,165 DEBUG JdbcTransaction:101 - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:33:55,168 DEBUG findOne:159 - ==> Preparing: select * from user where id=? 15:33:55,186 DEBUG findOne:159 - ==> Parameters: 1(Integer) 15:33:55,212 DEBUG findOne:159 - <== Total: 1 sqlSession1查询结果:com.rangers.entity.User{id=1,, address='杭州'} 15:33:55,215 DEBUG JdbcTransaction:123 - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:33:55,218 DEBUG JdbcTransaction:91 - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:33:55,218 DEBUG PooledDataSource:363 - Returned connection 1165303897 to pool. 15:33:55,219 DEBUG JdbcTransaction:137 - Opening JDBC Connection 15:33:55,220 DEBUG PooledDataSource:398 - Checked out connection 1165303897 from pool. 15:33:55,220 DEBUG JdbcTransaction:101 - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:33:55,224 DEBUG updateUser:159 - ==> Preparing: update user set name=?,address=? where id=? 15:33:55,225 DEBUG updateUser:159 - ==> Parameters: 游骑兵(String), 西安(String), 1(Integer) 15:33:55,233 DEBUG updateUser:159 - <== Updates: 1 执行更新操作结果:true 15:33:55,233 DEBUG JdbcTransaction:70 - Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:33:55,351 DEBUG JdbcTransaction:123 - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:33:55,354 DEBUG JdbcTransaction:91 - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:33:55,355 DEBUG PooledDataSource:363 - Returned connection 1165303897 to pool. 15:33:55,357 DEBUG IUserDao:62 - Cache Hit Ratio [com.rangers.dao.IUserDao]: 0.5 sqlSession3查询结果:com.rangers.entity.User{id=1,, address='杭州'}
解决
在查询的Mapper文件中引入cache-ref标签,指向执行增删改操作表的命名空间,例如在UserMapper.xml中增加一下标签
<cache-ref namespace="com.rangers.dao.IUserDao1"/>在此执行,查看控制台输出,发现第三次查询已直接从数据库中进行查询,结果正确
15:46:05,486 DEBUG IUserDao1:62 - Cache Hit Ratio [com.rangers.dao.IUserDao1]: 0.0 15:46:05,489 DEBUG JdbcTransaction:137 - Opening JDBC Connection 15:46:05,788 DEBUG PooledDataSource:406 - Created connection 1165303897. 15:46:05,789 DEBUG JdbcTransaction:101 - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,793 DEBUG findOne:159 - ==> Preparing: select * from user where id=? 15:46:05,822 DEBUG findOne:159 - ==> Parameters: 1(Integer) 15:46:05,842 DEBUG findOne:159 - <== Total: 1 sqlSession1查询结果:com.rangers.entity.User{id=1,, address='杭州'} 15:46:05,845 DEBUG JdbcTransaction:123 - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,848 DEBUG JdbcTransaction:91 - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,848 DEBUG PooledDataSource:363 - Returned connection 1165303897 to pool. 15:46:05,849 DEBUG JdbcTransaction:137 - Opening JDBC Connection 15:46:05,849 DEBUG PooledDataSource:398 - Checked out connection 1165303897 from pool. 15:46:05,849 DEBUG JdbcTransaction:101 - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,852 DEBUG updateUser:159 - ==> Preparing: update user set name=?,address=? where id=? 15:46:05,852 DEBUG updateUser:159 - ==> Parameters: 游骑兵(String), 西安(String), 1(Integer) 15:46:05,865 DEBUG updateUser:159 - <== Updates: 1 执行更新操作结果:true 15:46:05,865 DEBUG JdbcTransaction:70 - Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,970 DEBUG JdbcTransaction:123 - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,974 DEBUG JdbcTransaction:91 - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,976 DEBUG PooledDataSource:363 - Returned connection 1165303897 to pool. 15:46:05,976 DEBUG IUserDao1:62 - Cache Hit Ratio [com.rangers.dao.IUserDao1]: 0.0 15:46:05,976 DEBUG JdbcTransaction:137 - Opening JDBC Connection 15:46:05,976 DEBUG PooledDataSource:398 - Checked out connection 1165303897 from pool. 15:46:05,976 DEBUG JdbcTransaction:101 - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,979 DEBUG findOne:159 - ==> Preparing: select * from user where id=? 15:46:05,979 DEBUG findOne:159 - ==> Parameters: 1(Integer) 15:46:05,985 DEBUG findOne:159 - <== Total: 1 15:46:05,985 DEBUG JdbcTransaction:123 - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,989 DEBUG JdbcTransaction:91 - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@45752059] 15:46:05,990 DEBUG PooledDataSource:363 - Returned connection 1165303897 to pool. sqlSession3查询结果:com.rangers.entity.User{id=1,, address='西安'}
是否应该使用二级缓存
二级缓存的注意事项:
缓存是以namespace为单位的,不同namespace下的操作互不影响。
insert,update,delete操作会清空所在namespace下的全部缓存。
通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的namespace。
多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。
如果你遵守二级缓存的注意事项,那么你就可以使用二级缓存。