mybatis foreach map_Mybatis关联查询和动态SQL

Mybatis关联查询和动态SQL

相关面试题

1、Mybatis中#{}和${}的区别 是什么?

2、如何实现模糊查询?like?

3、Mybatis的动态sql有什么用?执行原理?有哪些动态sql?

4、如何实现1对N,N对1的查询 ?举例说明

回顾

问题:mybatis的操作流程?

1、全局配置文件(参考官网)

2、创建dao接口和SQL映射文件,提供实体类

3、注册映射文件

  

4、加载配置文件,获取SqlSessionFactory,获取SqlSession

5、测试

备注:在idea中 添加模板:配置文件,映射文件的创建:

操作:file-->settings-->File and Code Templates

d073322f3ce2fb327654c504f38b35ff.png

添加模板

学习目标

1、MyBatis关联查询(1对N,N对1)

2、动态SQL

3、#{}和 ${}的区别?

4、模糊查询

5、调用存储过程

学习内容

1、MyBatis关联查询

1.1 问题1:

如何将查询到的关系数据映射为实体对象?

1、使用别名:让别名和实体的属性名保持一致

实体类:

 @Data public class Emp { private int empno; private String empname; private String work; private String gender; } ​

查询:

  select empno, ename empname,job work,sex gender from emp 

2、结果映射:resultMap

在映射文件中指定resultMap

  

可以设置自动映射:

  

查询命令:

   select * from emp 

1.2、有关联关系的数据如何查询

比如:部门和员工

8bd8ff1d9925783a036797dcfc7d8555.png

1、嵌套select查询

在执行查询时嵌套select命令进行查询:

1.1 多对一操作:

实体类:

 @Data public class Emp { private int empno; private String ename; private String job; private String sex; ​ //引用部门:1 private Dept dept;//对应外键列:deptno ​ }

映射文件 :

  ​   select * from dept where deptno=#{deptno}  ​   select * from emp 

测试:

 @Test public void test3(){ SqlSession session= SessionFactory.getSession(); //接口绑定 EmpDao dao= session.getMapper(EmpDao.class); List list=dao.query3(); for (Emp emp : list) { System.out.println("员工:"+emp.getEmpno()+":"+emp.getEname()); System.out.println("部门:"+emp.getDept().getDeptno()+":"+emp.getDept().getDname()); } session.close(); }

引发N+1查询问题:

753b83fe85a6ebdfe025b31d24648cca.png

1.2 1对多操作:

实体类:

 @Data public class Dept { private int deptno; private String dname; ​ //引用员工的集合:N的一方 private List emps; ​ } ​

映射文件:

  select * from emp where deptno=#{deptno}  select * from dept 

测试:

 @Test public void test4(){ SqlSession session= SessionFactory.getSession(); //接口绑定 DeptDao dao= session.getMapper(DeptDao.class); List list=dao.query1(); for (Dept dept : list) { System.out.println("部门:"+dept.getDeptno()+":"+dept.getDname()); //遍历员工集合 for (Emp emp : dept.getEmps()) { System.out.println("员工:"+emp.getEmpno()+":"+emp.getEname()); } } session.close(); }

如何解决N+1查询问题?

开启懒加载,使用时再查询:

  

2、嵌套结果查询

在resultMap中嵌套resultMap,查询时使用表连接查询;(推荐使用)

2.1 多对一操作:

实体类同上(略)

映射文件配置:

  select * from dept d join emp e on d.deptno=e.deptno 

测试过程同上;

2.2 一对多操作:

实体类同上

映射文件配置:

  ​  select * from dept d join emp e on d.deptno=e.deptno 

测试过程同上;

备注:在实际的项目开发过程中,涉及到多对多关联关系的可以转换为1对多和多对一。

任务:员工(角色集合)和角色(员工集合)查询(三表连接),角色和权限?

备注:实际查询时不能使用select *查询,影响性能。

3、查询返回Map类型

应对:json类型转换时使用;省略实体类,省略resultMap

缺点:不符合面向对象的思想。

dao中:

 //返回List List query3();

映射文件:

   select * from dept d join emp e on d.deptno=e.deptno 

测试:

 @Test public void test6(){ SqlSession session= SessionFactory.getSession(); //接口绑定 DeptDao dao= session.getMapper(DeptDao.class); List list= dao.query3(); for (Map map : list) { System.out.println(map); } session.close(); }

2、动态SQL

如何实现多条件查询?

 select * from 表 where 1=1 if (条件){ 拼接 } if (条件){ 拼接 }

mybatis提供的对应的标签,实现动态sql

  • if
  • choose (when, otherwise)
  • where set ==trim (where, set)
  • foreach

参数传递:

在dao中如何实现传递多个参数:

  1. 单独传递
  2. 封装成实体
  3. 封装成map

1、单独传递:

 //@Param("名字"):设定参数的名字,供查询命令使用select List query5(@Param("name") String name);

如果不指定@Param注解报错:

 Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'name' in 'class java.lang.String'

2、封装成实体:

 List query5(Emp emp);  select * from emp where 1=1 -- ename:实体中的属性名字  and ename=#{ename} 

3、封装成map

 List query5(Map emp);  select * from emp where 1=1 -- ename:map中的键的名字  and ename=#{ename}  ​

测试:

 @Test public void test5(){ String name="小浩"; Map map=new HashMap(); map.put("ename
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值