MybatisPlus实现模糊查询(多表联查并实现分页操作)
1.创建两张数据库表
- 表一 :消费信息表
- 表二:用户信息表
2.需求说明
得到的结果需要带有消费信息表所有信息,加上用户信息表的用户名
3.实现
3.0 共用环境介绍
3.0.1 参数params传入的数据为
3.0.2 controller层
@RestController
@RequestMapping("/financail")
public class FinancialApprovalController extends AbstractController{
@Autowired
FinancialApprovalService financialApprovalService;
//通过姓名进行模糊查询
@GetMapping("/listTolike")
//R为控制数据输出格式
public R selsctListToLike(@RequestParam Map<String, Object> params){
PageUtils page= financialApprovalService.selsctListToLike(params);
if (page==null){
return R.error("请输入正确的用户名");
}
return R.ok().put("FinancialApproval",page);
}
}
3.0.3 Service层接口类
//FinancialApprovalEntity为消费信息的实体类
public interface FinancialApprovalService extends IService<FinancialApprovalEntity> {
PageUtils selsctListToLike(Map<String, Object> params);
}
3.1.方法一
该方法没有通过数据多表链接的方式进行,而是通过分开数据库查询并在Service层进行数据拼接
3.1.1 实体类层(FinancialApprovalEntity实体类)
- FinancialApprovalEntity实体类
/**
* 消费信息实体类
*/
@Data //lombok
@TableName("financial_approval") //链接表名
public class FinancialApprovalEntity implements Serializable {
@TableId
private Long financailId;
private String expenditureName;
private Double amount;
private Date expenditureDate;
private Integer authorizeStatus;
private Long userId;
//通过设置TableField为false,可以在数据库封装到实体类时,并不封装该值为false的属性
//userName不是financial_approval数据库表中所有,是要链接的数据
@TableField(exist = false)
private String userName;
}
3.1.2 Service层
@Service("FinancialApprovalService")
public class FinancialApprovalServiceImpl extends ServiceImpl<FinancialApprovalDao,FinancialApprovalEntity> implements FinancialApprovalService {
//消费信息的Dao层(Mapper层)
@Autowired
FinancialApprovalDao financialApprovalDao;
//用户信息的dao层(Mapper层)
@Autowired
SysUserDao sysUserDao;
@Override
public PageUtils selsctListToLike(Map<String, Object> params) {
//以下操作执行的sql语句为:
//select user_id , username from sys_user where username like '%#{username}%'
//通过用户名称模糊查询到用户id
LambdaQueryWrapper<SysUserEntity> queryWrapper=new LambdaQueryWrapper<>();
//将用户信息表中的用户id和用户名查询出来
queryWrapper.select(SysUserEntity::getUserId,SysUserEntity::getUsername);
//使用条件构造器中的like模糊查询进行查询
//对用户名进行模糊查询
queryWrapper.like(SysUserEntity::getUsername,params.get("name"));
//将查询到的数据存入list中
List<SysUserEntity> sysUserEntities = sysUserDao.selectList(queryWrapper);
//判断查询结果是否为空
if (sysUserEntities.size()==0) {
return null;
}
//-----------------------------------------------------------------------
//将数据封装到Map中让用户id为key,用户名为value
//方便下面查出数据时,通过map的特性直接将username进行赋值
Map<Long,String> nameMap = new HashMap<>();
//将用户id存入到list用于面的范围查询
List<Long> longs=new ArrayList<Long>();
sysUserEntities.forEach(x->{
nameMap.put(x.getUserId(),x.getUsername());
longs.add(x.getUserId());
});
//-----------------------------------------------------------------------
/*以下操作执行的sql语句为
select financail_id,expenditure_name,amount,expenditure_date,authorize_status,user_id from financial_approval where user_id in (2,3)
*/
LambdaQueryWrapper<FinancialApprovalEntity> financialWrapper = new LambdaQueryWrapper<FinancialApprovalEntity>();
//对用户id进行范围查询
financialWrapper.in(FinancialApprovalEntity::getUserId,longs);
//分页查询
IPage<FinancialApprovalEntity> page =this.page(new Query<FinancialApprovalEntity>().getPage(params),financialWrapper );
//——————————————————————————————————————————————————————————————————————
//page将参数分装进IPage中,可以通过getRecords()方法获取到封装的列表
//将用户id通过map键值对,通过键值获取用户名,存入实体类中
page.getRecords().forEach(x->{
x.setUserName(nameMap.get(x.getUserId()));
});
return new PageUtils(page);
}
}
3.2 方法二
1.该方法将通过通过创建链接表的方式存储查询到的数据
2.该方法将写一个类似于this.page()的方法
3.2.1 链接表的实体类(FinancialApprovalVO )
@Data
public class FinancialApprovalVO {
//消费表中的数据
@TableId
private Long financailId;
private String expenditureName;
private Double amount;
private Date expenditureDate;
private Integer authorizeStatus;
private Long userId;
//用户表中的数据
private String userName;
3.2.2 Service层
@Service("FinancialApprovalService")
public class FinancialApprovalServiceImpl extends ServiceImpl<FinancialApprovalDao,FinancialApprovalEntity> implements FinancialApprovalService {
//消费信息的Dao层(Mapper层)
@Autowired
FinancialApprovalDao financialApprovalDao;
public PageUtils selsctListToLike(Map<String, Object> params) {
QueryWrapper<FinancialApprovalEntity> financialApproval = new QueryWrapper<FinancialApprovalEntity>();
//使用条件构造器中的like模糊查询进行查询
financialApproval.like("sys_user.username",params.get("name"));
//封装的实体类变成了FinancialApprovalVO
//fiVoUser()为自己写的dao层方法,用于拼接Wrapper的sql语句的前置sql语句
IPage<FinancialApprovalVO> page =financialApprovalDao.fiVoUser(new Query<FinancialApprovalVO>().getPage(params),financialApproval);
return new PageUtils(page);
}
}
3.2.3 dao层(Mapper层)
- 写到层之前我们先看this.page中的方法
从该方法中我们发现他直接将形参传入到mapper层中,并调用了selectPage方法 - 进入Mapper层继续查看方法
发现该方法使用了一个@param的传递参数的方法
@Param()注解是什么
@Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的的字段名相对应
- 参数传递到了Mapper.xml了用什么获取拼接的sql语句呢?
通过${ew.customSqlSegment}进行sql语句的拼接
dao接口类
@Mapper
//因为该dao用的是FinancialApprovalEntity(消费信息表),所以不能用注解的方式,封装FinancialApprovalVO(链接表),
//但是可以在mapper.xml中具体封装
public interface FinancialApprovalDao extends BaseMapper<FinancialApprovalEntity> {
List<FinancialApprovalEntity> findAll();
//上面是模仿官方语句所写的接口方法,下面是官方接口方法的写法
//应为已经确定了实体类型所以直接将一些参数封装了实体类型
IPage<FinancialApprovalVO> fiVoUser(IPage<FinancialApprovalVO> page, @Param(Constants.WRAPPER) Wrapper<FinancialApprovalEntity> queryWrapper);
// <E extends IPage<T>> E selectPage(E page, @org.apache.ibatis.annotations.Param("ew") Wrapper<T> queryWrapper);
}
mapper.xml类
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wedu.modules.sys.dao.FinancialApprovalDao">
<!-- 提供封装实体类FinancialApprovalVO -->
<select id="fiVoUser" resultType="com.wedu.modules.sys.entity.vo.FinancialApprovalVO">
select financail_id,expenditure_name,amount,expenditure_date,authorize_status,financial_approval.user_id as user_id,username
from financial_approval left join sys_user on sys_user.user_id=financial_approval.user_id
-- 上面是链接信息,我用的是左链接查询
-- 下面是wapper语句所写的拼接语句
${ew.customSqlSegment}
</select>
</mapper>