接口定义
 SqlSession
SqlSession
定义SqlSession的基本行为,具体说明见注释。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 
 | public interface SqlSession {
 
 
 
 
 
 
 
 <E> List<E> selectList(String statementId, Object... params) throws Exception;
 
 
 
 
 
 
 
 
 <T> T selectOne(String statementId, Object... params) throws Exception;
 
 
 
 
 
 
 
 int update(String statementId, Object params) throws Exception;
 
 
 
 
 
 
 
 int save(String statementId, Object params) throws Exception;
 
 
 
 
 
 
 
 int delete(String statementId, Object params) throws Exception;
 
 
 
 
 
 
 
 <T> T getMapper(Class<T> mapperClass);
 
 
 
 
 void close();
 }
 
 | 
 SqlSessionFactory
SqlSessionFactory
定义生产SqlSession的工厂接口
| 12
 3
 4
 5
 6
 7
 8
 
 | public interface SqlSessionFactory {
 
 
 
 
 SqlSession openSession();
 }
 
 | 
 Executor
Executor
Executor用来封装具体操作,解决原生JDBC的痛点,去除大量的模板代码。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | public interface Executor {
 
 
 
 
 
 
 
 
 <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception;
 
 
 
 
 
 
 
 
 int update(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception;
 
 
 
 
 void close();
 }
 
 | 
 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder使提供给使用者使用的外部接口,用来从输入流中解析配置文件并且返回一个SqlSessiob工厂对象。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | public class SqlSessionFactoryBuilder {
 
 
 
 
 
 public SqlSessionFactory build(InputStream in) throws Exception {
 
 XMLConfigBuilder builder = new XMLConfigBuilder();
 Configuration configuration = builder.parseConfig(in);
 
 return new DefaultSqlSessionFactory(configuration);
 }
 }
 
 | 
实现
 SimpleExecutor
SimpleExecutor
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 
 | public class SimpleExecutor implements Executor {private PreparedStatement statement;
 private Connection connection;
 @Override
 @SuppressWarnings({"unchecked", "Duplicates"})
 public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {
 
 connection = configuration.getDataSource().getConnection();
 
 String sql = mappedStatement.getSql();
 
 BoundSql boundSql = getBoundSql(sql);
 
 statement = connection.prepareStatement(boundSql.getSqlText());
 
 String paramType = mappedStatement.getParamType();
 Class<?> type = getClassType(paramType);
 List<ParameterMapping> mappingList = boundSql.getParameterMappingList();
 for (int i = 0; i < mappingList.size(); i++) {
 ParameterMapping parameterMapping = mappingList.get(i);
 String content = parameterMapping.getContent();
 Field field = type.getDeclaredField(content);
 
 field.setAccessible(true);
 E o = (E)field.get(params[0]);
 
 statement.setObject(i+1, o);
 }
 
 ResultSet resultSet = statement.executeQuery();
 String resultType = mappedStatement.getResultType();
 Class<?> resultTypeClass = getClassType(resultType);
 
 List<Object> objects = new ArrayList<>();
 while (resultSet.next()) {
 Object o = resultTypeClass.getDeclaredConstructor().newInstance();
 ResultSetMetaData metaData = resultSet.getMetaData();
 for (int i = 0; i < metaData.getColumnCount(); i++) {
 
 String columnName = metaData.getColumnName(i+1);
 Object value = resultSet.getObject(columnName);
 
 PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
 Method writeMethod = propertyDescriptor.getWriteMethod();
 writeMethod.invoke(o, value);
 }
 objects.add(o);
 }
 return (List<E>) objects;
 }
 
 @Override
 @SuppressWarnings("Duplicates")
 public int update(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {
 connection = configuration.getDataSource().getConnection();
 String sql = mappedStatement.getSql();
 BoundSql boundSql = getBoundSql(sql);
 statement = connection.prepareStatement(boundSql.getSqlText());
 
 String paramType = mappedStatement.getParamType();
 Class<?> type = getClassType(paramType);
 List<ParameterMapping> mappingList = boundSql.getParameterMappingList();
 for (int i = 0; i < mappingList.size(); i++) {
 ParameterMapping parameterMapping = mappingList.get(i);
 String content = parameterMapping.getContent();
 Field field = type.getDeclaredField(content);
 
 field.setAccessible(true);
 Object o = field.get(params[0]);
 
 statement.setObject(i+1, o);
 }
 
 return statement.executeUpdate();
 }
 
 @Override
 public void close() {
 try {
 statement.close();
 connection.close();
 } catch (SQLException ignored) {}
 }
 
 private Class<?> getClassType(String paramType) throws ClassNotFoundException {
 if (paramType != null) {
 return Class.forName(paramType);
 }
 throw new NullPointerException("paramType is null");
 }
 
 
 
 
 
 
 
 private BoundSql getBoundSql(String sql) {
 
 ParameterMappingTokenHandler tokenHandler = new ParameterMappingTokenHandler();
 GenericTokenParser genericTokenParser = new GenericTokenParser("#{", "}", tokenHandler);
 
 String parseSql = genericTokenParser.parse(sql);
 
 List<ParameterMapping> mappings = tokenHandler.getParameterMappings();
 return new BoundSql(parseSql, mappings);
 }
 }
 
 | 
 DefaultSqlSession
DefaultSqlSession
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 
 | public class DefaultSqlSession implements SqlSession {
 private final Configuration configuration;
 
 private Executor executor;
 
 public DefaultSqlSession(Configuration configuration) {
 this.configuration = configuration;
 }
 
 @Override
 public <E> List<E> selectList(String statementId, Object... params) throws Exception {
 
 executor = new SimpleExecutor();
 MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
 return executor.query(configuration, mappedStatement, params);
 }
 
 @Override
 public <T> T selectOne(String statementId, Object... params) throws Exception {
 List<T> t = selectList(statementId, params);
 if (t.size() == 1) {
 return t.get(0);
 } else if (t.size() > 1){
 throw new RuntimeException("返回结果过多");
 }
 throw new RuntimeException("返回结果为空");
 }
 
 @Override
 public int update(String statementId, Object params) throws Exception {
 executor = new SimpleExecutor();
 MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
 return executor.update(configuration, mappedStatement, params);
 }
 
 @Override
 public int save(String statementId, Object params) throws Exception {
 executor = new SimpleExecutor();
 MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
 return executor.update(configuration, mappedStatement, params);
 }
 
 @Override
 public int delete(String statementId, Object params) throws Exception {
 executor = new SimpleExecutor();
 MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
 return executor.update(configuration, mappedStatement, params);
 }
 
 @Override
 @SuppressWarnings("unchecked")
 public <T> T getMapper(Class<T> mapperClass) {
 
 Object o = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, (proxy, method, args) -> {
 String methodName = method.getName();
 String className = method.getDeclaringClass().getName();
 String statementId = className + "." + methodName;
 
 Type genericReturnType = method.getGenericReturnType();
 if (genericReturnType instanceof ParameterizedType) {
 return selectList(statementId, args);
 }
 return selectOne(statementId, args);
 });
 return (T) o;
 }
 
 @Override
 public void close() {
 try {
 executor.close();
 }catch(Exception ignore){}
 }
 }
 
 | 
 DefaultSqlSessionFactory
DefaultSqlSessionFactory
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | public class DefaultSqlSessionFactory implements SqlSessionFactory {
 private final Configuration configuration;
 
 public DefaultSqlSessionFactory(Configuration configuration) {
 this.configuration = configuration;
 }
 
 @Override
 public SqlSession openSession() {
 return new DefaultSqlSession(configuration);
 }
 }
 
 |