龙空技术网

SpringBoot整合Mybatis-Plus源码分析(十) SqlSession 查询流程

爱好编程的程序员老徐 124

前言:

当前大家对“session值作为数据库条件”都比较注重,我们都需要学习一些“session值作为数据库条件”的相关知识。那么小编同时在网络上汇集了一些关于“session值作为数据库条件””的相关知识,希望小伙伴们能喜欢,朋友们快快来了解一下吧!

从上文分析到调用UserDao的保存方法会调用DefaultSqlSession的insert方法继而调用到SimpleExecutor的doUpdate方法,本文我们分析查询方法,根据经验分析查询会调用到SimpleExecutor的doQuery方法,该方法截图如下:

SimpleExecutor的doQuery方法截图

我们从该方法开始分析,首先还是创建StatementHandler,取出sql语句设置占位符标志,然后调用PreparedStatement对象的execute执行sql语句查询,这些我们在上一篇文章已经详细分析了,感兴趣的可以去看看,接着调用resultSetHandler的handleResultSets方法处理数据库查询结果,该ResultSetHandler接口的实现类是DefaultResultSetHandler,

该方法的截图如下:

DefaultResultSetHandler的handleResultSets方法截图

调用getFirstResultSet方法创建一个ResultSetWrapper对象。参数是ResultSet和Configuration对象,从Configuration对象获取TypeHandlerRegistry对象,赋值给成员变量TypeHandlerRegistry,获取列个数,从1开始循环到列个数,把列名添加到字符串集合中,获取jdbcType类型添加到List<JdbcType>集合中,比如字段类型是varchar,添加到集合中,把字段的java表示类型添加到classNames字符串集合中,比如字段类型是vachar,对应的java类型是java.lang.String,然后执行返回到handleResultSets方法中,调用对象MappedStatement的getResultMaps方法获取ResultMap对象的集合,在Mybaits中ResultMap对象于定义SQL查询结果与Java对象之间的映射关系。它提供了一种灵活的方式来处理复杂的查询结果,并将查询结果映射到对应的Java对象中。ResultMap的主要作用包括:

1.对象关系映射(ORM):ResultMap定义了查询结果中每列与Java对象属性之间的映射规则。它可以指定每个列如何映射到Java对象的属性,包括属性名称、类型转换、关联关系等。

2.简化映射配置:通过使用ResultMap,可以避免在每个查询语句中重复定义映射规则。相反,可以在ResultMap中定义一次,并在多个查询中重复使用。这样可以减少重复的配置代码,并提高维护性。

3.处理复杂查询结果:ResultMap可以处理复杂的查询结果,例如多表关联查询或查询结果包含嵌套对象。可以在ResultMap中定义关联关系、嵌套映射等,以便将查询结果正确地映射到对应的Java对象中。

4.支持字段别名:如果查询结果中的列名与Java对象的属性名不完全匹配,可以使用ResultMap的<result>元素的属性来定义字段别名。这样可以解决列名与属性名不一致的问题,并确保正确的映射。

接着向下调用我们只看重要的方法,DefaultResultSetHandler对象的getRowValue方法,接着调用方法createResultObject,该方法是最重要的核心方法,它反射创建了要返回的对象类,该方法截图如下:

DefaultResultSetHandler的createResultObject方法截图

通过调用resultMap.getType()获取返回类型,本例子中我们假定返回的类型是一个com.xulifeng.exercise.aliasepackage.User类型,判断该类型是否是接口或者有默认构造方法,如果是调用ObjectFactory的create方法反射创建一个该类型的对象。调用MybatisConfiguration对象的newMetaObject方法传入发射创建的对象得到一个MetaObject对象,MetaObject是一个用于封装Java对象的元数据工具类,该对象的作用用于简化对Java对象属性的操作。它提供了一种方便的方式来访问和操作Java对象的属性,无论是普通Java对象还是集合对象,该对象的主要作用是:

1.属性获取和设置:MetaObject提供了一种方便的方式来获取和设置Java对象的属性值,无论是公共属性还是私有属性。通过MetaObject,可以避免使用繁琐的反射代码,而是通过简单的API调用来实现属性的读取和赋值。

2.嵌套属性访问:如果Java对象中存在嵌套属性(例如对象的属性中包含其他对象),MetaObject可以递归地访问和操作这些嵌套属性。可以通过“属性名.子属性名”的方式来访问嵌套属性,并进行属性的读取和赋值操作。

3.集合属性操作:对于集合属性(如List、Map等),MetaObject提供了一组专门的方法来访问和操作集合中的元素。可以使用这些方法来获取集合的大小、遍历集合元素、添加、删除和更新集合中的元素。

4.自动类型转换:MetaObject可以自动处理属性值的类型转换。例如,当想将一个字符串值赋给一个整型属性时,MetaObject可以自动将字符串转换为整型,以确保类型的匹配。

5.元数据操作:通过MetaObject,可以获取Java对象的元数据信息,如属性名、属性类型、getter和setter方法等。这样可以实现一些基于元数据的通用操作,如动态生成SQL语句或根据属性名动态生成查询条件。

总之,MetaObject在MyBatis中起到了简化Java对象属性访问和操作的作用。它提供了便捷的方式来读取、写入和操作Java对象的属性值,尤其适用于处理复杂对象结构和集合属性。通过使用MetaObject,可以避免手动编写繁琐的反射代码,提高代码的可读性和维护性。

接着向下分析,下面开始调用applyAutomaticMappings方法,该方法截图如下:

DefaultResultSetHandler的applyAutomaticMappings方法截图

获取数据库列名和属性名的对应关系比如column是name1,property是java字段属性值是name并指定TypeHandler类型,假定TypeHandler类型是StringTypeHandler,通过获取数据库name1列的值调用StringTypeHandler的getNullableResult方法,该方法返回的是一个Strng类型的值,该方法截图如下:

StringTypeHandler的getNullableResult方法

然后调用metaObject.setValue(mapping.property, value),把User对象的name属性值赋值为通过name1列查询到的值,这样User对象的name属性值就有值了,其他对象的属性也是这样的操作过程就不在重复,等所有属性赋值完成以后,执行调用链返回到DefaultResultSetHandler的callResultHandler方法,该方法截图如下:

DefaultResultSetHandler的callResultHandler方法截图

把得到User对象添加到上下文中,继而添加到DefaultResultSetHandler的成员属性 List<Object>中返回一个集合,判断集合个数是否是1,如果是调用list.get(0)获取一个对象返回,这适用于调用dao对象的selectById方法,分析到此SqlSession方法的查询流程就结束了。

总结:

本篇文章分析了SqlSession的查询执行流程,该流程主要是创建了StatementHandler对象,继而创建了ParameterHandler对象,由于本例子是查询操作需要把数据库查询到的字段映射到java实体类上故而多了一个DefaultResultSetHandler处理过程,该过程的主要逻辑是查找数据库字段和java字段的映射关系,调用不同的TypeHandler把查询到的值赋值到对应的java字段上,然后封装成集合返回给调用端,整个流程结束,下节我将分析插件机制和具体插件的执行流程,下节见。

标签: #session值作为数据库条件 #java session获取