我们可以看到DefaultSqlSeeion 获取到了configuration,并通过statementid 从configuration 中获取mapper。 然后具体实现交给了Executer 类来实现。我们这里先不管Executer 是怎么实现的,就假装已经实现了。那么整个框架端就完成了。通过调用Sqlsession.selectList() 方法,来获取结果。
感觉我们都还没有处理,就框架搭建好了?骗鬼呢,确实前面我们从获取文件解析文件,然后创建工厂。都是做好准备工作。下面开始我们JDBC的实现。 SqlSession 具体实现
我们前面说SqlSeesion 的具体实现有下面5步
1、获取数据库连接
2、获取sql,并对sql 进行解析
3、通过内省,将参数注入到preparedStatement 中
4、执行sql
5、通过反射将结果集封装成对象
但是我们在DefaultSqlSeeion 中将实现交给了Executer来执行。所以我们就要在Executer中来实现这些操作。
我们首先来创建一个Executer 接口,并写一个DefaultSqlSeeion中调用的query 方法。
public interface Executer { <E> List<E> query(Configuration configuration,Mapper mapper,Object...parm) throws Exception; }接着我们写一个SimpleExecuter 类来实现Executer 。
然后SimpleExecuter.query()方法中,我们一步一步的实现。
因为数据库连接信息保存在configuration,所以直接获取就好了。
//获取连接 connection=configuration.getDataSource().getConnection(); 获取sql,并对sql 进行解析我们这里想一下,我们在Usermapper.xml写的sql 是什么样子?
select * from user where username=#{username} {username} 这样的sql 我们改怎么解析呢?分两步
1、将sql 找到#{***},并将这部分替换成 ?号
2、对 #{***} 进行解析获取到里面的参数对应的paramType 中的值。
具体实现用到下面几个类。
GenericTokenParser类,可以看到有三个参数,开始标记,就是我们的“#{” ,结束标记就是 “}”, 标记处理器就是处理标记里面的内容也就是username。
主要的就是parse() 方法,用来获取操作1 的sql。获取结果例如:
select * from user where username=?那上面用到TokenHandler 来处理参数。
ParameterMappingTokenHandler实现TokenHandler的类
可以看到将参数名称存放 ParameterMapping 的集合中了。
ParameterMapping 类就是一个实体,用来保存参数名称的。
所以我们在我们通过GenericTokenParser类,就可以获取到解析后的sql,以及参数名称。我们将这些信息封装到BoundSql实体类中。
public class BoundSql { private String sqlText; private List<ParameterMapping> parameterMappingList=new ArrayList<>(); public BoundSql(String sqlText, List<ParameterMapping> parameterMappingList) { this.sqlText = sqlText; this.parameterMappingList = parameterMappingList; } ////getter()和setter() 方法。 }好了,那么分两步走,先获取,后解析
获取
获取原始sql 很简单,sql 信息就存在mapper 对象中,直接获取就好了。