做断桥铝最知名的网站,山网站建设,中信建设有限责任公司 李玲,如何创建平台类网站编译软件#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统#xff1a;win10 x64 位 家庭版 Maven版本#xff1a;apache-maven-3.6.3 Mybatis版本#xff1a;3.5.6 文章目录 一、Mybatis中的自动映射是什么#xff1f;二、Mybatis中的自定义映射是什么#xff1f;三、为什… 编译软件IntelliJ IDEA 2019.2.4 x64 操作系统win10 x64 位 家庭版 Maven版本apache-maven-3.6.3 Mybatis版本3.5.6 文章目录 一、Mybatis中的自动映射是什么二、Mybatis中的自定义映射是什么三、为什么要使用自定义映射[resultMap]四、自定义映射[resultMap]可以适用哪些场景4.1 resultMap之级联映射4.1.1 级联映射之association映射[1:1]4.1.2 级联映射之collection映射[1:m] 4.2 总结ResultMap中的相关标签及属性4.3 分步查询4.3.1 一对一的关联关系4.3.2 一对多的关联关系4.3.3 扩展 五、Mybatis如何使用延迟加载【懒加载】 一、Mybatis中的自动映射是什么
Mybatis中的自动映射不是什么高大上的技术名词而是我们使用Mybatis框架进行持久化层开发时常用select元素中的常见属性resultType它可以自动将数据库内表中的字段与类中的属性进行关联映射故而得名。 二、Mybatis中的自定义映射是什么
定义 自定义映射简而言之就是resultMap。Mybatis官方将resultMap称为结果映射在为一些比如连接的复杂语句编写映射代码的时候一份 resultMap 能够代替实现同等功能的数千行代码。 设计思想 对简单的语句做到零配置对于复杂一点的语句只需要描述语句之间的关系就行了。 三、为什么要使用自定义映射[resultMap]
原因 它可以解决自动映射[resultType]解决不了的两类问题 ❓ 哪两类问题 多表连接查询时需要返回多张表的结果集 不信请看如下测试案例 测试案例通过员工id获取员工信息及员工所属的部门信息 ①准备数据 ②在Mapper接口书写相应的方法 代码示例如下 //通过员工id获取员工信息及员工所属的部门信息
public ListEmployee showempByempId(int empId);③在接口对应的映射文件中书写相应的sql 代码示例如下 select idshowempByempId resultTypeemployeeSELECTe.id,e.last_name,e.email,e.salary,d.dpt_id,d.dpt_nameFROMtbl_employee e, tbl_department dWHEREe.dept_idd.dpt_idANDe.id1;
/select③测试 Test
public void test01(){try {String resource mybatis-config.xml;InputStream inputStream Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);//通过SqlSessionFactory对象调用openSession();SqlSession sqlSession sqlSessionFactory.openSession();//获取EmployeeMapper的代理对象EmployeeMapper employeeMapper sqlSession.getMapper(EmployeeMapper.class);ListEmployee employees employeeMapper.showempByempId(1);System.out.println(employees);} catch (IOException e) {e.printStackTrace();}}为什么员工所属的部门信息查不出来 原因 书写的sql涉及到多表查询映射文件中相应select子标签的属性为resultType。该属性不支持映射多表查询后的结果集需要用到自定义映射来解决该问题 单表查询时不支持驼峰式自动映射【如果不想为字段定义别名】
自定义映射【resultMap】自动映射解决不了的问题可以交给自定义映射 注意 resultType与resultMap只能同时使用一个 四、自定义映射[resultMap]可以适用哪些场景
4.1 resultMap之级联映射 何为级联映射 答曰 级联映射是指在保存主对象时将关联的对象也一起保存到数据库中。例如对于一对多或者多对一、多对多等关系对象时当保存某个一对象时与这个依赖的对象都应该自动保存或更新。比如部门和员工表一对多关系当保存部门数据时和部门有关联的员工表也同时保存。 用法案例 基于第三节中的案例在映射文件中使用resultMap来解决多表查询后结果集中dept值为null的问题 代码示例如下
①在在映射文件中使用自定义映射
resultMap idempAnddeptResultMap typeemployee!-- column返回的结果集中的字段 property:返回值类型employee中的属性要映射的类 --!-- id属性是定义主键字段与属性之间的关联关系 --id columnid propertyid/id!-- result属性是定义非主键字段与属性之间的关联关系 --result columnlast_name propertylastName/resultresult columnemail propertyemail/resultresult columnsalary propertysalary/resultresult columndpt_id propertydept.deptId/resultresult columndpt_name propertydept.deptName/result
/resultMapselect idshowempByempId resultMapempAnddeptResultMapSELECTe.id,e.last_name,e.email,e.salary,d.dpt_id,d.dpt_nameFROMtbl_employee e, tbl_department dWHEREe.dept_idd.dpt_idANDe.id1;
/select②测试运行 4.1.1 级联映射之association映射[1:1]
特点 解决一对一的关联关系 用法案例 基于4.1小结中的案例对映射文件中的sql部分进行association映射的改写观察效果 代码示例如下
①对映射文件中的sql部分进行association映射的改写
resultMap idempAnddeptResultMap typeemployee!-- column返回的结果集中的字段 property:返回值类型employee中的属性要映射的类 --!-- id属性是定义主键字段与属性之间的关联关系 --id columnid propertyid/id!-- result属性是定义非主键字段与属性之间的关联关系 --result columnlast_name propertylastName/resultresult columnemail propertyemail/resultresult columnsalary propertysalary/result!-- javaType: 用来指定某个属性(dept)或字段在 Java 代码中所对应的具体数据类型 (mybatis.pojo.Dept) --!-- dept属性指的是employee对象中的属性 --association propertydept javaTypemybatis.pojo.Deptid columndpt_id propertydeptId/idresult columndpt_name propertydeptName/result/association/resultMapselect idshowempByempId resultMapempAnddeptResultMapSELECTe.id,e.last_name,e.email,e.salary,d.dpt_id,d.dpt_nameFROMtbl_employee e, tbl_department dWHEREe.dept_idd.dpt_idANDe.id1;
/select②测试运行 4.1.2 级联映射之collection映射[1:m]
特点 解决一对多的关联关系 用法案例 根据部门编号查询对应的部门信息然后拿着部门编号去员工表里去找所属的员工信息此时部门与员工是一对多的关系 代码示例如下
准备数据 ①在DeptMapper接口书写相应的方法
//根据部门编号查询对应的部门信息然后拿着部门编号去员工表里去找所属的员工信息(一对多
public Dept showEmployeesByDeptId(int deptId);②在在DeptMapper接口对应的映射文件中书写相应的sql
!-- collection propertyemployees ofTypemybatis.pojo.Employee - 在Dept类中名为employees的集合中存储的元素类型 --resultMap idshowEmployeesByDeptIdResultMap typedeptid propertydeptId columndpt_id/idresult propertydeptName columndpt_name/resultcollection propertyemployees ofTypemybatis.pojo.Employee!-- id属性是定义主键字段与属性之间的关联关系 --id columnid propertyid/id!-- result属性是定义非主键字段与属性之间的关联关系 --result columnlast_name propertylastName/resultresult columnemail propertyemail/resultresult columnsalary propertysalary/result/collection/resultMapselect idshowEmployeesByDeptId resultMapshowEmployeesByDeptIdResultMapSELECTe.id,e.last_name,e.email,e.salary,d.dpt_id,d.dpt_nameFROMtbl_employee e, tbl_department dWHEREe.dept_idd.dpt_idANDd.dpt_id#{dptId};/select③测试
Test
public void test04(){try {String resource mybatis-config.xml;InputStream inputStream Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);//通过SqlSessionFactory对象调用openSession();SqlSession sqlSession sqlSessionFactory.openSession();//获取EmployeeMapper的代理对象DeptMapper deptMapper sqlSession.getMapper(DeptMapper.class);//查询部门编号为1的部门信息并得到所属员工的所有员工信息Dept dept deptMapper.showEmployeesByDeptId(1);System.out.println(dept);} catch (IOException e) {e.printStackTrace();}}4.2 总结ResultMap中的相关标签及属性 resultMap标签自定义映射标签 id属性定义唯一标识type属性设置映射类型 resultMap子标签 id标签定义主键字段与属性关联关系 result标签定义非主键字段与属性关联关系 column属性定义表中字段名称property属性定义类中属性名称 associationi标签定义一对一的关联关系 property属性定义关联关系属性javaType属性定义关联关系属性的类型select属性设置分步查询SQL全路径colunm属性设置分步查询SQL中需要参数fetchType:设置局部延迟加载【懒加载】 collection标签定义一对多的关联关系 property属性定义关联关系属性ofType属性定义关联关系属性类型select属性设置分步查询SQL全路径colunm属性设置分步查询SQL中需要参数fetchType:设置局部延迟加载【懒加载】是否开启
4.3 分步查询 为什么使用分步查询【分步查询优势】 将多表连接查询改为【分步单表查询】从而提高程序运行效率 4.3.1 一对一的关联关系
用法案例 使用分步查询实现通过员工id获取员工信息及员工所属的部门信息比如说1.通过员工id获取员工信息2.通过员工信息中的部门id获得所属部门得信息员工与部门是一对一的关系即一个员工只能归属一个部门 代码示例如下
①在EmployeeMapper接口中定义实现通过员工id获取员工信息的方法
//使用分步查询实现通过员工id获取员工信息及员工所属的部门信息
//1.通过员工id获取员工信息
//2.通过员工信息中的部门id获得所属部门得信息
public Employee selectEmpByempId(int empId);②在DeptMapper接口中定义实现通过从查出来的员工信息中的部门编号去查所属部门信息
//通过部门id查询所属部门得信息
public Dept selectDeptByDeptId(int deptId);③在EmployeeMapper接口对应的映射文件书写相应的sql resultMap idselectEmpByempIdResultMap typemybatis.pojo.Employeeid propertyid columnid/idresult propertylastName columnlast_name/resultresult propertyemail columnemail/resultresult propertysalary columnsalary/result!-- columndeptId 设置分步查询SQL中需要得参数dept_Id将此值传入到mybatis.mapper.DeptMapper中的selectDeptByDeptId方法中 --association propertydeptselectmybatis.mapper.DeptMapper.selectDeptByDeptIdcolumndept_Id /association/resultMapselect idselectEmpByempId resultMapselectEmpByempIdResultMapSELECTid,last_name,email,salary,dept_idFROMtbl_employeeWHEREid#{empId};/select④在DeptMapper接口对应的映射文件中书写相应的sql
resultMap idselectDeptByDeptIdResultMap typedeptid propertydeptId columndpt_Id/idresult propertydeptName columndpt_name/result
/resultMapselect idselectDeptByDeptId resultMapselectDeptByDeptIdResultMapselectdpt_Id,dpt_namefromtbl_departmentwheredpt_Id#{dptId}
/select⑤测试
Test
public void test02(){try {String resource mybatis-config.xml;InputStream inputStream Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);//通过SqlSessionFactory对象调用openSession();SqlSession sqlSession sqlSessionFactory.openSession();//获取EmployeeMapper的代理对象EmployeeMapper employeeMapper sqlSession.getMapper(EmployeeMapper.class);Employee employee employeeMapper.selectEmpByempId(2);System.out.println(employee);} catch (IOException e) {e.printStackTrace();}}4.3.2 一对多的关联关系
用法案例 通过部门id获取部门信息及部门所属员工信息【使用分步查询来实现】其中按1.通过部门id获取部门信息2.通过部门id获取员工信息等这两个步骤完成分步查询 代码示例如下
①在DeptMapper接口中书写查询通过部门id获取部门信息的方法
//通过部门id获取部门信息
public Dept showEmployeesByDeptIdBetter(int deptId);②在DeptMapper接口对应的映射文件中书写相应的sql
!-- typedept 设置映射类型为dept为什么不是dept类的全称因为我在配置文件给它起了别名 --resultMap idshowEmployeesByDeptIdBetterResultMap typedeptid propertydeptId columndpt_id/idresult propertydeptName columndpt_name/resultcollection propertyemployeesselectmybatis.mapper.EmployeeMapper#selectEmployeeByempIdcolumndpt_Id/collection/resultMapselect idshowEmployeesByDeptIdBetter resultMapshowEmployeesByDeptIdBetterResultMapSELECTdpt_id,dpt_nameFROMtbl_departmentWHEREdpt_id#{dptId};/select③在EmployeeMapper接口中书写查询通过部门id获取所属员工信息的方法
//通过部门id查询对应的员工信息
public Employee selectEmployeeByempId(int empId);④在EmployeeMapper接口对应的映射文件中书写相应的sql
select idshowEmployeesByDeptIdBetter resultMapshowEmployeesByDeptIdBetterResultMapSELECTdpt_id,dpt_nameFROMtbl_departmentWHEREdpt_id#{dptId};/select⑤测试
Test
//测试分步查询版根据部门编号查询对应的部门信息然后拿着部门编号去员工表里去找所属的员工信息
public void test05(){try {String resource mybatis-config.xml;InputStream inputStream Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);//通过SqlSessionFactory对象调用openSession();SqlSession sqlSession sqlSessionFactory.openSession();//获取EmployeeMapper的代理对象DeptMapper deptMapper sqlSession.getMapper(DeptMapper.class);Dept dept deptMapper.showEmployeesByDeptId(1);System.out.println(dept);} catch (IOException e) {e.printStackTrace();}}4.3.3 扩展 如果使用分步查询时需要传递给调用的查询中多个参数则需要将多个参数封装成 Map来进行传递语法如下{k1v1,k2v2} 五、Mybatis如何使用延迟加载【懒加载】
什么是延迟加载 需要时加载不需要暂时不加载如何理解举个生活中的例子就好比当你非常饥饿时才会去吃饭 优势 可以提高程序运行效率 语法 ①全局设置 在核心配置文件中这样写示例代码如下
settings!-- 开启驼峰命名自动映射 --setting namemapUnderscoreToCamelCase valuetrue/!-- 开启全局延迟加载模式 --setting namelazyLoadingEnabled valuetrue/!-- 关闭按需延迟加载模式在3.4.2版本及以后该步骤可省略 --setting nameaggressiveLazyLoading valuefalse/
/settings用法案例 在核心配置文件开启全局延迟加载模式借助8.6小结中的案例代码演示全局延迟加载模式的效果 代码示例如下
测试运行如下
try {String resource mybatis-config.xml;InputStream inputStream Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);//通过SqlSessionFactory对象调用openSession();SqlSession sqlSession sqlSessionFactory.openSession();//获取EmployeeMapper的代理对象EmployeeMapper employeeMapper sqlSession.getMapper(EmployeeMapper.class);Employee employee employeeMapper.selectEmpByempId(2);System.out.println(employee.getLastName() employee.getLastName());System.out.println(--------------------------------------);System.out.println(employee.getDept() employee.getDept());} catch (IOException e) {e.printStackTrace();
}②局部设置 fetchType eager关闭局部延迟加载lazy开启局部延迟加载
用法案例 在上述案例中EmployeeMapper接口对应的映射文件里属性id的值为selectEmpByempId的sql设置关闭延迟加载已经设置了全局延迟加载模式这里再开启局部延迟加载效果不明显遂采用关闭局部延迟加载测试效果 代码示例如下 resultMap idselectEmpByempIdResultMap typemybatis.pojo.Employeeid propertyid columnid/idresult propertylastName columnlast_name/resultresult propertyemail columnemail/resultresult propertysalary columnsalary/result!-- columndeptId 设置分步查询SQL中需要得参数dept_Id将此值传入到mybatis.mapper.DeptMapper中的selectDeptByDeptId方法中 --!-- fetchTypelazy 为此方法设置局部延迟加载 --association propertydeptselectmybatis.mapper.DeptMapper.selectDeptByDeptIdcolumndept_IdfetchTypelazy /association/resultMapselect idselectEmpByempId resultMapselectEmpByempIdResultMapSELECTid,last_name,email,salary,dept_idFROMtbl_employeeWHEREid#{empId};/select运行测试如下