数据库查询结果集有三种映射方式:
1、ResultMap结果集映射;
2、构造器映射;
3、自动映射;
1、ResultMap结果集映射
1.1Mapper.xml中:
利用resultMap元素配置,必须为resultMap元素指定id和type属性
id属性作用:与sql语句连接
type属性作用:指定结果集映射对象
resultMap一般有两个子元素
id子元素:定义对象的标识属性
result子元素:定义对象的一般属性
他们俩都有如下属性
*column:指定列名(数据库中)
*property:指定对应的属性名(Java程序中)
javaType:指定java类型,一般无需指定,MyBatis会自动推断
jdbcType:指定数据列的jdbc类型,一般无需指定,MyBatis会自动推断
typeHandler:类型处理器,一般无需指定,MyBatis内置了大量的类型吃利器,自定类型处理器可能需要指定(也可以在mybatis-config.xml中指定)
<resultMap id="rm" type="User">
<id column="uesr_id" property="userId" />
<result column="user_age" property="userAge" />
<result column="user_name" property="userName"/>
<result column="user_datetime" property="userDate" />
</resultMap>
1.2注解中:
原理差不多,需要注意的是定义对象的标识属性的方式,是在@Result中指定id=true。
@Select("select * from user where user_id between #{s} and #{e} ")
//注意注解名是 @Results不是ResultMap
@Results({
@Result(column = "user_id",property = "userId",id = true),
@Result(column = "user_name",property = "userName"),
@Result(column = "user_datetime",property = "userDate"),
@Result(column = "user_age",property = "userAge")
HashSet<User> queryUser2(@Param("s") int startId, @Param("e") int endId);
})
在xml配置中的id和result元素有的属性,@Result注解中都有,除此之外,@Result额外有one和many两个属性,关联映射中会用到,这里不展开。
2、构造器映射:
如果结果集封装对象中有无参的构造器,那么会默认调用这个无参构造器创建对象,然后通过set,get方法对对象的属性进行操作(所以如果写了有参数的构造器,一定要记得写无参数的构造器,否则很有可能会报错:可以看这篇文章:MyBatis数据库列名和封装结果集对象的属性名不同名并且没有配置结果集映射也能正确完成数据库和结果集对象之间的映射)。
除此之外,我们也可以指定用哪个构造器创建结果集映射对象,而且可以利用这个来进行结果集映射,而不用一一地用列名和属性名进行对应。
2.1Mapper.xml中:
利用resultMap的子元素constructor元素:
在constructor下有两个子元素:idArg,arg
他们俩都有如下属性
column
javaType:构造器参数对应的java类型
jdbcType
typeHadler
name:指定构造器参数名
select:引用另一个select元素的id,后面再介绍关联映射的时候回想详细介绍
resultMap:引用另一个resultMap元素的id,后面再介绍关联映射的时候回想详细介绍
<resultMap id="rm" type="User">
<constructor>
<idArg column="user_id" javaType="int"/>
<arg column="user_name" javaType="String"/>
</constructor>
<result column="user_age" property="userAge" />
<result column="user_datetime" property="userDate" />
</resultMap>
当然,因为没有指定name属性,所以这些数据与构造器关联的方式是按顺的,也就是构造器参数顺序必须与constructor元素中idArg /arg 的顺序对应。
如果需要使用name指定构造器参数,那么必须为构造器参数指定@Param注解或者用java8的-parameters进行编译,否则java不会记住方法参数。
2.2注解中:
原理差不多,需要注意的是定义对象的标识属性的方式,是在@ConstructorArgs中指定id=true。另外javaType不是字符串而是指定class
@Select("select * from user where user_id between #{s} and #{e} ")
@ConstructorArgs({
@Arg(column="user_name",name = "name",javaType=String.class),
@Arg(column="user_id",name = "id",javaType=Integer.class,id = true)
})
@Results({
@Result(column = "user_age",property = "userAge"),
@Result(column = "user_datetime",property = "userDate")
})
HashSet<User> queryUser2(@Param("s") int startId, @Param("e") int endId);
当然xml能指定的属性,注解中都可
3、自动映射(同名映射/驼峰映射)
MyBatis支持三种自动映射策略:
NONE:不使用自动映射
PARTIAL:部分自动映射,只自动映射没有定义嵌套结果集的结果集。(默认)
FULL:完全自动映射。
在配置xml文件中的setting的autoMappingBehavior配置,一般无需更改。
<settings>
<setting name="autoMappingBehavior" value="NONE"/>
</settings>
自动映射规则:若数据库中的列名和java程序中的属性一致那么MyBatis会自动映射。
当然,MyBatis绝对不止这么聪明,他还能进行驼峰映射,例如:
数据库列名的 user_id 会自动与java程序属性的 userId进行映射。
不过这个功能要在mybatis-config.xml中配置。
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>