net start mysql #启动服务器
如果要卸载mysql可以运行一下命令
net stop mysql #停止服务器

Mybatis XML Mapper 用法

select

resultMap 用于配置 Java 对象的属性与查询结果列的对应关系

resultMap 包含的属性:

  • id:必填且唯一
  • type:必填,查询结果映射的对象类型
  • extends:选填,表示该 resultMap 继承自其他的 resultMap
  • autoMapping:选填,表示是否启用非映射字段(resultMap 中没有配置的字段)的自动映射功能

resultMap 包含的子标签:

  • constructor:使用构造方法注入结果,包含两个子标签
    • idArg:id 参数,标记结果作为 id(唯一值),可以帮助提高整体性能
    • arg:注入到构造方法的一个普通结果
  • id:一个 id 结果,标记结果作为 id(唯一值),可以帮助提高整体性能
  • result:注入到 Java 对象属性的普通结果
  • association:类型关联,可以将结果进行包装成这种类型
  • collection:复杂类型的集合
  • discriminator:根据结果值来决定使用哪个结果映射
  • case:基于某些值得结果映射

子标签 id result 都包含的属性

  • column:从数据库得到的列名,或者是列的别名
  • property:映射到结果的属性,支持嵌套如:address.street.number
  • javaType:一个 Java 类的完全限定名或一个类型别名(通过 typeAlias 配置或者默认的类型);若映射到普通的 Bean,MyBatis 会自动判断属性的类型,如果是映射到 HashMap,则需要明确地指定 javaType 属性
  • jdbcType:列对应的数据库类型。指明插入、更新、删除操作时,对于为空的列的处理方式
  • typeHandler:覆盖默认的类型处理器,值可以是类的完全限定名或类型别名

当 resultType = 某个 Bean 时,需要设置别名来应对列名和属性名不一致的情况;使用 resultMap 则使用配置好的映射方式。

MyBatis 映射是将属性名的映射是转换为大写之后再进行映射,即 property=”userName” 和 property=”username” 都可以匹配到对象的 userName 属性上面。

  1. <resultMap id="userMap" type="tk.mybatis.simple.model.SysUser">
  2. <id property="id" column="id"/>
  3. <result property="userName" column="user_name"/>
  4. <result property="userPassword" column="user_password"/>
  5. <result property="userEmail" column="user_email"/>
  6. <result property="userInfo" column="user_info"/>
  7. <result property="headImg" column="head_img" jdbcType="BLOB"/>
  8. <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
  9. </resultMap>
  10. <select id="selectById" resultMap="userMap">
  11. select * from sys_user where id = #{id}
  12. </select>
  13. <select id="selectAll" resultType="tk.mybatis.simple.model.SysUser">
  14. select id,
  15. user_name userName,
  16. user_password userPassword,
  17. user_email userEmail,
  18. user_info userInfo,
  19. head_img headImg,
  20. create_time createTime
  21. from sys_user
  22. </select>

关联查询结果嵌套

一次 SQL 查询根据表或指定的属性映射到不同的对象中,对象里面嵌套对象,使用 属性.属性 进行赋值,注意双引号

  • 缺点:SQL 比较复杂,不容易写对;嵌套结果应用到不同的类上,增加服务器压力

    1. <select id="selectRolesByUserId" resultType="tk.mybatis.simple.model.SysRole">
    2. select
    3. r.id,
    4. r.role_name roleName,
    5. r.enabled,
    6. r.create_by createBy,
    7. r.create_time createTime,
    8. u.user_name as "user.userName",
    9. u.user_email as "user.userEmail"
    10. from sys_user u
    11. inner join sys_user_role ur on u.id = ur.user_id
    12. inner join sys_role r on ur.role_id = r.id
    13. where u.id = #{userId}
    14. </select>
    1. 使用 resultMap 继承
      1. <resultMap id="userRoleMap" extends="userMap" type="tk.mybatis.simple.model.SysUser">
      2. <result property="role.id" column="role_id"/>
      3. <result property="role.roleName" column="role_name"/>
      4. <result property="role.enabled" column="enabled"/>
      5. <result property="role.createBy" column="create_by"/>
      6. <result property="role.createTime" column="role_create_time" jdbcType="TIMESTAMP"/>
      7. </resultMap>
    1. 使用 resultMap association 标签配置一对一映射(使用 association 和 对上面进行改造)

