@Test public void testUpdateShouldFlushLocalCache() throws SQLException { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.SIMPLE); try { PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class); Person person = personMapper.selectByIdNoFlush(1); person.setLastName("Perez"); //it is ignored in update personMapper.update(person); Person updatedPerson = personMapper.selectByIdNoFlush(1); assertEquals("Smith", updatedPerson.getLastName()); assertNotSame(person, updatedPerson); sqlSession.commit(); } finally { sqlSession.close(); } }
@Test public void shouldGetAUserNoException() { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false); try { Mapper mapper = sqlSession.getMapper(Mapper.class); User user = mapper.getUser(1); user.setId(2); user.setName("User2"); mapper.insertUser(user); Assert.assertEquals("Dept1", mapper.getUser(2).getDept().getName()); } catch (Exception e) { Assert.fail(e.getMessage()); } finally { sqlSession.commit(); sqlSession.close(); } }
@Test public void shouldAcceptDifferentTypeInTheSameBatch() { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { ObjA a = new ObjA(); a.setId(1); a.setName(111); sqlSession.insert("insertUser", a); ObjB b = new ObjB(); b.setId(2); b.setName("222"); sqlSession.insert("insertUser", b); List<BatchResult> batchResults = sqlSession.flushStatements(); batchResults.clear(); sqlSession.clearCache(); sqlSession.commit(); List<User> users = sqlSession.selectList("selectUser"); assertEquals(2, users.size()); } finally { sqlSession.close(); } }
@Ignore // Not supported yet in PostgreSQL @Test public void testInsertMappedBatch() throws Exception { Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/keycolumn/MapperConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { InsertMapper mapper = sqlSession.getMapper(InsertMapper.class); Name name = new Name(); name.setFirstName("Fred"); name.setLastName("Flintstone"); mapper.insertNameMapped(name); Name name2 = new Name(); name2.setFirstName("Wilma"); name2.setLastName("Flintstone"); mapper.insertNameMapped(name2); List<BatchResult> batchResults = sqlSession.flushStatements(); assertNotNull(name.getId()); assertNotNull(name2.getId()); assertEquals(1, batchResults.size()); } finally { sqlSession.close(); } }
@Test public void testInsert() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { User user1 = new User(null, "Pocoyo"); sqlSession.insert("insert", user1); User user2 = new User(null, "Valentina"); sqlSession.insert("insert", user2); sqlSession.flushStatements(); assertEquals(new Integer(50), user1.getId()); assertEquals(new Integer(50), user2.getId()); sqlSession.commit(); } finally { sqlSession.close(); } try { sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("select"); Assert.assertTrue(users.size() == 2); } finally { sqlSession.close(); } }
@Test public void testInsertJdbc3() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { User user1 = new User(null, "Pocoyo"); sqlSession.insert("insertIdentity", user1); User user2 = new User(null, "Valentina"); sqlSession.insert("insertIdentity", user2); sqlSession.flushStatements(); assertEquals(Integer.valueOf(0), user1.getId()); assertEquals(Integer.valueOf(1), user2.getId()); sqlSession.commit(); } finally { sqlSession.close(); } try { sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("selectIdentity"); Assert.assertTrue(users.size() == 2); } finally { sqlSession.close(); } }
@Test public void testInsertWithMapper() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { Mapper userMapper = sqlSession.getMapper(Mapper.class); User user1 = new User(null, "Pocoyo"); userMapper.insert(user1); User user2 = new User(null, "Valentina"); userMapper.insert(user2); sqlSession.flushStatements(); assertEquals(new Integer(50), user1.getId()); assertEquals(new Integer(50), user2.getId()); sqlSession.commit(); } finally { sqlSession.close(); } try { sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("select"); Assert.assertTrue(users.size() == 2); } finally { sqlSession.close(); } }
@Test public void testInsertMapperJdbc3() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { Mapper userMapper = sqlSession.getMapper(Mapper.class); User user1 = new User(null, "Pocoyo"); userMapper.insertIdentity(user1); User user2 = new User(null, "Valentina"); userMapper.insertIdentity(user2); sqlSession.flushStatements(); assertEquals(Integer.valueOf(0), user1.getId()); assertEquals(Integer.valueOf(1), user2.getId()); sqlSession.commit(); } finally { sqlSession.close(); } try { sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("selectIdentity"); Assert.assertTrue(users.size() == 2); } finally { sqlSession.close(); } }
@Test public void testSameUpdateAfterCommitSimple() { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.SIMPLE); try { PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class); Person person = personMapper.selectById(1); person.setFirstName("Simone"); // Execute first update then commit. personMapper.update(person); sqlSession.commit(); // Execute same update a second time. This used to raise an NPE. personMapper.update(person); sqlSession.commit(); } finally { sqlSession.close(); } }
@Test public void testSameUpdateAfterCommitReuse() { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.REUSE); try { PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class); Person person = personMapper.selectById(1); person.setFirstName("Simone"); // Execute first update then commit. personMapper.update(person); sqlSession.commit(); // Execute same update a second time. This used to raise an NPE. personMapper.update(person); sqlSession.commit(); } finally { sqlSession.close(); } }
@Test public void testSameUpdateAfterCommitBatch() { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class); Person person = personMapper.selectById(1); person.setFirstName("Simone"); // Execute first update then commit. personMapper.update(person); sqlSession.commit(); // Execute same update a second time. This used to raise an NPE. personMapper.update(person); sqlSession.commit(); } finally { sqlSession.close(); } }
/** * 源码解析: 从数据源创建会话 * * @param execType 执行类型 * @param level 数据库隔离级别 * @param autoCommit 是否自动提交 * @return */ private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { // 源码解析: 获取环境 final Environment environment = configuration.getEnvironment(); // 源码解析: 获取事务工厂 final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); // 源码解析: 创建一个新的事务 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); // 源码解析: 创建执行器 final Executor executor = configuration.newExecutor(tx, execType); // 源码解析: 创建一个新的sql会话 return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { // 源码解析: 关闭事务 closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { // 源码解析: 错误上下文清空重置 ErrorContext.instance().reset(); } }
private void settingsElement(Properties props) throws Exception { configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL"))); configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE"))); configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true)); configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory"))); configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false)); configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), true)); configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true)); configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true)); configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false)); configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE"))); configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null)); configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null)); configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false)); configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false)); configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION"))); configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER"))); configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString")); configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true)); configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage"))); configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false)); configuration.setLogPrefix(props.getProperty("logPrefix")); configuration.setLogImpl(resolveClass(props.getProperty("logImpl"))); configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory"))); }
@Test public void testInsert() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { User user1 = new User(null, "Pocoyo"); sqlSession.insert("insert", user1); User user2 = new User(null, "Valentina"); sqlSession.insert("insert", user2); sqlSession.flushStatements(); assertEquals(new Integer(50), user1.getId()); assertEquals(new Integer(50), user2.getId()); sqlSession.commit(); } finally { sqlSession.close(); } sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("select"); Assert.assertTrue(users.size() == 2); }
@Test public void testInsertJdbc3() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { User user1 = new User(null, "Pocoyo"); sqlSession.insert("insertIdentity", user1); User user2 = new User(null, "Valentina"); sqlSession.insert("insertIdentity", user2); sqlSession.flushStatements(); assertEquals(Integer.valueOf(0), user1.getId()); assertEquals(Integer.valueOf(1), user2.getId()); sqlSession.commit(); } finally { sqlSession.close(); } sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("selectIdentity"); Assert.assertTrue(users.size() == 2); }
@Test public void testInsertWithMapper() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { Mapper userMapper = sqlSession.getMapper(Mapper.class); User user1 = new User(null, "Pocoyo"); userMapper.insert(user1); User user2 = new User(null, "Valentina"); userMapper.insert(user2); sqlSession.flushStatements(); assertEquals(new Integer(50), user1.getId()); assertEquals(new Integer(50), user2.getId()); sqlSession.commit(); } finally { sqlSession.close(); } sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("select"); Assert.assertTrue(users.size() == 2); }
@Test public void testInsertMapperJdbc3() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { Mapper userMapper = sqlSession.getMapper(Mapper.class); User user1 = new User(null, "Pocoyo"); userMapper.insertIdentity(user1); User user2 = new User(null, "Valentina"); userMapper.insertIdentity(user2); sqlSession.flushStatements(); assertEquals(Integer.valueOf(0), user1.getId()); assertEquals(Integer.valueOf(1), user2.getId()); sqlSession.commit(); } finally { sqlSession.close(); } sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("selectIdentity"); Assert.assertTrue(users.size() == 2); }
@Bean @Qualifier("batch-operations") @SuppressWarnings("SpringJavaAutowiringInspection") public SqlSession myBatisBatchOperationsSession(DataSource dataSource) throws Exception { /* NOTE: Unfortunately, in MyBatis it's not possible to execute batch and non-batch operations in single SqlSession. To support this scenario, we have to create completely new SqlSessionFactoryBean and completely new SqlSession. Surprisingly, this does not necessarily mean that the batch and non-batch operations will be executed in different transactions (as we would expect) - we tested this configuration using scenario 8. and it turned out that the bot non-batch and batch operations were run using same connection and in same transaction. I guess this has something to do with how connection is obtained by MyBatis from dataSource... */ SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml")); return new SqlSessionTemplate(sqlSessionFactoryBean.getObject(), ExecutorType.BATCH); }
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { final Environment environment = configuration.getEnvironment(); final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); //通过事务工厂来产生一个事务 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); //生成一个执行器(事务包含在执行器里) final Executor executor = configuration.newExecutor(tx, execType); //然后产生一个DefaultSqlSession return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { //如果打开事务出错,则关闭它 closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { //最后清空错误上下文 ErrorContext.instance().reset(); } }
@Test(expected = TransientDataAccessResourceException.class) public void testChangeExecutorTypeInTx() throws Exception { TransactionStatus status = null; try { status = txManager.getTransaction(new DefaultTransactionDefinition()); session = SqlSessionUtils.getSqlSession(sqlSessionFactory); session = SqlSessionUtils.getSqlSession(sqlSessionFactory, ExecutorType.BATCH, exceptionTranslator); fail("should not be able to change the Executor type during an existing transaction"); } finally { SqlSessionUtils.closeSqlSession(session, sqlSessionFactory); // rollback required to close connection txManager.rollback(status); } }
@Test public void testBatch() { setupBatchStatements(); session = SqlSessionUtils.getSqlSession(sqlSessionFactory, ExecutorType.BATCH, exceptionTranslator); session.getMapper(TestMapper.class).insertTest("test1"); session.getMapper(TestMapper.class).insertTest("test2"); session.getMapper(TestMapper.class).insertTest("test3"); // nothing should execute until commit assertExecuteCount(0); session.commit(true); SqlSessionUtils.closeSqlSession(session, sqlSessionFactory); assertCommit(); assertSingleConnection(); assertExecuteCount(3); }
@Test public void testBatchInTx() { setupBatchStatements(); DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(); txDef.setPropagationBehaviorName("PROPAGATION_REQUIRED"); TransactionStatus status = txManager.getTransaction(txDef); session = SqlSessionUtils.getSqlSession(sqlSessionFactory, ExecutorType.BATCH, exceptionTranslator); session.getMapper(TestMapper.class).insertTest("test1"); session.getMapper(TestMapper.class).insertTest("test2"); session.getMapper(TestMapper.class).insertTest("test3"); SqlSessionUtils.closeSqlSession(session, sqlSessionFactory); txManager.commit(status); assertCommit(); assertSingleConnection(); assertExecuteCount(3); }
@Test(expected = PersistenceException.class) public void testBatchWithError() { try { setupBatchStatements(); session = SqlSessionUtils.getSqlSession(sqlSessionFactory, ExecutorType.BATCH, exceptionTranslator); session.getMapper(TestMapper.class).insertTest("test1"); session.getMapper(TestMapper.class).insertTest("test2"); session.update("org.mybatis.spring.TestMapper.insertFail"); session.getMapper(TestMapper.class).insertTest("test3"); session.commit(true); SqlSessionUtils.closeSqlSession(session, sqlSessionFactory); assertCommit(); assertSingleConnection(); assertExecuteCount(4); } finally { SqlSessionUtils.closeSqlSession(session, sqlSessionFactory); } }
@Test(expected = DataAccessException.class) public void testBatchInTxWithError() { setupBatchStatements(); DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(); txDef.setPropagationBehaviorName("PROPAGATION_REQUIRED"); TransactionStatus status = txManager.getTransaction(txDef); session = SqlSessionUtils.getSqlSession(sqlSessionFactory, ExecutorType.BATCH, exceptionTranslator); session.getMapper(TestMapper.class).insertTest("test1"); session.getMapper(TestMapper.class).insertTest("test2"); session.update("org.mybatis.spring.TestMapper.insertFail"); session.getMapper(TestMapper.class).insertTest("test3"); SqlSessionUtils.closeSqlSession(session, sqlSessionFactory); txManager.commit(status); }