Coverage Report - org.apache.ibatis.session.defaults.DefaultSqlSession
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultSqlSession
87%
87/100
100%
20/20
2.031
DefaultSqlSession$StrictMap
100%
4/4
100%
2/2
2.031
 
 1  
 /**
 2  
  *    Copyright 2009-2015 the original author or authors.
 3  
  *
 4  
  *    Licensed under the Apache License, Version 2.0 (the "License");
 5  
  *    you may not use this file except in compliance with the License.
 6  
  *    You may obtain a copy of the License at
 7  
  *
 8  
  *       http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  *    Unless required by applicable law or agreed to in writing, software
 11  
  *    distributed under the License is distributed on an "AS IS" BASIS,
 12  
  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  *    See the License for the specific language governing permissions and
 14  
  *    limitations under the License.
 15  
  */
 16  
 package org.apache.ibatis.session.defaults;
 17  
 
 18  
 import java.sql.Connection;
 19  
 import java.sql.SQLException;
 20  
 import java.util.Collection;
 21  
 import java.util.HashMap;
 22  
 import java.util.List;
 23  
 import java.util.Map;
 24  
 
 25  
 import org.apache.ibatis.binding.BindingException;
 26  
 import org.apache.ibatis.exceptions.ExceptionFactory;
 27  
 import org.apache.ibatis.exceptions.TooManyResultsException;
 28  
 import org.apache.ibatis.executor.BatchResult;
 29  
 import org.apache.ibatis.executor.ErrorContext;
 30  
 import org.apache.ibatis.executor.Executor;
 31  
 import org.apache.ibatis.executor.result.DefaultMapResultHandler;
 32  
 import org.apache.ibatis.executor.result.DefaultResultContext;
 33  
 import org.apache.ibatis.mapping.MappedStatement;
 34  
 import org.apache.ibatis.session.Configuration;
 35  
 import org.apache.ibatis.session.ResultHandler;
 36  
 import org.apache.ibatis.session.RowBounds;
 37  
 import org.apache.ibatis.session.SqlSession;
 38  
 
 39  
 /**
 40  
  *
 41  
  * The default implementation for {@link SqlSession}.
 42  
  * Note that this class is not Thread-Safe.
 43  
  *
 44  
  * @author Clinton Begin
 45  
  */
 46  
 public class DefaultSqlSession implements SqlSession {
 47  
 
 48  
   private Configuration configuration;
 49  
   private Executor executor;
 50  
 
 51  
   private boolean autoCommit;
 52  
   private boolean dirty;
 53  
 
 54  1638
   public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
 55  1638
     this.configuration = configuration;
 56  1638
     this.executor = executor;
 57  1638
     this.dirty = false;
 58  1638
     this.autoCommit = autoCommit;
 59  1638
   }
 60  
 
 61  
   public DefaultSqlSession(Configuration configuration, Executor executor) {
 62  0
     this(configuration, executor, false);
 63  0
   }
 64  
 
 65  
   @Override
 66  
   public <T> T selectOne(String statement) {
 67  12
     return this.<T>selectOne(statement, null);
 68  
   }
 69  
 
 70  
   @Override
 71  
   public <T> T selectOne(String statement, Object parameter) {
 72  
     // Popular vote was to return null on 0 results and throw exception on too many.
 73  858
     List<T> list = this.<T>selectList(statement, parameter);
 74  837
     if (list.size() == 1) {
 75  789
       return list.get(0);
 76  48
     } else if (list.size() > 1) {
 77  3
       throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
 78  
     } else {
 79  45
       return null;
 80  
     }
 81  
   }
 82  
 
 83  
   @Override
 84  
   public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
 85  6
     return this.selectMap(statement, null, mapKey, RowBounds.DEFAULT);
 86  
   }
 87  
 
 88  
   @Override
 89  
   public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
 90  21
     return this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT);
 91  
   }
 92  
 
 93  
   @Override
 94  
   public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
 95  27
     final List<? extends V> list = selectList(statement, parameter, rowBounds);
 96  27
     final DefaultMapResultHandler<K, V> mapResultHandler = new DefaultMapResultHandler<K, V>(mapKey,
 97  
         configuration.getObjectFactory(), configuration.getObjectWrapperFactory(), configuration.getReflectorFactory());
 98  27
     final DefaultResultContext<V> context = new DefaultResultContext<V>();
 99  27
     for (V o : list) {
 100  54
       context.nextResultObject(o);
 101  54
       mapResultHandler.handleResult(context);
 102  54
     }
 103  27
     return mapResultHandler.getMappedResults();
 104  
   }
 105  
 
 106  
   @Override
 107  
   public <E> List<E> selectList(String statement) {
 108  114
     return this.selectList(statement, null);
 109  
   }
 110  
 
 111  
   @Override
 112  
   public <E> List<E> selectList(String statement, Object parameter) {
 113  1374
     return this.selectList(statement, parameter, RowBounds.DEFAULT);
 114  
   }
 115  
 
 116  
   @Override
 117  
   public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
 118  
     try {
 119  1419
       MappedStatement ms = configuration.getMappedStatement(statement);
 120  1413
       return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
 121  27
     } catch (Exception e) {
 122  27
       throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
 123  
     } finally {
 124  1419
       ErrorContext.instance().reset();
 125  
     }
 126  
   }
 127  
 
 128  
   @Override
 129  
   public void select(String statement, Object parameter, ResultHandler handler) {
 130  15
     select(statement, parameter, RowBounds.DEFAULT, handler);
 131  15
   }
 132  
 
 133  
   @Override
 134  
   public void select(String statement, ResultHandler handler) {
 135  21
     select(statement, null, RowBounds.DEFAULT, handler);
 136  18
   }
 137  
 
 138  
   @Override
 139  
   public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
 140  
     try {
 141  39
       MappedStatement ms = configuration.getMappedStatement(statement);
 142  39
       executor.query(ms, wrapCollection(parameter), rowBounds, handler);
 143  3
     } catch (Exception e) {
 144  3
       throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
 145  
     } finally {
 146  39
       ErrorContext.instance().reset();
 147  36
     }
 148  36
   }
 149  
 
 150  
   @Override
 151  
   public int insert(String statement) {
 152  0
     return insert(statement, null);
 153  
   }
 154  
 
 155  
   @Override
 156  
   public int insert(String statement, Object parameter) {
 157  168
     return update(statement, parameter);
 158  
   }
 159  
 
 160  
   @Override
 161  
   public int update(String statement) {
 162  0
     return update(statement, null);
 163  
   }
 164  
 
 165  
   @Override
 166  
   public int update(String statement, Object parameter) {
 167  
     try {
 168  279
       dirty = true;
 169  279
       MappedStatement ms = configuration.getMappedStatement(statement);
 170  279
       return executor.update(ms, wrapCollection(parameter));
 171  9
     } catch (Exception e) {
 172  9
       throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
 173  
     } finally {
 174  279
       ErrorContext.instance().reset();
 175  
     }
 176  
   }
 177  
 
 178  
   @Override
 179  
   public int delete(String statement) {
 180  0
     return update(statement, null);
 181  
   }
 182  
 
 183  
   @Override
 184  
   public int delete(String statement, Object parameter) {
 185  24
     return update(statement, parameter);
 186  
   }
 187  
 
 188  
   @Override
 189  
   public void commit() {
 190  81
     commit(false);
 191  81
   }
 192  
 
 193  
   @Override
 194  
   public void commit(boolean force) {
 195  
     try {
 196  84
       executor.commit(isCommitOrRollbackRequired(force));
 197  84
       dirty = false;
 198  0
     } catch (Exception e) {
 199  0
       throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + e, e);
 200  
     } finally {
 201  84
       ErrorContext.instance().reset();
 202  84
     }
 203  84
   }
 204  
 
 205  
   @Override
 206  
   public void rollback() {
 207  30
     rollback(false);
 208  30
   }
 209  
 
 210  
   @Override
 211  
   public void rollback(boolean force) {
 212  
     try {
 213  33
       executor.rollback(isCommitOrRollbackRequired(force));
 214  33
       dirty = false;
 215  0
     } catch (Exception e) {
 216  0
       throw ExceptionFactory.wrapException("Error rolling back transaction.  Cause: " + e, e);
 217  
     } finally {
 218  33
       ErrorContext.instance().reset();
 219  33
     }
 220  33
   }
 221  
 
 222  
   @Override
 223  
   public List<BatchResult> flushStatements() {
 224  
     try {
 225  12
       return executor.flushStatements();
 226  0
     } catch (Exception e) {
 227  0
       throw ExceptionFactory.wrapException("Error flushing statements.  Cause: " + e, e);
 228  
     } finally {
 229  12
       ErrorContext.instance().reset();
 230  
     }
 231  
   }
 232  
 
 233  
   @Override
 234  
   public void close() {
 235  
     try {
 236  1587
       executor.close(isCommitOrRollbackRequired(false));
 237  1587
       dirty = false;
 238  
     } finally {
 239  1587
       ErrorContext.instance().reset();
 240  1587
     }
 241  1587
   }
 242  
 
 243  
   @Override
 244  
   public Configuration getConfiguration() {
 245  1030
     return configuration;
 246  
   }
 247  
 
 248  
   @Override
 249  
   public <T> T getMapper(Class<T> type) {
 250  1059
     return configuration.<T>getMapper(type, this);
 251  
   }
 252  
 
 253  
   @Override
 254  
   public Connection getConnection() {
 255  
     try {
 256  276
       return executor.getTransaction().getConnection();
 257  0
     } catch (SQLException e) {
 258  0
       throw ExceptionFactory.wrapException("Error getting a new connection.  Cause: " + e, e);
 259  
     }
 260  
   }
 261  
 
 262  
   @Override
 263  
   public void clearCache() {
 264  9
     executor.clearLocalCache();
 265  9
   }
 266  
 
 267  
   private boolean isCommitOrRollbackRequired(boolean force) {
 268  1704
     return (!autoCommit && dirty) || force;
 269  
   }
 270  
 
 271  
   private Object wrapCollection(final Object object) {
 272  1731
     if (object instanceof Collection) {
 273  30
       StrictMap<Object> map = new StrictMap<Object>();
 274  30
       map.put("collection", object);
 275  30
       if (object instanceof List) {
 276  27
         map.put("list", object);
 277  
       }
 278  30
       return map;
 279  1701
     } else if (object != null && object.getClass().isArray()) {
 280  6
       StrictMap<Object> map = new StrictMap<Object>();
 281  6
       map.put("array", object);
 282  6
       return map;
 283  
     }
 284  1695
     return object;
 285  
   }
 286  
 
 287  36
   public static class StrictMap<V> extends HashMap<String, V> {
 288  
 
 289  
     private static final long serialVersionUID = -5741767162221585340L;
 290  
 
 291  
     @Override
 292  
     public V get(Object key) {
 293  78
       if (!super.containsKey(key)) {
 294  3
         throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
 295  
       }
 296  75
       return super.get(key);
 297  
     }
 298  
 
 299  
   }
 300  
 
 301  
 }