【MyBatis系列4】一对一,一对多,多对多查询及延迟加载(N+1问题)分析

总结

蚂蚁面试比较重视基础,所以Java那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年1班,很有青春的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。


经历这次面试我还通过一些渠道发现了需要大厂真实面试主要有:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。

蚂蚁金服5面,总结了49个面试题,遇到的面试官都是P7级别以上

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

//创建SqlSession对象

SqlSession session = sqlSessionFactory.openSession();

/**

  • 相比较于session.selectList(“com.xxx.UserMapper.listAllUser”)来实现查询,

  • 下面这种通过先获取mapper再挑用mapper中方法的方式会更灵活

*/

UserMapper userMapper = session.getMapper(UserMapper.class);

List userList = userMapper.listUserByUserName(“孤狼1号”);

System.out.println(null == userList ? “”: JSONObject.toJSONString(userList));

List userList2 = userMapper.listUserByTable(“lw_user”);

System.out.println(null == userList2 ? “”: JSONObject.toJSONString(userList2));

}

}

查询结果输出如下:

在这里插入图片描述

#和$区别


从上面的输出sql语句截图可以看到,如果使用#的话,那么sql语句会先在sql语句中使用占位符,也就是预编译,对应JBDC中的PreparedStatement。而使用$,则会直接把参数拼到sql语句上,相当于JDBC中的Statement。

一般情况下不建议使用$,因为这种直接拼接的方式容易被sql注入攻击。

比如,上面的sql语句:

select user_id,user_name from ${tableName}

假如tableName传入的是:lw_user;delete from lw_user;那么这时候执行的sql语句就会变成:

select user_id,user_name from lw_user;delete from lw_user;

这时候整张表的数据都会被删除,而如果使用的是#{tableName},最终执行的是如下sql:

select user_id,user_name from ‘lw_user;delete from lw_user;’

产生的后果只是查询了一张不存在的表而已。

动态参数的查询

====================================================================

上面的例子中参数是固定的,那么假如我们参数不固定呢?比如有2个参数,但是我可能一个都不用,也可能只用1个,或者2个都用。这种又该如何实现呢?

如下图所示,可以通过where和if标签结合使用,两个条件都写了and,这是因为Mybatis会帮我们处理掉多余的and关键字。

select user_id,user_name from lw_user

and user_id=#{userId}

and user_name=#{userName}

或者说我们对同一个参数需要进行不同取值拼接不同的sql,那么可以通过choose标签根据不同的参数拼接不同的sql

select user_id,user_name from lw_user

and user_id=#{userId}

and user_id=#{userId}

and user_id=#{userId}

当然,Mybatis还提供了其他许多标签,用来处理更加复杂的组合,在这里就不举例说明了。

一对一查询

==================================================================

假如我们现在有两种表,是一对一关系,我们想同时查询出来,当然最简单的办法是再写一个类,把两张表的结果属性都放到一个类里面,但是这种方式无疑会造成了很多重复代码,而且体现不出层级关系,假如我们有一张表lw_user表,存储用户信息,另一张表lw_user_job存储了用户的工作经历,那么很明显,job对应类应该包含在user类内,这种应该怎么实现呢?

请看!

1、新建一个实体类UserJob来映射lw_user_job表属性:

package com.lonelyWolf.mybatis.model;

public class LwUserJob {

private String id;

private String userId; //用户id

private String companyName; //公司名

private String position; //职位

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getCompanyName() {

return companyName;

}

public void setCompanyName(String companyName) {

this.companyName = companyName;

}

public String getPosition() {

return position;

}

public void setPosition(String position) {

this.position = position;

}

}

2、在原先的LwUser类增加一个引用属性来引用LwUserJob:

package com.lonelyWolf.mybatis.model;

public class LwUser {

private String userId; //用户id

private String userName; //用户名称

private LwUserJob usreJobInfo;//用户工作信息

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public LwUserJob getUsreJobInfo() {

return usreJobInfo;

}

public void setUsreJobInfo(LwUserJob usreJobInfo) {

this.usreJobInfo = usreJobInfo;

}

}

3、UserMapper.java中新增一个方法:

List listUserAndJob();

这时候UserMapper.xml需要自定义一个ResultMap:

select * from lw_user u inner join lw_user_job j on u.user_id=j.user_id

这时候执行查询就可以得到如下结果:

[{“userId”:“1”,“userJobInfo”:{“companyName”:“自由职业”,“id”:“11”,“position”:“初级开发”},“userName”:“孤狼1号”}]

一对多查询

==================================================================

假设用户信息和工作信息时1对多的关系,又该如何呢?

只需做2步简单的改造:

1、将LwUser中引用属性改为List:

private List userJobList;

2、Mapper中的ResultMap文件同时做出修改,通过collection标签代替association标签,同时javaType修改为ofType:

最后

学习视频:

大厂面试真题:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

bcType=“VARCHAR” />

最后

学习视频:

[外链图片转存中…(img-lhkJBpDj-1715480007925)]

大厂面试真题:

[外链图片转存中…(img-qQ1pF3OM-1715480007925)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值