association 属性:

  • property:实体类的属性名
  • javaType:属性对应的 Java 类型,下面的例子使用的是 javaType
  • resultMap:使用现有的 resultMap,不用重新配置
  • columnPrefix:查询列前缀,配置前缀后,子标签配置 result 的 column 可以省略前缀

    1. <resultMap id="userRoleMap" extends="userMap" type="tk.mybatis.simple.model.SysUser">
    2. <association property="role" columnPrefix="role_" javaType="tk.mybatis.simple.model.SysRole"/>
    3. <result property="id" column="role_id"/>
    4. <result property="roleName" column="role_name"/>
    5. <result property="enabled" column="enabled"/>
    6. <result property="createBy" column="create_by"/>
    7. <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    8. </resultMap>
    9. <select id="selectUserAndRoleById2" resultMap="userRoleMap">
    10. select
    11. u.id,
    12. u.user_name,
    13. u.user_password,
    14. u.user_email,
    15. u.user_info,
    16. u.head_img,
    17. u.create_time,
    18. r.id role_id,
    19. r.role_name role_role_name,
    20. r.enabled role_enabled,
    21. r.create_by role_create_by,
    22. r.create_time role_create_time
    23. from sys_user u
    24. inner join sys_user_role ur on u.id = ur.user_id
    25. inner join sys_role r on ur.role_id = r.id
    26. where u.id = #{id}
    27. </select>
    1. 进一步的将 association 中的 javaType 替换为 resultMap ```xml
<a name="TRQyc"></a> ### 关联的嵌套查询 不同于**关联结果嵌套**,**关联的嵌套查询**则是通过简单的进行**额外的查询** association 标签嵌套查询常用属性: - select:另一个映射查询的 id,Mybatis 会额外执行这个查询获取嵌套对象的结果 - column:列名(或别名),将主查询中列的结果作为嵌套查询的参数。例如 column={prop1=col1,prop2=col2},prop1 和 prop2 作为嵌套查询的参数 - fetchType:数据加载方式,可选值未 lazy(延迟加载) 和 eager(积极加载),该配置会覆盖全局的 lazyLoadingEnabled 配置xml // userMapper.xml
  1. <select id="selectUserAndRoleByIdSelect" resultMap="userRoleMapSelect">
  2. select
  3. u.id,
  4. u.user_name,
  5. u.user_password,
  6. u.user_email,
  7. u.user_info,
  8. u.head_img,
  9. u.create_time,
  10. ur.role_id
  11. from sys_user u
  12. inner join sys_user_role ur on u.id = ur.user_id
  13. where u.id = #{id}
  14. </select>
  15. // roleMapper.xml
  16. <select id="selectRoleById" resultMap="roleMap">
  17. select * from sys_role where id = #{id}
  18. </select>
  1. - 全局延迟加载属性,注意,延迟加载通过动态代理实现,通过 SqlSession 执行 SQL,注意 SqlSession 的生命周期,避免 SqlSession 已经销毁,而仍然去调用查询方法,造成异常。
  2. ```xml
  3. <setting name="aggressiveLazyLoading" value="false"/>
  • lazyLoadTriggerMethods 默认值为 equals,clone,hashCode,toString,当调用配置中的方法时,会自动触发对象的延迟加载

    一对多的查询结果嵌套 collection

  • 查询用户角色下面的权限,collection property 指定实体类属性,以及 ofType 对应的 JavaBean 类型 ```xml public class SysUser implements Serializable { private List roleList; }

    // 进一步,使用 resultMap 代替

  1. Mybatis 数据合并原理:查询 userMap 中的 id 标签对应的字段是否相同,相同就合并;若没有配置 id,则比对所有的字段,全部相同则合并;所以在 resultMap 中配置 id 子标签可以提高查询效率
  2. <a name="SXTpL"></a>
  3. ## insert
  4. <a name="PF0xZ"></a>
  5. ### insert 包含的属性
  6. - id:唯一标志
  7. - parameterType:传入语句参数的完全限定名或别名,由于 Mybatis 可以推断出传入语句的具体参数,因此不建议配置
  8. - flushCache:默认值为 true,即任何时候语句被调用都会清空一级缓存和二级缓存
  9. - timeout:等待数据库返回结果的超时时间,超过即抛出异常
  10. - statementTypeSTATEMENT/PREPARED/CALLABLEMybatis 采用的预编译方式,默认为 PREPARED
  11. - useGeneratedKeys:默认值为 false,若设为 trueMyBatis 会使用 JDBC getGeneratedKeys 方法取出由数据库内部生成的主键
  12. - keyProperty:将 useGeneratedKeys 获取的主键值赋值给 keyProperty 指定的属性名
  13. - keyColumn:仅 INSERT UPDATE 有效。通过 useGeneratedKeys 生成的键值设置表中的列名
  14. - databaseId:若配置了 databaseIdProvider
  15. 注意:对于特殊的数据类型,建议指明 jdbcType 的值,防止类型错误(BLOBTIMESTAMP
  16. <a name="S56Km"></a>
  17. ### 插入之后返回主键的方式
  18. - 使用 useGeneratedKeys
  19. ```java
  20. <insert id="insert2" useGeneratedKeys="true" keyProperty="id">
  21. insert into sys_user(
  22. user_name, user_password,
  23. <if test="userEmail != null">
  24. <if test="userEmail != ''">
  25. user_email,
  26. </if>
  27. </if>
  28. user_info, head_img, create_time)
  29. values(
  30. #{userName}, #{userPassword},
  31. <if test="userEmail != null">
  32. <if test="userEmail != ''">
  33. #{userEmail},
  34. </if>
  35. </if>
  36. #{userInfo}, #{headImg, jdbcType=BLOB}, #{createTime, jdbcType=TIMESTAMP})
  37. </insert>
  • 使用 selectKey

order 值在 MySQL 中是 AFTER ,在 Oracle 是 BEFORE,因为 Oracle 是先获取值,再插入,并且写插入语句的时候,必须指定 id,否则会抛出主键不为空的异常。

  1. <insert id="insert3">
  2. insert into sys_user(
  3. user_name, user_password, user_email,
  4. user_info, head_img, create_time)
  5. values(
  6. #{userName}, #{userPassword}, #{userEmail},
  7. #{userInfo}, #{headImg, jdbcType=BLOB}, #{createTime, jdbcType=TIMESTAMP})
  8. <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
  9. SELECT LAST_INSERT_ID()
  10. </selectKey>
  11. </insert>

接口包含多个参数场景

建议使用 @Param ,给参数配置@Param注解后,MyBatis 就会自动将参数封装成 Map 类型,@Param 注解值
会作为 Map 中的 key,因此在 SQL 部分就可以通过配置的注解值来使用参数。

List selectRolesByUserIdAndRoleEnabled(@Param(“userId”)Long userId, @Param(“enabled”)Integer enabled);

动态 SQL

  • where、if 标签配合使用实现动态查询

    • 当 if 条件都不满足,SQL 中不会加入 where
    • 当 if 条件有满足项,where 标签会自动去除语句第一个 and
      1. <select id="selectByUser" resultType="tk.mybatis.simple.model.SysUser">
      2. select id,
      3. user_name userName,
      4. user_password userPassword,
      5. user_email userEmail,
      6. user_info userInfo,
      7. head_img headImg,
      8. create_time createTime
      9. from sys_user
      10. <where>
      11. <if test="@tk.mybatis.util.StringUtil@isNotEmpty(userName)">
      12. and user_name like concat('%', #{userName}, '%')
      13. </if>
      14. <if test="userEmail != null and userEmail != ''">
      15. and user_email = #{userEmail}
      16. </if>
      17. </where>
      18. </select>
  • insert if 标签在列部分和values部分需要同时加上,保证上下可以互相对应 完全匹配

    1. <insert id="insert2" useGeneratedKeys="true" keyProperty="id">
    2. insert into sys_user(
    3. user_name, user_password,
    4. <if test="userEmail != null">
    5. <if test="userEmail != ''">
    6. user_email,
    7. </if>
    8. </if>
    9. user_info, head_img, create_time)
    10. values(
    11. #{userName}, #{userPassword},
    12. <if test="userEmail != null">
    13. <if test="userEmail != ''">
    14. #{userEmail},
    15. </if>
    16. </if>
    17. #{userInfo}, #{headImg, jdbcType=BLOB}, #{createTime, jdbcType=TIMESTAMP})
    18. </insert>
  • choose when otherwise 实现条件选择

    1. <select id="selectByIdOrUserName" resultType="tk.mybatis.simple.model.SysUser">
    2. select id,
    3. user_name userName,
    4. user_password userPassword,
    5. user_email userEmail,
    6. user_info userInfo,
    7. head_img headImg,
    8. create_time createTime
    9. from sys_user
    10. where 1 = 1
    11. <choose>
    12. <when test="id != null">
    13. and id = #{id}
    14. </when>
    15. <when test="userName != null and userName != ''">
    16. and user_name = #{userName}
    17. </when>
    18. <otherwise>
    19. limit 0
    20. </otherwise>
    21. </choose>
    22. </select>
  • set 标签

    • set 标签会自动去除最后字符串结尾的 逗号
    • 注意:若 if 条件都不满足,结尾还是要加上一个更新语句 id = #{id},避免 SQL 错误
      1. <update id="updateByIdSelective">
      2. update sys_user
      3. <set>
      4. <if test="userName != null and userName != ''">
      5. user_name = #{userName},
      6. </if>
      7. <if test="userPassword != null and userPassword != ''">
      8. user_password = #{userPassword},
      9. </if>
      10. <if test="userEmail != null and userEmail != ''">
      11. user_email = #{userEmail},
      12. </if>
      13. <if test="userInfo != null and userInfo != ''">
      14. user_info = #{userInfo},
      15. </if>
      16. <if test="headImg != null">
      17. head_img = #{headImg, jdbcType=BLOB},
      18. </if>
      19. <if test="createTime != null">
      20. create_time = #{createTime, jdbcType=TIMESTAMP},
      21. </if>
      22. id = #{id}
      23. </set>
      24. where id = #{id}
      25. </update>
  • foreach 实现 in 集合

    • collection 必填,值为要迭代循环的属性名

      • 当参数类型为 list 时,collection = list;当参数类型为 数组 时, collection = array; ```xml List selectByIdList(List idList);

      ```

  • foreach 批量插入 ```xml int insertList(List userList);

insert into sys_user( user_name, user_password,user_email, user_info, head_img, create_time) values (

  1. #{user.userName}, #{user.userPassword},#{user.userEmail},
  2. #{user.userInfo}, #{user.headImg, jdbcType=BLOB}, #{user.createTime, jdbcType=TIMESTAMP})
  3. </foreach>
  4. </insert>
  1. - foreach 动态 update
  2. ```xml
  3. int updateByMap(Map<String, Object> map);
  4. <update id="updateByMap">
  5. update sys_user
  6. set
  7. <foreach collection="_parameter" item="val" index="key" separator=",">
  8. ${key} = #{val}
  9. </foreach>
  10. where id = #{id}
  11. </update>
  • bind 标签创建一个变量,供上下文使用
    1. <if test="userName != null and userName != ''">
    2. <bind name="userNameLike" value = "'%' + userName + '%'"/>
    3. and user_name = #{userNameLike}
    4. </if>

MyBatis 注解方式的基本用法

MyBatis注解方式就是将SQL语句直接写在接口上。这种方式的优点是,对于需求比较简单的系统,效率较高。
缺点是,当SQL有变化时都需要重新编译代码,一般情况下不建议使用注解方式。

@Select

  • 当列名和属性名不一致时,需要使用 @Results 进行映射
  • @Results 实现其实就是 resultMap,也可以根据 id 进行引用

    1. @Results(id = "roleResultMap", value = {
    2. @Result(property = "id", column = "id", id = true),
    3. @Result(property = "roleName", column = "role_name"),
    4. @Result(property = "enabled", column = "enabled"),
    5. @Result(property = "createBy", column = "create_by"),
    6. @Result(property = "createTime", column = "create_time")
    7. })
    8. @Select("select id,role_name, enabled, create_by, create_time from sys_role where id = #{id}")
    9. SysRole selectById2(Long id);
    10. @ResultMap("roleResultMap")
    11. @Select("select * from sys_role")
    12. List<SysRole> selectAll();

    insert

  • 使用 @Options(useGeneratedKeys = true, keyProperty = “id”) 返回自增主键

  • 使用 @SelectKey(statement = “SELECT LAST_INSERT_ID()”, keyProperty = “id”, resultType = Long.class, before = false) 返回非自增主键
    • before = false 等同于 XML 配置方式下面的 order=”AFTER” ```xml @Insert({“insert into sys_role(id, role_name, enabled, create_by, create_time)”,
      1. "values(#{id}, #{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})"})
      int insert(SysRole sysRole);

// 返回自增主键 @Insert({“insert into sys_role(role_name, enabled, create_by, create_time)”, “values(#{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})”}) @Options(useGeneratedKeys = true, keyProperty = “id”) int insert2(SysRole sysRole);

// 返回非自增主键 before = false 就是前面 XML 中 order = AFTER @Insert({“insert into sys_role(role_name, enabled, create_by, create_time)”, “values(#{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})”}) @SelectKey(statement = “SELECT LAST_INSERT_ID()”, keyProperty = “id”, resultType = Long.class, before = false) int insert3(SysRole sysRole);

  1. <a name="MrNKd"></a>
  2. ## Provider 注解
  3. 自定义一个类,然后专门写 SQL。Mybatis 提供了 @SelectProvider、@InsertProvider、@UpdateProvider、@DeleteProvider 4 个 provider 实现查询、插入、更新、删除操作
  4. 注意:
  5. provider 主键包含 type 和 method 两个必填属性;type 指定的类必须包含一个空的构造方法,method 指定的方法必须返回 String 类型
  6. ```xml
  7. @SelectProvider(type = PrivilegeProvider.class, method = "selectById")
  8. SysPrivilege selectById(Long id);
  9. public class PrivilegeProvider {
  10. // 返回 String 类型
  11. public String selectById(final Long id){
  12. return new SQL(){
  13. {
  14. SELECT("id, privilege_name, privilege_url");
  15. FROM("sys_privilege");
  16. WHERE("id = #{id}");
  17. }
  18. }.toString();
  19. }
  20. }

MyBatis 高级查询

高级结果映射

鉴别器映射

discriminator
image.png

存储过程

存储过程不支持 二级缓存,所以设置 useCache = false
mode:IN 入参、OUT 出参(必须指定 jdbcType)、INOUT 输入输出参数
javaType:BLOB 类型对应 byte[] 数组,而 MyBatis 映射 Java 类不推荐基本数据类型,

  1. void selectUserById(SysUser user);
  2. <select id="selectUserById" statementType="CALLABLE" useCache="false">
  3. {call select_user_by_id(
  4. #{id, mode=IN},
  5. #{userName, mode=OUT, jdbcType=VARCHAR},
  6. #{userPassword, mode=OUT, jdbcType=VARCHAR},
  7. #{userEmail, mode=OUT, jdbcType=VARCHAR},
  8. #{userInfo, mode=OUT, jdbcType=VARCHAR},
  9. #{headImg, mode=OUT, jdbcType=BLOB, javaType=_byte[]},
  10. #{createTime, mode=OUT, jdbcType=TIMESTAMP}
  11. )}
  12. </select>

枚举

MyBatis 缓存配置

一级缓存

MyBatis的一级缓存存在于sqlSession的生命周期中,在同一个sqlSession中查询时,MyBatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一一个Map对象中。如果同一个sqlSession中执行的方法和参数完全- - 致,那么通过算法会生成相同的键值,当Map缓存对象中已经存在该键值时,则会返回缓存中的对象。

二级缓存

存在于 SqlSessionFactory 生命周期中,首先开启全局配置,默认是打开的,一般不用显示声明。

  1. <configuration>
  2. <settings>
  3. <setting name="cacheEnabled" value="true"/> 默认值 true
  4. </settings>
  5. </configuration>

MyBatis 二级缓存与命名空间进行绑定,所以二级缓存需要配置到 Maper.xml 映射文件或者 Mapper.java 文件中。

  • 在 mapper 文件中加入 元素开启二级缓存
    1. <mapper namespace="tk.mybatis.simple.mapper.UserMapper">
    2. <cache
    3. eviction="FIFO"
    4. flushInterval="60000"
    5. size="512"
    6. readOnly="true"/>
    7. </mapper>

cache 属性

  • eviction 收回策略
    • LRU ,默认值
    • FIFO
    • SOFT 软引用,移除基于垃圾回收器状态和软引用规则的对象
    • WEAK 弱引用,更积极地移除基于垃圾回收器状态和软引用规则的对象
  • flushInterval 刷新间隔,可以设置任意正整数,单位为 ms。默认情况下不设置,缓存仅调用语句时更新
  • size 引用数目,要记住的缓存对象数目和运行环境可用内存资源数目,默认为 1024
  • readOnly,可以设置为 true or false,只读缓存只能读不能修改,默认为 false

  • 接口中配置缓存

  1. @CacheNamespace
  2. public interface RoleMapper {
  3. }

如果接口和XML同时使用,那么需要改为参照缓存,避免冲突

  1. @CacheNamespaceRef(RoleMapper.class)
  2. public interface RoleMapper {
  3. }

二级缓存脏读

二级缓存事基于命名空间的,多表查询的时候,可能另外的操作更新了,查询到脏数据

可以使用参照缓存解决脏数据问题,但是这样做在表连接较多的时候就很麻烦

  1. <mapper namespace="tk.mybatis.simple.mapper.UserMapper">
  2. <cache-ref namespace="tk.mybatis.simple.mapper.RoleMapper"/>
  3. </mapper>

二级缓存适用场景

  • 查询为主的应用
  • 绝大部分都是单表操作,若关联表比较少,可以使用参照缓存

MyBatis 插件开发

拦截器接口

  1. public interface Interceptor {
  2. Object intercept(Invocation invocation) throws Throwable;
  3. Object plugin(Object target);
  4. void setProperties(Properties properties);
  5. }

拦截器实现

@Intercepts 注解的属性事一个 @Signature 数组,可以在同一个拦截器中拦截不同的接口和方法

@Signature 属性

  • type:设置拦截的接口,可选值是 Executor 、ParameterHandler、ResultSetHandler、StatmentHandler
  • method:接口中的方法名称,即 type 中接口中定义的方法
  • args:拦截方法的参数类型数组

    1. @Intercepts(
    2. @Signature(
    3. type = Executor.class,
    4. method = "query",
    5. args = {MappedStatement.class, Object.class,
    6. RowBounds.class, ResultHandler.class}
    7. )
    8. )
    9. public class PageInterceptor implements Interceptor {

    拦截器接口触发时机

  • Executor ```java public interface Executor {

    ResultHandler NO_RESULT_HANDLER = null;

    int update(MappedStatement ms, Object parameter) throws SQLException;

    List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;

    List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;

    Cursor queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;

    List flushStatements() throws SQLException;

    void commit(boolean required) throws SQLException;

    void rollback(boolean required) throws SQLException;

    CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);

    boolean isCached(MappedStatement ms, CacheKey key);

    void clearLocalCache();

    void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);

    Transaction getTransaction();

    void close(boolean forceRollback);

    boolean isClosed();

    void setExecutorWrapper(Executor executor);

}

  1. - ResultSetHandler
  2. ```java
  3. public interface ResultSetHandler {
  4. //该方法会在除存储过程及返回值类型为
  5. Cursor<T>(org.apache.ibatis.cursor.Cursor<T>)以外的查询方法中被调用
  6. <E> List<E> handleResultSets(Statement stmt) throws SQLException;
  7. // 该方法是3.4.0版本中新增加的,只会在返回值类型为Cursor<T>的查询方法中被调用,
  8. <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;
  9. // 该方法只在使用存储过程处理出参时被调用
  10. void handleOutputParameters(CallableStatement cs) throws SQLException;
  11. }
  • StatementHandler ```java public interface StatementHandler {

    // 该方法会在数据库执行前被调用,优先于当前接口中的其他方法而被执行 Statement prepare(Connection connection, Integer transactionTimeout)

    1. throws SQLException;

    // 该方法在prepare方法之后执行,用于处理参数信息 void parameterize(Statement statement)

    1. throws SQLException;

    // 在全局设置配置defaultExecutorType=”BATCH”时,执行数据操作才会调用该方法, void batch(Statement statement)

    1. throws SQLException;

    int update(Statement statement)

    1. throws SQLException;

    // 执行SELECT方法时调用 List query(Statement statement, ResultHandler resultHandler)

    1. throws SQLException;

    // 该方法是3.4.0版本中新增加的,只会在返回值类型为Cursor的查询中被调用 Cursor queryCursor(Statement statement)

    1. throws SQLException;

    BoundSql getBoundSql();

    ParameterHandler getParameterHandler();

}

  1. - ParameterHandler
  2. ```java
  3. public interface ParameterHandler {
  4. Object getParameterObject();
  5. void setParameters(PreparedStatement ps)
  6. throws SQLException;
  7. }