Mybatis返回值接收
可以使用两种方式进行参数的接收
resultType
resultMap
这两种分别都是需要在Mapper.xml文件中去设置的
当结果是一个简单的对象或者list
或者map
,对象中没有嵌套对象,或者集合时,就可以直接使用resultType
反之如果需要返回的值是一个复杂对象,其中包含list或者map的时候,就需要使用resultMap
去确定返回值格式
1 使用 resultType
<sql id="basicSelect">
id,name,age,address,emp_detail
</sql>
-
查询单个Map对象
<select id="selectUsers" resultType="map"> select id, username, hashedPassword from some_table where id = #{id} </select>
Map selectUsers(Long id);
-
查询具体单个对象
<select id="selectEmpById" resultType="cn.sycoder.domain.Employee"> select <include refid="basicSelect"></include> from employee where id = #{id} </select> <!-- 定义sql--> <sql id="basicSelect"> id,name,age,address,emp_detail </sql>
Employee selectEmpById(Long id);
-
查询集合对象
<select id="selectEmp" resultType="cn.sycoder.domain.Employee"> select <include refid="basicSelect"></include> from employee where id = #{id} </select>
List<Employee> selectEmp(Long id);
-
查询单个值
<select id="selectCount" resultType="java.lang.Integer"> select count(*) from employee </select>
Integer selectCount();
2 使用 resultMap
2.1 简单使用
-
应用场景:实体类属性和数据库列名不匹配的时候(比如,数据库采用经典命名法,java 使用驼峰命名法的时候)
<resultMap id="basicMap" type="cn.sycoder.domain.Employee"> <!-- 设置数据库id 的对应字段--> <id property="id" column="id"></id> <result property="empDetail" column="emp_detail"></result> <result property="name" column="name"></result> </resultMap> <select id="selectEmpById" resultMap="basicMap"> select <include refid="basicSelect"></include> from employee where id = #{id} </select>
-
解决方式2
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
-
id & result
<id property="id" column="post_id"/> <result property="subject" column="post_subject"/>
-
id & result 属性
属性 描述 property
映射到列结果的字段或属性。如果 JavaBean 有这个名字的属性(property),会先使用该属性。否则 MyBatis 将会寻找给定名称的字段(field)。无论是哪一种情形,你都可以使用常见的点式分隔形式进行复杂属性导航。 比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。 stu.name column
数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName)
方法的参数一样。javaType
一个 Java 类的全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。
2.2多结果集处理前期准备
-
新建学生和班级表
create table class ( id bigint auto_increment primary key, name varchar(64) null ); create table student ( id bigint auto_increment primary key, name varchar(64) null, age int null, class_id bigint null, constraint student_class_id_fk foreign key (class_id) references class (id) ); insert into class values (null,'软工1班'),(null,'计科2班'); insert into student (id, name, age,class_id) values (null,'sy',18,1),(null,'zs',19,1),(null,'zz',20,1),(null,'小明',22,2);
2.3一对多处理
-
collection :使用 collection 就可以获取到多个结果集对象
-
一个班级对应多个学生
-
操作
-
第一步,新建 mapper 方法
public interface ClassMapper { MyClass getById(Long id); }
-
第二步,编写 xml
<resultMap id="basicMap" type="cn.sycoder.domain.MyClass"> <id property="id" column="id"></id> <result property="name" column="name"></result> <!-- 获取学生信息信息--> <collection property="stus" ofType="cn.sycoder.domain.Student"> <id property="id" column="sId"></id> <result property="name" column="sName"></result> <result property="age" column="age"></result> <result property="classId" column="class_id"></result> </collection> </resultMap> <select id="getById" resultMap="basicMap"> select c.*,s.id sId,s.name sName,s.age,s.class_id from class c left join student s on c.id = s.class_id where c.id = #{id} </select>
-
2.4多对一的处理
-
关联(association):如果我的类里面有其它对象的关联关系,可以使用 association 来进行操作
属性 描述 property
映射到列结果的字段或属性。如果用来匹配的 JavaBean存在给定名字的属性,那么它将会被使用。否则 MyBatis 将会寻找给定名称的字段。无论是哪一种情形,你都可以使用通常的点式分隔形式进行复杂属性导航。比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。 javaType
一个 Java 类的完全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。 -
传统操作
-
使用级联操作
<resultMap id="basicMap" type="cn.sycoder.domain.Student"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="age" column="age"></result> <result property="classId" column="class_id"></result> <result property="cls.id" column="cId"></result> <result property="cls.name" column="cName"></result> </resultMap> <select id="listAllStus" resultMap="basicMap"> select stu.*,c.id cId,c.name cName from student stu left join class c on stu.class_id = c.id </select>
-
-
使用 association 操作
-
代码
<resultMap id="AssociationMap" type="cn.sycoder.domain.Student"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="age" column="age"></result> <result property="classId" column="class_id"></result> <association property="cls" javaType="cn.sycoder.domain.MyClass"> <id property="id" column="cId"></id> <result property="name" column="cName"></result> </association> </resultMap> <select id="listAllStusByAssociation" resultMap="AssociationMap"> select stu.*,c.id cId,c.name cName from student stu left join class c on stu.class_id = c.id </select>
-
3 嵌套 select 查询
- 以多条sql 的方式执行
3.1关联关系 assciation select
-
查询学生信息,包含班级信息
<resultMap id="AssociationSelectMap" type="cn.sycoder.domain.Student"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="age" column="age"></result> <result property="classId" column="class_id"></result> <association property="cls" column="class_id" select="cn.sycoder.mapper.StudentMapper.getClassById"/> </resultMap> <select id="listAllStusByAssociationSelect" resultMap="AssociationSelectMap"> select * from student </select> <select id="getClassById" resultType="cn.sycoder.domain.MyClass"> select * from class where id = #{id} </select>
-
如果关联的是多个结果集使用 resultSet
属性 描述 column
当使用多个结果集时,该属性指定结果集中用于与 foreignColumn
匹配的列(多个列名以逗号隔开),以识别关系中的父类型与子类型。foreignColumn
指定外键对应的列名,指定的列将与父类型中 column
的给出的列进行匹配。resultSet
指定用于加载复杂类型的结果集名字。 <resultMap id="blogResult" type="Blog"> <id property="id" column="id" /> <result property="title" column="title"/> <association property="author" javaType="Author" resultSet="authors" column="author_id" foreignColumn="id"> <id property="id" column="id"/> <result property="username" column="username"/> <result property="password" column="password"/> <result property="email" column="email"/> <result property="bio" column="bio"/> </association> </resultMap>
3.2 collection select
-
需求:通过班级去查学生,使用嵌套 select 查询
<resultMap id="collectionSelect" type="cn.sycoder.domain.MyClass"> <id property="id" column="id"></id> <result property="name" column="name"></result> <!-- 获取学生信息信息--> <collection property="stus" ofType="cn.sycoder.domain.Student" select="getStudentByClassId" column="id"/> </resultMap> <select id="getByClassId" resultMap="collectionSelect"> select * from class where id = #{id} </select> <select id="getStudentByClassId" resultType="cn.sycoder.domain.Student"> select * from student where class_id = #{id} </select>
3.3 关联查询的总结
- 优点:
- 可以实现延迟加载,前提是要配置
- sql 写起来变得简单了
- 缺点:
- 发起了多条 sql,正常查询只发起一条sql