简单介绍:
在之前我们在讲SQL映射文件中的映射查询语句的<select>标签的时候,对其中的四个常用属性的讲解并不是那么的透彻,今天就来详细的解释<select>的四个常用属性的具体含义以及<select>标签在进行查询的时候查询参数是如何传递的,以及查询出结果后是如何自动映射的。
使用方法:
<select id="SQL语句的唯一标识" resultType="传入参数类型" parameterType="结果集封装实体类">
select * from user where id = #{id}
</select>
我们对上面的每一个属性进行比较详细的讲解:
id:
在同一个命名空间下,这条SQL语句的唯一标识。在同一命名空间下,这个值不能重复,但是在不同的命名空间下,这个值是可以重复的。命名空间的概念就相当于Java中的类名,而id的值就相当于是类名,通过包名+类名的方式可以在所有文件中精确定位一条唯一的SQL映射语句
resultType:
翻译过来就是结果类型。表示当这条SQL语句查询完成之后返回的结果将要封装到哪一个POJP实体类中,如果之前配置过别名映射,这个地方填的就是POJO类的短别名,如果没有配置别名映射,这个地方填的就是POJO类的全限定类名。全限定类名就是包名+类名的方式定位唯一的类。
parameterType:
翻译过来就是参数类型。在我们的查询语句中会有一些参数是外部引用的,也就是使用#{}的方式,在花括号里面会有一些从外部引用的参数,这种#{}的写法在XML文件中表示引用外部的变量,而这个变量的来源就是取自于parameterType的值。
代码实现:
首先,我们就来实现一个非常简单的,根据id查询相应的数据,我们这次不使用接口化开发,而是使用最原本的MyBatis给我们提供的API来完成查询的动作:
可以看到,只要我们正确的配置SQL映射文件和MyBatis核心配置文件的<mappers>属性,以及在查询的时候正确的使用命名空间.唯一标识的方式正确的引用SQL语句,以及传递正确的参数,就能正确的查询出想要的结果,而我们这次讨论的问题在于两个。
1.我们的参数经历了什么?
2.他是怎么做到把MySQL的数据表信息和Java中的类映射到一起的。
文字讲解:
首先就是我们传递的参数经历了什么?
在我们编写SQL映射语句的时候,parameterType属性值对应的是我们的参数类型,上面我们写的是Int类型,也就是数字整形,那么这个参数从哪里来?
它来自于这里,也就是我们的查询方法的第二个参数,我们回想一下对于查询方法的参数介绍。第一个参数表示SQL映射语句的唯一标识,第二个参数就是我们在查询的时候会使用到的参数。所以这个参数的类型就是我们parameter的值,具体的值就是我们在调用方法的时候传进去的值,传进去之后它去了哪了呢?
去了这里。之前我们说狗,#{}这种写法表示引用外部的数据,这个外部的数据就是我们传递的参数,如果这个参数的类型和我们预设的数据类型不符合,也就是我们传入的参数的数据类型和我们在parameterType的值不同,就会报错,比如我们传入一个String类型:
他就会非常贴心的提醒我们,String类型不能被转换成Integer类型,就说明这是我们参数传递时候的类型错误。
在正常的传递进来之后,这个SQL语句就算是完整了,然后就可以开始查询,并最终会出现一个查询结果,然后就来到了我们的第二个问题。
MySQL中的表数据是怎么映射到我们的Java实体类的?
这个问题也非常的简单,之前我们说过。resultType的值就是用来帮助我们自动映射MySQL表数据和Java实体类的,而要完成自动映射的也是有条件的,那就是要求我们数据库表的列名和Java实体类的属性名要完全一致,并且数据类型也要一直,其中Java中的String类型对应MySQL中的varchar类型:
只有满足了这两个条件,并且将resultType的值设置为对应的Java实体类的之后才可以完成自动映射。如果这时候我改变一下数据类型,我们将Java实体类中的name的值改为int类型:
这时候再来进行查询,就会出现下面的效果:
他会告诉我们无法从字符串”张三“确定数据类型。这个张三是我们数据库的name字段的值,但是根据我们配置的自动映射规则,Java实体类student的name属性字段是int类型,而"张三”是字符串类型,两者类型并不匹配,所以会导致类型无法匹配的错误。
所以,我们可以画一张图来最终演示一下这一整个的过程:
图画的略微有一些抽象,但是我觉得问题不大,能理解就好