MyBatis
public class Employee {
private Integer id;
private String eName;
private Integer age;
private String sex;
}
返回 Integer 类型结果
EmployeeMapper.java
/**
* 查询员工总数
* @return 员工总数
*/
Integer getEmpCount();
EmployeeMapper.xml
<!--查询员工总数-->
<!--MyBatis将常用的Java类型,都起了别名,因此不需要写全类名-->
<select id="getEmpCount" resultType="Integer">
select count(*) from employee
</select>
测试
//查询员工总数
Integer count = employeeMapper.getEmpCount();
System.out.println(count);
返回 Map 类型结果
返回的 Map 集合中只有一个元素
- 当 Map 集合中只有一个对象时,可以不指定 key,映射文件 resultType 的值要为 Map 类型
EmployeeMapper.java
/**
* 根据id获取Map集合形式的员工信息
* @param id
* @return 某个员工的Map集合
*/
//当Map集合中只有一个对象时,可以不指定key,映射文件resultType的值要为Map类型
Map<String,Employee> getEmpMapById(String id);
EmployeeMapper.xml
<!--以Map集合形式查询某个员工的信息-->
<select id="getEmpMapById" resultType="java.util.HashMap">
select * from employee where id = #{id}
</select>
测试
//以Map集合方式获取一个员工信息
Map<String, Employee> employee = employeeMapper.getEmpMapById("3");
System.out.println(employee);
返回的 Map 集合中有多个元素
- 当 Map 集合中有多个对象时,要通过
@MapKey指定查询结果中的哪个属性为 key。 - 若指定的 key 不存在,则 key=null。
- 映射文件 resultType 的值可以为 Map 类型,也可以为 Map 的 Value 类型。
EmployeeMapper.java
/**
* 查询员工信息
* @return 以Map集合返回Employee
*/
//当Map集合中有多个对象时,要通过@MapKey的value属性指定谁为key,
//若指定的key不存在,则key=null,且使用该注解后,映射文件resultType的值可以不为Map类型
@MapKey(value="id")//让查询结果中的id作为key
Map<String,Employee> getEmpMaps();
<!--以Map集合形式查询全部员工信息-->
<select id="getEmpMaps" resultType="Employee"><!--resultType="java.util.HashMap"也可以-->
select * from employee
</select>
测试
//以Map集合方式获取全部员工信息
Map<String, Employee> empMaps = employeeMapper.getEmpMaps();
System.out.println(empMaps);
传入多个参数
使用 MyBatis 默认的键获取参数
当方法中形参的个数大于1时,MyBatis 会将参数封装为 Map 对象,key 按照形参的顺序依次为arg0-argN或param1-paramN,在配置文件中可以根据 key 获取对应的参数值。
EmployeeMapper.java
/**
* 根据id和name获取Employee
* @param id
* @param name
* @return Employee
*/
//当传递多个参数时,MyBatis会将参数封装为Map对象,键为arg0-argN或param1-paramN
Employee getEmployeeByIdAndName(String id, String name);
EmployeeMapper.xml
<!--Employee getEmployeeByIdAndName(String id, String name);-->
<select id="getEmployeeByIdAndName" resultType="com.mcc.MyBatis.bean.Employee">
select * from employee where id = #{param1} and ename = #{param2}
</select>
测试
//根据id和name获取员工信息
Employee employee = employeeMapper.getEmployeeByIdAndName("3", "mcc");
System.out.println(employee);
使用 @Param 自定义键
可以通过@Param注解,自定义参数在 Map 集合中的 key。
EmployeeMapper.java
/**
* 根据name和age获取Employee
* @param name
* @param age
* @return Employee
*/
//通过@Param注解,指定参数在Map集合中的key
Employee getEmployeeByNameAndAge(@Param("eName") String name, @Param("age") Integer age);
EmployeeMapper.xml
<!--Employee getEmployeeByNameAndAge(@Param("eName") String name, @Param("age") String age);-->
<select id="getEmployeeByNameAndAge" resultType="Employee">
select * from employee where ename = #{eName} and age = #{age}
</select>
测试
//根据name和age获取员工信息
Employee employee = employeeMapper.getEmployeeByNameAndAge("admin", 20);
System.out.println(employee);
参数传递自定义 Map 集合
EmployeeMapper.java
/**
* 根据Map获取员工信息
* @param map
* @return Employee
*/
Employee getEmpByMap(Map<String,Object> map);
EmployeeMapper.xml
<!--Employee getEmpByMap(Map<String,Object> map);-->
<select id="getEmpByMap" resultType="Employee">
select * from employee where id = #{id} and sex = #{sex}
</select>
测试
//根据Map查询员工信息,假设根据id和sex查找
Map<String,Object> map = new HashMap<String,Object>();
map.put("id",1);
map.put("sex","男");
Employee employee = employeeMapper.getEmpByMap(map);
System.out.println(employee);
多对一查询
Employee.java
public class Employee {
private Integer id;
private String eName;
private Integer age;
private String sex;
private Department dept;
}
Department.java
public class Department {
private String id;
private String dName;
private List<Employee> empList;
}
自定义映射关系
需求:获取所有员工以及所属的部门信息
当返回的对象包括其他对象时,如 Employee 中包含 Department 对象,需要使用resultMap自定义映射,标签中的中属性:
id:设置主键的映射关系result:设置非主键字段的映射关系column:查询到的字段名property:需要映射到的 JavaBean 的属性,支持级联赋值,如为 Employee 对象的 Department dept 属性赋值,可以写成dept.属性
EmpDeptMapper.java
/**
* 获取每个部门的所有员工
* @return List<Employee>
*/
List<Employee> getDeptAllEmps();
EmpDeptMapper.xml
<resultMap id="EmpMap01" type="Employee">
<!--id:设置主键的映射关系-->
<id column="eid" property="id"/>
<!--result:设置非主键字段的映射关系-->
<result column="eName" property="eName"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<result column="did" property="dept.id"/>
<result column="dName" property="dept.dName"/>
</resultMap>
<!--List<Employee> getDeptAllEmps();-->
<select id="getDeptAllEmps" resultMap="EmpMap02">
select e.id eid,e.eName,e.age,e.sex,d.id did,d.dName
from department d
left join employee e
on d.id = e.departmentId
</select>
测试:
List<Employee> employees = empDeptMapper.getDeptAllEmps();
System.out.println(employees);
使用 association 实现自定义映射
上述情况,为 Employee 的 Department 属性赋值时,可以使用association标签实现,属性:
property:为哪个属性赋值javaType:该属性的 java 类型
EmpDeptMapper.xml
<resultMap id="EmpMap02" type="Employee">
<id column="eid" property="id"/>
<result column="eName" property="eName"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<association property="dept" javaType="com.mcc.MyBatis.bean.Department">
<id column="did" property="id"/>
<result column="dName" property="dName"/>
</association>
</resultMap>
<!--List<Employee> getDeptAllEmps();-->
<select id="getDeptAllEmps" resultMap="EmpMap02">
select e.id eid,e.eName,e.age,e.sex,d.id did,d.dName
from department d
left join employee e
on d.id = e.departmentId
</select>
分步查询
分步查询:将一次复杂查询分解为两次简单查询,将第一次的查询结果作为参数,传入第二次查询中,最后返回最终结果。
分步查询需要使用association或collection标签中的select属性:
select:第二步查询需要调用的方法的全类名column:传入第二步调用的方法中的参数
需求:获取指定 id 的员工以及所属的部门信息
步骤:首先先查询指定 id 的员工信息,再将员工的 departmentId 作为参数(第二步的查询条件)传递给查询部门信息的方法
EmpDeptMapper.java
/**
* 根据id查询员工信息,使用分步查询完成
* @param id
* @return Employee
*/
Employee getEmpByIdStep(String id);
DepartmentMapper.java
/**
* 根据id获取部门信息
* @param id
* @return Department
*/
Department getDept(String id);
EmpDeptMapper.xml
<resultMap id="EmpStepMap" type="Employee">
<id column="id" property="id"/>
<result column="eName" property="eName"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<!--执行 DepartmentMapper.java 中的 getDept() 方法,获取部门信息-->
<association property="dept" select="com.mcc.MyBatis.mapper.DepartmentMapper.getDept" column="did"/>
</resultMap>
<!--Employee getEmpByIdStep(String id);-->
<select id="getEmpByIdStep" resultMap="EmpStepMap">
select id,eName,age,sex,departmentId did from employee where id = #{id}
</select>
DepartmentMapper.xml
<mapper namespace="com.mcc.MyBatis.mapper.DepartmentMapper">
<select id="getDept" resultType="com.mcc.MyBatis.bean.Department">
select id,dName from department where id = #{id}
</select>
</mapper>
一对多查询
Employee.java
public class Employee {
private Integer id;
private String eName;
private Integer age;
private String sex;
private Department dept;
}
Department.java
public class Department {
private String id;
private String dName;
private List<Employee> empList;
}
使用 collection 实现自定义映射
需求:根据 id 查询部门信息,包括部门内的所有员工
需要使用到collection标签,改标签内的属性:
property:为哪个属性赋值,该属性为集合类型ofType:集合内存储的元素的类型
EmpDeptMapper.java
/**
* 根据部门id获取部门及部门内所有员工信息
* @param id
* @return Department
*/
Department getDeptEmpsById(String id);
EmpDeptMapper.xml
<resultMap id="DeptEmps01" type="Department">
<id column="did" property="id"/>
<result column="dName" property="dName"/>
<!--
collection:处理数据是集合的问题,即一对多的问题
ofType:指定集合中保存的数据类型,不需要指定javatype
-->
<collection property="empList" ofType="Employee">
<id column="eid" property="id"/>
<result column="eName" property="eName"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
</collection>
</resultMap>
<!--Department getDeptEmpsById(String id);-->
<select id="getDeptEmpsById" resultMap="DeptEmps01">
select d.id did,d.dName,e.id eid,e.eName,e.age,e.sex,e.departmentId
from department d left join employee e
on d.id = e.departmentId
where d.id = #{id}
</select>
测试:
Department dept = empDeptMapper.getDeptById("RS");
System.out.println(dept);
分步查询
可以使用分步查询,实现上面的需求:
步骤:先根据 id 查找部门信息,再根据 id 查找部门内的所有员工
使用collection标签的select属性,指定第二步要执行的方法。
EmpDeptMapper.java
/**
* 根据id查找部门
* @param id
* @return Department
*/
Department getDeptById(String id);
/**
* 根据部门id查找所有员工
* @param departmentId
* @return
*/
List<Employee> getDeptEmpsStepById(String departmentId);
EmpDeptMapper.xml
<resultMap id="DeptEmps02" type="Department">
<id column="id" property="id"/>
<result column="dName" property="dName"/>
<collection property="empList" select="com.mcc.MyBatis.mapper.EmpDeptMapper.getDeptEmpsStepById" column="id"/>
<!--
当查询的条件有多个时,可以通过Map形式传递参数,如:根据id和dName查询,则column="{id=id,dName=dName}",
此时,select的另外一个sql语句中,#{}要根据传递的key获取传递的参数
-->
</resultMap>
<!--使用分步查询,根据部门id查找该部门的信息,以及该部门下的全部员工-->
<!--Department getDeptById(String id);-->
<select id="getDeptById" resultMap="DeptEmps02">
select id,dName from department where id = #{id}
</select>
<!--List<Employee> getDeptEmpsStepById(String departmentId);-->
<select id="getDeptEmpsStepById" resultType="Employee">
select id,eName,age,sex,departmentId from employee where departmentId = #{departmentId}
</select>
分步查询的延迟加载
设置延迟加载
什么是延迟加载?
- 设置延迟加载,只有用到查询到的属性时,才会执行sql语句,没有用到时,不会执行
- 延迟加载只有在分步查询中才会生效
实现方式:
在核心配置文件 mybatis-config.xml 中,配置settings:
lazyLoadingEnabled:是否开启延迟加载,默认为falseaggressiveLazyLoading:是否查询全部数据,默认为true- lazyLoadingEnabled=“true” 时,aggressiveLazyLoading=“false”
lazyLoadingEnabled=“false” 时,aggressiveLazyLoading=“true”
mybatis-config.xml
<settings>
<!-- mapUnderscoreToCamelCase:下划线格式转换为驼峰格式,如user_name => userName -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--
设置延迟加载,只有用到查询到的属性时,才会执行sql语句,没有用到时,不会执行
延迟加载只有在分步查询中才会生效
lazyLoadingEnabled:是否开启延迟加载,默认为false
aggressiveLazyLoading:是否查询全部数据,默认为true
lazyLoadingEnabled="true"时,aggressiveLazyLoading="false"
lazyLoadingEnabled="false"时,aggressiveLazyLoading="true"
-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
测试:
Employee emp = empDeptMapper.getEmpByIdStep("5");
//测试延迟加载
System.out.println(emp.geteName());//只执行查询员工信息的语句,不执行查询员工所属部门的语句
System.out.println(emp.getDept());//执行查询员工所属部门的语句
单独设置某条语句的延迟加载情况
在 mybatis-config.xml 中设置的延迟加载对项目中所有的分步查询都有效,可以在分步查询语句中通过fetchType属性,设置或修改本条语句的延迟加载情况。
fetchType="lazy":开启延迟加载fetchType="eager":关闭延迟加载
<resultMap id="EmpStepMap" type="Employee">
<id column="id" property="id"/>
<result column="eName" property="eName"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<!--执行 DepartmentMapper.java 中的 getDept() 方法,获取部门信息-->
<association property="dept" select="com.mcc.MyBatis.mapper.DepartmentMapper.getDept" column="did" fetchType="lazy"/>
</resultMap>
本文详细介绍了MyBatis中返回不同类型的查询结果,包括Integer和Map,以及如何处理Map集合中的单个和多个元素。此外,还讲解了如何传入多个参数,使用@Param自定义键,以及参数传递自定义Map集合的方法。同时,深入探讨了多对一查询和一对多查询的实现,包括association和collection的使用。最后,阐述了分步查询的实现和延迟加载的配置,以及如何单独设置某条语句的延迟加载情况。
1201

被折叠的 条评论
为什么被折叠?



