五、MappedStatement
MappedStatement:描述<select|update|insert|delete>或者@Select、@Update等注解配置的SQL信息。
<select>
标签中的常用属性:
id:命名空间中唯一的标识符,可以被用来引用这条配置信息。
parameterType:用于指定这条语句的参数类的完全限定名或别名。MyBatis能够根据Mapper接口方法中的参数类型推断出传入语句的类型。
resultType:返回的期望类型的类的完全限定名或别名。注意,如果返回结果是集合类型,则resultType属性应该指定集合中可以包含的类型,而不是集合本身。
resultMap:用于引用通过<resultMap>
标签配置的实体属性与数据库字段之间建立的结果集的映射(注意:resultMap和resultType属性不能同时使用)。
flushCache:用于控制是否刷新缓存。如果将其设置为true,则任何时候只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值为false。
useCache:是否使用二级缓存。如果将其设置为true,则会导致本条语句的结果被缓存在MyBatis的二级缓存中,对应标签,该属性的默认值为true。
statementType:参数可选值为STATEMENT、PREPARED或CALLABLE,默认值为PREPARED。
resultSetType:参数可选值为FORWARD_ONLY、SCROLL_SENSITIVE或SCROLL_INSENSITIVE,默认未设置,由JDBC驱动决定。
resultSets:这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并每个结果集给一个名称,名称使用逗号分隔。
lang:指定LanguageDriver实现,MyBatis中的LanguageDriver用于解析<select|update|insert|delete>标签中的SQL语句,生成SqlSource对象。
<insert>
标签的常用属性:
useGeneratedKeys:属性值为true时,MyBatis使用JDBC Statement对象的getGeneratedKeys()方法来取出由数据库内部生成的键值,例如MySQL自增主键。
keyProperty:用于将数据库自增主键或者<insert>
标签中<selectKey>
标签返回的值填充到实体的属性中,如果有多个属性,则使用逗号分隔。
keyColumn:通过生成的键值设置表中的列名,这个设置仅在某些数据库(例如PostgreSQL)中是必需的,当主键列不是表中的第一列时需要设置,如果有多个字段,则使用逗号分隔。
MappedStatement其他的属性:
cache:二级缓存实例,根据Mapper中的<cache>
标签配置信息创建对应的Cache实现。
sqlSource:解析<select|update|insert|delete>,将SQL语句配置信息解析为SqlSource对象。
resource:Mapper配置文件路径。
configuration:Configuration对象的引用,方便获取MyBatis配置信息及TypeHandler、TypeAlias等信息。
keyGenerator:主键生成策略,默认为Jdbc3KeyGenerator,即数据库自增主键。当配置了<selectKey>
时,使用SelectKeyGenerator生成主键。
statementLog:用于输出日志。
六、StatementHandler:
StatementHandler:
封装了对JDBC Statement的操作,例如设置Statement对象的fetchSize属性、设置查询超时时间、调用JDBC Statement与数据库交互等。
BaseStatementHandler是一个抽象类,封装了通用的处理逻辑及方法执行流程,具体方法的实现由子类完成,这里使用设计模式中的模板方法模式。
SimpleStatementHandler继承至BaseStatementHandler,封装了对JDBC Statement对象的操作,
PreparedStatementHandler封装了对JDBC PreparedStatement对象的操作,
CallableStatementHandler则封装了对JDBC CallableStatement对象的操作。
RoutingStatementHandler会根据Mapper配置中的statementType属性(取值为STATEMENT、PREPARED或CALLABLE)创建对应的StatementHandler实现。
StatementHandler接口常用方法:
prepare():
创建JDBC Statement对象,并完成Statement对象的属性设置。
parameterize():
使用MyBatis中的ParameterHandler组件为PreparedStatement和CallableStatement参数占位符设置值。
batch():
将SQL命令添加到批处量执行列表中。
update():
调用Statement对象的execute()方法执行更新语句,例如UPDATE、INSERT、DELETE语句。
query():
执行查询语句,并使用ResultSetHandler处理查询结果集。
queryCursor():
带游标的查询,返回Cursor对象,能够通过Iterator动态地从数据库中加载数据,适用于查询数据量较大的情况,避免将所有数据加载到内存中。
getBoundSql():
获取Mapper中配置的SQL信息,BoundSql封装了动态SQL解析后的SQL文本和参数映射信息。
getParameterHandler():
获取ParameterHandler实例。
七、TypeHandler
TypeHandler:
处理JDBC类型与Java类型之间的转换,BaseTypeHandler类实现了TypeHandler接口,对调用setParameter()方法,参数为Null的情况做了通用的处理。
对调用getResult()方法,从ResultSet对象或存储过程调用结果中获取列的值出现的异常做了处理,当我们需要自定义TypeHandler时,只需要继承BaseTypeHandler类即可。
使用的两种场景:
1.PreparedStatement对象为参数占位符设置值时,需要调用PreparedStatement接口中提供的一系列的setXXX()方法,将Java类型转换为对应的JDBC类型并为参数占位符赋值。
2.执行SQL语句获取ResultSet对象后,需要调用ResultSet对象的getXXX()方法获取字段值,此时会将JDBC类型转换为Java类型。
TypeHandler接口中4个方法:
1.setParameter()
用于为PreparedStatement对象参数的占位符设置值。
2.3个重载的getResult()方法
用于从ResultSet对象中获取列的值,或者获取存储过程调用结果。
TypeHandler与Java、JDBC类型的对应关系:
在TypeHandlerRegistry中,通过Map对象保存JDBC类型、Java类型与TypeHandler之间的关系,
在TypeHandlerRegistry类的构造方法中,通过register()方法注册所有的TypeHandler。
八、ParameterHandler
ParameterHandler:
在PreparedStatementHandler和CallableStatementHandler操作对应的Statement执行数据库交互之前为参数占位符设置值,
ParameterHandler接口只有一个默认的实现类,即DefaultParameterHandler。
ParameterHandler接口中2个方法:
1.getParameterObject():
用于获取执行Mapper时传入的参数对象。
2.setParameters():
用于为JDBC PreparedStatement或者CallableStatement对象设置参数值。
setParameters()方法的逻辑:
1.获取Mapper配置中的参数映射,然后对所有参数映射信息进行遍历(MyBatis通过ParameterMapping描述参数映射的信息),
2.根据参数名称获取对应的参数值,调用对应的TypeHandler对象的setParameter()方法为Statement对象中的参数占位符设置值。
九、ResultSetHandler
ResultSetHandler:
在StatementHandler对象执行完查询操作或存储过程后,对结果集或存储过程的执行结果进行处理,ResultSetHandler接口只有一个默认的实现,即DefaultResultHandler。
ResultSetHandler接口中有3个方法:
1.handleResultSets():
获取Statement对象中的ResultSet对象,对ResultSet对象进行处理,返回包含结果实体的List对象。
2.handleCursorResultSets():
将ResultSet对象包装成Cursor对象,对Cursor进行遍历时,能够动态地从数据库查询数据,避免一次性将所有数据加载到内存中。
3.handleOutputParameters():
处理存储过程调用结果。
handleResultSets()方法的逻辑:
1.从Statement对象中获取ResultSet对象,然后将ResultSet包装为ResultSetWrapper对象,通过ResultSetWrapper对象能够更方便地获取表字段名称、字段对应的TypeHandler信息。
2.获取解析Mapper接口及Mapper SQL配置生成的ResultMap信息,一条语句一般对应一个ResultMap。
3.调用handleResultSet()方法对ResultSetWrapper对象进行处理,将生成的实体对象存放在multipleResults列表中。