兖州网站开发,如何自建网站入口,应不应该购买老域名建设新网站,网站开发怎么实现用户一对一发文字图片前言 上一篇文章中荔枝梳理了有关MyBatis的相关环境配置和核心配置文件及其模板的设置和生成#xff0c;而在这篇文章中荔枝会着重梳理MyBatis多种查询情况、特殊SQL执行以及两表联查时映射关系的处理。希望对需要的小伙伴有帮助~~~ 文章目录
前言
一、多种查询情况
1.1 查…前言 上一篇文章中荔枝梳理了有关MyBatis的相关环境配置和核心配置文件及其模板的设置和生成而在这篇文章中荔枝会着重梳理MyBatis多种查询情况、特殊SQL执行以及两表联查时映射关系的处理。希望对需要的小伙伴有帮助~~~ 文章目录
前言
一、多种查询情况
1.1 查询单条数据
1.2 查询多条数据
1.3 特殊SQL的执行
1.3.1 模糊查询
1.3.2 批量删除
1.3.3 动态设置表名
1.3.4 获取自增主键
二、自定义映射
2.1 解决字段名和属性名不一致的三种方案
2.2 多对一的映射关系
2.2.1 通过级联属性赋值解决多对一映射
2.2.2 通过association解决多对一映射问题
2.2.3 association分步查询解决多对一映射问题
2.2.4 延迟加载
2.3 一对多映射关系
2.3.1 Collection解决一对多映射关系
2.3.2 分步查询解决一对多映射关系
总结 一、多种查询情况 在MyBatis中对于数据库的查询来说如果查询出来的数据只有一条可以通过实体类对象或者集合list、map来接收如果查询的数据有多条则一定不能通过实体类来接收否则会抛出异常TooManyResultException。
1.1 查询单条数据
实体类对象
User getUserById(Param(id) Integer id);
list集合
ListUser getAllUser(Param(id) Integer id);map集合
MapString,Object getUserByIdToMap(Param(id) Integer id);
1.2 查询多条数据 list集合
ListUser getAllUser(Param(id) Integer id);map集合
ListMapString,Object getAllUserToMap(Param(id) Integer id);或者借助MapKey注解
MapKey(id) //把查询到的数据的某一个字段作为key查询到的所有数据作为值value
MapString,Object getAllUserToMap2(Param(id) Integer id);
1.3 特殊SQL的执行
在MyBatis中大多数的查询都可以使用#{}的格式来获取参数但是有一些特殊SQL的执行则不能直接采用#{}的格式。
1.3.1 模糊查询
采用${}格式
mapper namespacecom.crj.mapper.SQLMapper
!-- ListUser getUserByLike(Param(username) String username);--select idgetUserByLike resultTypeUserselect * from t_user where username like %${username}%/select
/mapper 采用concat拼接并采用#{}
mapper namespacecom.crj.mapper.SQLMapper
!-- ListUser getUserByLike(Param(username) String username);--select idgetUserByLike resultTypeUserselect * from t_user where username like concat(%,#{username},%)/select
/mapper
采用 拼接SQL
mapper namespacecom.crj.mapper.SQLMapper
!-- ListUser getUserByLike(Param(username) String username);--select idgetUserByLike resultTypeUserselect * from t_user where username like %#{username}%/select
/mapper
1.3.2 批量删除
在执行批量删除的时候为什么不能使用#{}这是因为#{}会自动加上单引号从而导致SQL异常无法实现批量删除的功能。
!-- int deleteMore(Param(ids) String ids);--delete iddeleteMoredelete from t_user where id in (${ids})/delete
1.3.3 动态设置表名
在数据库执行完水平分表之后MyBatis在执行数据操作的时候就需要动态设置表名从而实现分表查询。这里因为表名是不能加单引号的所以这里还是采用${}的形式来实现动态分表查询。
!-- ListUser getUserByTableName(Param(tableName) String tableName);--select idgetUserByTableName resultTypeUserselect * from ${tableName} where id1/select
1.3.4 获取自增主键
插入数据时使用自增主键需要设置insert标签的两个属性
useGeneratedKeys设置当前标签中的SQL使用了自增主键keyProperty将自增的主键的值赋值给传输到映射文件中参数的某个属性
!-- void insertUser(User user);--insert idinsertUser useGeneratedKeystrue keyPropertyidinsert into t_user values (null,#{username},#{password})/insert 二、自定义映射 在之前我们使用resultType要求字段名和属性名一致使用的是一种默认的自动创建的映射关系。但是当字段名和属性名不一致的时候或者处理一对多和多对一的映射关系的时候我们需要自定义映射关系resultMap。
2.1 解决字段名和属性名不一致的三种方案
为字段起别名保持与属性名一致
select idgetAllEmp resultTypeEmpselect eid,emp_name empName from t_emp
/select
在核心配置文件中借助setting标签中的mapUnderscoreToCameCase
!--设置mybatis的全局设置--settings
!-- mapUnderscoreToCameCase:将下划线映射到驼峰命名,默认是false不支持--setting namemapUnderscoreToCameCase valuetrue//settings 通过将mapUnderscoreToCameCase属性值设置为true开启mybatis将下划线映射为驼峰命名的功能
使用resultMap来自定义映射
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.crj.mybatis.mapper.EmpMapper
!-- ListEmp getAllEmp();--resultMap idempResultMap typeEmp!--使用resultMap后建议要把所有字段名和属性之间的关系都声明出来--id propertyeid columneid/result columnemp_name propertyempName/ !--注意这里的映射关系--result columnage propertyage/result columnsex propertysex//resultMapselect idgetAllEmp resultMapempResultMapselect * from t_emp/select
/mapper id唯一标识不能重复 type设置映射关系中的实体类类型
这里有两个子标签id和result。
id设置主键的映射关系
result设置普通字段的映射关系
属性 property设置映射关系中的属性名必须是type属性所设置的实体类类型的属性名 column设置映射关系中的字段名是SQL语句查询出的字段名
2.2 多对一的映射关系
这里有员工和部门两张表分别为二者创建实现类Emp和Dept。在多对一的映射关系中我们考虑的是多个员工同属于一个部门。
package com.crj.mybatis.pojo;public class Emp {private Integer eid;private String empName;private Integer age;private String sex;private String email;private Dept dept;Overridepublic String toString() {return Emp{ eid eid , empName empName \ , age age , sex sex \ , email email \ , dept dept };}public Dept getDept() {return dept;}public void setDept(Dept dept) {this.dept dept;}public Emp(Integer eid, String empName, Integer age, String sex, String email) {this.eid eid;this.empName empName;this.age age;this.sex sex;this.email email;}public Emp(){}public Integer getEid() {return eid;}public void setEid(Integer eid) {this.eid eid;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName empName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex sex;}public String getEmail() {return email;}public void setEmail(String email) {this.email email;}
}2.2.1 通过级联属性赋值解决多对一映射 resultMap idgetEmpAndDept typeEmpid propertyeid columneid/result columnemp_name propertyempName/result columnage propertyage/result columnsex propertysex/result columndid propertydept.did/result columndept_name propertydept.deptName//resultMap!-- Emp getEmpAndDept(Param(eid) Integer eid);--select idgetEmpAndDept resultMapgetEmpAndDeptselect * from t_emp left join t_dept on t_emp.didt_dept.did where t_emp.eid #{eid}/select
2.2.2 通过association解决多对一映射问题
其中对于association中的属性我们需要了解
property需要处理多对一映射关系的属性名javaType 该属性的类型 resultMap idgetEmpAndDept typeEmpid propertyeid columneid/result columnemp_name propertyempName/result columnage propertyage/result columnsex propertysex/association propertydept javaTypeDpetid propertydid columndid/idresult propertydeptName columndept_name/result/association/resultMap
2.2.3 association分步查询解决多对一映射问题
此时association中的property属性的含义不变但还有两个比较重要的属性需要设置相应的属性值
select设置分步查询的sql的唯一标识(一般是设置多对一中一处的mapper接口全类名.方法名)column设置分布查询的条件在这个例子中分布查询是依据两个表之间的关系也就是did来实现的。 fetchType当开启了全局的延迟加载之后可以通过此属性手动控制延迟加载的效果
分步查询的第一步查询员工信息
EmpMapper.java
package com.crj.mybatis.mapper;import com.crj.mybatis.pojo.Emp;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface EmpMapper {/*** 通过分布查询员工以及员工所对应的部门信息* 分布查询第一步查询员工信息*/Emp getEmpAndDeptByStepOne(Param(eid) Integer eid);
}EmpMapper.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.crj.mybatis.mapper.EmpMapper
!-- 分步查询两表联查--resultMap idempAndDeptByStepResultMap typeEmpid propertyeid columneid/result columnemp_name propertyempName/result columnage propertyage/result columnsex propertysex/association propertydept selectcom.crj.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo columndid/association/resultMap
!-- Emp getEmpAndDeptByStepOne(Param(eid) Integer eid);--select idgetEmpAndDeptByStepOne resultMapempAndDeptResultMapTwoselect * from t_emp where eid #{eid}/select/mapper
分步查询第二步根据查询到的员工信息中的did来查询相应的部门信息
DpetMapper.java
package com.crj.mybatis.mapper;import com.crj.mybatis.pojo.Dept;
import org.apache.ibatis.annotations.Param;public interface DeptMapper {/*** 通过分布查询员工以及员工所对应的部门信息* 分布查询第二步通过did查询员工所对应的部门*/Dept getEmpAndDeptByStepTwo(Param(did) Integer did);}DeptMapper.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.crj.mybatis.mapper.DeptMapper
!-- Dept getEmpAndDeptByStepTwo(Param(did) Integer did);--select idgetEmpAndDeptByStepTwo resultTypeDeptselect * from t_dept where did #{did}/select
/mapper
需要注意的是分步查询在实际的应用场景中使用的会比较多。 注意为什么更推荐使用分步查询呢 这是因为通过分步查询我们可以实现MyBatis的延迟加载懒加载 功能通过分步查询我们可以做到需要查询什么信息就执行什么SQL语句比如我们仅需要查询员工信息而不需要部门的内容时通过延迟加载我们只会执行EmpMapper中的SQL语句同时分步查询也实现了两种不同的查询功能的隔离。MyBatis中默认是不会开启延迟加载的功能滴 2.2.4 延迟加载
要想实现延迟加载的功能就必须在全局配置文件中开启相应的延迟加载的开关
lazyLoadingEnabled延迟加载的全局开关。当开启时所有关联对象都会延迟加载默认trueaggressiveLazyLoading当开启时任何方法的调用都会加载该对像的所有属性。否则每个属性会按需加载默认false; 开启延迟加载时针对于当前的所有的分步查询如果哪一步不需要延迟加载可通过association和collection中的fetchType属性设置当前的分步查间是否使用延迟加载fetchTypelazy(延迟加载) l eager(立即加载) settings
!-- 开启延迟加载--setting namelazyLoadingEnabled valuetrue//settings
2.3 一对多映射关系
2.3.1 Collection解决一对多映射关系
Dpet.java
//一对多的映射关系private ListEmp emps;
DeptMapper.java /*** 以部门为主表来获取部门中所有的员工信息*/Dept getDeptAndEmp(Param(did) Integer did);
DeptMapper.xml
resultMap iddeptAndEmpResultMap typeDeptid propertydid columndid/idresult propertydeptName columndept_name/result!--注意区分ofType和association中属性javaType的区别--collection propertyemps ofTypeEmpid propertydid columndid/idresult propertyempName columnemp_name/resultresult propertyage columnage/resultresult propertysex columnsex/resultresult propertyemail columnemail/result/collection/resultMap
!-- Dept getDeptAndEmp(Param(did) Integer did);--select idgetDeptAndEmp resultMapdeptAndEmpResultMapselect * from t_dept left join t_emp on t_dept.did t_emp.did where t_dept.did #{did}/select
2.3.2 分步查询解决一对多映射关系
分步查询的第一步查询部门信息
DeptMapper.java
package com.crj.mybatis.mapper;import com.crj.mybatis.pojo.Dept;
import org.apache.ibatis.annotations.Param;public interface DeptMapper {/*** 分步查询处理一对多的关系* 第一步查询部门信息*/Dept getDeptAndEmpByStepOne(Param(did) Integer did);}DeptMapper.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.crj.mybatis.mapper.DeptMapperresultMap iddeptAndEmpByStepResultMap typeDeptid propertydid columndid/idresult propertydeptName columndept_name/resultcollection propertyemps selectcom.crj.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo columndid/collection/resultMap
!-- Dept getDeptAndEmpByStepOne(Param(did) Integer did);--select idgetDeptAndEmpByStepOne resultMapdeptAndEmpByStepResultMapselect * from t_dept where did #{did}/select
/mapper
分步查询第二步根据查询到的员工信息中的did来查询相应的部门信息
EmpMapper.java
package com.crj.mybatis.mapper;import com.crj.mybatis.pojo.Emp;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface EmpMapper {/*** 分步查询处理一对多的关系* 第二步根据did查询员工信息*/ListEmp getDeptAndEmpByStepTwo();
}EmpMapper.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.crj.mybatis.mapper.EmpMapper!-- ListEmp getDeptAndEmpByStepTwo();--select idgetDeptAndEmpByStepTwo resultTypeEmpselect * from t_emp where did #{did}/select/mapper 总结 弄清楚两种映射关系以及相应的文件依赖关系和处理无疑时学习的重点荔枝学习的时候也是感觉好像懂了但复盘的时候还是有很多概念明显没有弄清楚。最近荔枝的学习状态有点波动可能是摆烂了两周的缘故。。。接下来荔枝也会调整状态滴继续学习Java后端技术栈并作出相应的Blog输出。最近看了丙哥的文章喜欢一句话分享给大家你知道的越多你不知道的越多。共勉共勉哈哈哈哈~~~ 今朝已然成为过去明日依然向往未来我是小荔枝在技术成长的路上与你相伴码文不易麻烦举起小爪爪点个赞吧哈哈哈~~~ 比心心♥~~~