接口定义
SqlSession
定义SqlSession的基本行为,具体说明见注释。
1 2 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
定义生产SqlSession的工厂接口
1 2 3 4 5 6 7 8
| public interface SqlSessionFactory {
SqlSession openSession(); }
|
Executor
Executor用来封装具体操作,解决原生JDBC的痛点,去除大量的模板代码。
1 2 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使提供给使用者使用的外部接口,用来从输入流中解析配置文件并且返回一个SqlSessiob工厂对象。
1 2 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
1 2 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
1 2 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
1 2 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); } }
|