文章目录
- 六**、MyBatis的各种查询功能**
- 6.1、查询一个实体类的对象
- 6.2、查询一个list集合
- 6.3、查询单个数据
- 6.4、查询一条数据为Map集合
- 6.5、查询多条数据为Map集合
- 七、**特殊SQL的执行**
- 7.1、模糊查询
- 7.2、批量删除
- 7.3、动态设置表名
- 7.4、添加功能获取自增的主键
- 八、**自定义映射resultMap 一对一、多对一、一对多、多对多**
- 8.1、resultMap处理字段和属性的映射关系
- 8.2、一对一映射处理
- 8.3、多对一映射处理
- 8.4、一对多映射处理 部门 -->员工
- 8.5、多对多映射关系
六**、MyBatis的各种查询功能**
6.1、查询一个实体类的对象
6.2、查询一个list集合
- 当查询的数据为多条记录时,不能使用实体类作为返回值,否则会抛出异常:TooManyResultsException,但是如果查询的数据只有一条,可以使用实体类或集合作为返回值
6.3、查询单个数据
6.4、查询一条数据为Map集合
6.5、查询多条数据为Map集合
-
方式一
- 将表中的数据以map集合的方式查询,一条数据对应一个map;如果有多条数据,就会产生多个map集合,此时可以将这些map放在一个list集合中获取
-
方式二
- 如果有多条数据,可以将每条数据转换的map集合放在一个大的map集合中,但是必须要通过@MapKey注解来完成。将查询的某个字段的值作为大的Map集合的键(key)
七、特殊SQL的执行
7.1、模糊查询
<select id="方法名" resultType="返回值类型">
SELECT *
from user
where username like "%"#{name}"%"
</select>
7.2、批量删除
<delete id="deleteAll">
delete
from user
where id in #{ids}
</delete>
7.3、动态设置表名
<select id="getUserList" resultType="object">
SELECT *
from ${tableName}
</select>
7.4、添加功能获取自增的主键
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (username, password)
VALUES (#{username}, #{password})
</insert>
八、自定义映射resultMap 一对一、多对一、一对多、多对多
8.1、resultMap处理字段和属性的映射关系
如果字段名和实体类中的属性名不一致的情况下,可以通过resultMap设置自定义映射。
- 可以通过为字段起别名的方式,别名起成和属性名一致。保证字段名和实体类中的属性名一致
<select id="getEmpByEmpId" resultType="emp">
select emp_id empId,emp_name empName,age,sex from emp where emp_id = #{empId}
</select>
- 如果字段名和实体类中的属性名不一致的情况下,但是字段名符合数据库的规则(使用_),实体类中使用的属性名符合java的规则(使用驼峰命名),可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中的数据时,自动将带下划线“_”的字段名转为驼峰命名
- user_name:userName
- emp_id:empId
<settings>
<!--将数据库字段名的下划线映射为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--Emp getEmpByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpByEmpId" resultType="emp">
select * from emp where emp_id = #{empId}
</select>
- 使用resutlMap自定义映射处理
<!--
resultMap:设置自定义的映射关系
id:唯一标识
type:处理映射关系的实体类的类型 一般使用MyBatis的别名
常用的标签
id:处理主键和实体类中属性的映射关系
result:处理普通字段和实体类中属性的映射关系
column:设置映射关系中的字段名,必须是sql查询出的某个字段
property:设置映射关系中的属性的属性名,必须是处理的实体类型中的属性名
-->
<resultMap id="empReslutMap" type="emp">
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
</resultMap>
8.2、一对一映射处理
人与身份证号
- 级联方式处理
/**
* 根据id查询人员信息
* @param id
* @return
*/
Person findPersonById(@Param("id") Integer id);
<!-- Person findPersonById(Integer id);-->
<select id="findPersonById" resultMap="IdCardWithPersonResult">
SELECT person.*,idcard.code
FROM person,idcard
WHERE person.card_id=idcard.id AND person.id=#{id}
</select>
<resultMap id="IdCardWithPersonResult" type="person">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="card.id" column="id"></result>
<result property="card.code" column="code"></result>
</resultMap>
- association
<resultMap id="IdCardWithPersonResult2" type="person">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<association property="card" javaType="IdCard">
<id property="id" column="id"></id>
<result property="code" column="code"></result>
</association>
</resultMap>
- 分步查询
<!--分步查询第一步-->
<!-- Person findPersonById3(@Param("id") Integer id);-->
<select id="findPersonById3" resultMap="IdCardWithPersonResult3">
select * from person where id=#{id}
</select>
<resultMap id="IdCardWithPersonResult3" type="person">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<!--
association:处理一对一或者多对一的映射关系(处理的实体类类型的属性)
property:设置需要处理映射关系的属性的属性名
javaType:设置要处理的属性的类型
column:第一步传递给第二步的字段,映射关系的表关联的字段
-->
<association property="card" javaType="IdCard" column="card_id"
select="com.qcby.mybatis.mapper.IdCardMapper.findCodeById">
</association>
</resultMap>
<!--分步查询的第二步-->
<!--IdCard findCodeById(@Param("id") Integer id);-->
<select id="findCodeById" resultType="idcard">
SELECT * from idcard where id=#{id}
</select>
8.3、多对一映射处理
场景模拟:
查询员工信息以及员工所对应的部门信息
使用resultMap自定义映射处理
处理多对一的映射关系:
-
级联方式处理
-
association
-
分步查询
- 级联方式处理
/**
* 获取员工以及所对应的部门信息
* @param empId
* @return
*/
Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);
<!-- Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
SELECT emp.*,dept.*
FROM emp
LEFT JOIN dept
ON emp.dept_id=dept.dept_id
WHERE emp.emp_id=#{empId}
</select>
<resultMap id="empAndDeptResultMap" type="emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="sex" property="sex"></result>
<result column="dept_id" property="dept.deptId"></result>
<result column="dept_name" property="dept.deptName"></result>
</resultMap>
@Test
public void testGetEmpAndDeptByEmpId(){
Emp emp = empMapper.getEmpAndDeptByEmpId(1);
System.out.println(emp);
}
- association
<resultMap id="empAndDeptResultMap" type="emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="sex" property="sex"></result>
<association property="dept" javaType="dept">
<id column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"></result>
</association>
</resultMap>
-
分步查询
-
根据员工id查询员工信息
emp接口中
/**
* 通过分步查询来查询员工以及所对应部门信息的第一步
* @param empId
* @return
*/
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);
dept接口中
/**
* 通过分步查询来查询员工以及所对应部门信息的第二步
* @param deptId
* @return
*/
Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);
emp映射文件中
<!--Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
select * from emp where emp_id = #{empId}
</select>
<resultMap id="empAndDeptByStepResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="sex" property="sex"></result>
<association property="dept" column="dept_id"
select="com.qcby.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
></association>
</resultMap>
dept映射文件中
<!--Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);-->
<select id="getEmpAndDeptByStepTwo" resultType="Dept">
select * from dept where dept_id = #{deptId}
</select>
测试
@Test
public void testGetEmpAndDeptByStepOne(){
Emp emp = empMapper.getEmpAndDeptByStepOne(1);
System.out.println(emp);
}
分步查询的优点:可以实现延迟加载(懒加载),但是必须在核心配置文件中设置全局配置信息:
lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有管理对象都会延迟加载
aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载,此时就可以实现按需加载,获取的数据是什么,就会执行相应的sql语句
此时可以通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”
8.4、一对多映射处理 部门 -->员工
没有级联方式的查询,只有collection 和分步查询
8.4.1 collection
dept接口
/**
* 查询部门以及部门中的员工信息
* @param deptId
* @return
*/
Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);
dept映射文件中
<!--Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);-->
<select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">
SELECT *
FROM dept
LEFT JOIN emp
ON dept.dept_id=emp.dept_id
WHERE dept.dept_id=#{deptId}
</select>
<resultMap id="deptAndEmpResultMap" type="dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<!--ofType:设置集合类型的属性中存储的数据的类型-->
<collection property="emps" ofType="emp">
<id column="emp_id" property="empId"></id>
<result column