springboot之联表查询方式

 更新时间:2023年07月19日 10:44:35   作者:isHuPei  
这篇文章主要介绍了springboot之联表查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

springboot 联表查询

业务分析

在开发管理系统时,遇到需要将 User 和 对应的 Organization 联表查询起来,找到用户所对应的组织信息

数据库

  • user表中字段有:user_id、user_name、user_age、user_org_id
  • organization表字段有:org_id、org_name

entity包下的User类

@Data
public class User{
    private Integer userId;
    private String 	userName;
    private Integer userAge;
    private Integer userOrgId;
}

entity包下的Organization类

@Data
public class Organization{
    private Integer orgId;
    private String orgName;    
}

已有的user对象并不满足查询需求,我们需要得到这样一个包装的对象以便查询下列信息:

user_id、user_name、user_age、user_org_name

故,此业务场景下可以引入vo

创建 vo 包下 UserVo类

@Data
public class UserVo{
    private Integer userId;
    private String 	userName;
    private Integer userAge;
    private Organization organization;   //注意这里的数据类型和名称
}

两种办法

推荐第一种,因为数据库每次连接开销较大,第二种与数据库进行了多次连接,而第一种与数据库只需交互一次,效率较高。

第一种

直接sql做join连接,在数据库层面联表查询。

集成mybatis,编写userMapper.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.xxx.mapper.UserMapper">
	 <resultMap id="organizationResult" type="organization">
	        <id     property="orgId"    column="org_id"     />
	        <result property="orgName"  column="org_name"   />
	</resultMap>
    <resultMap type="UserVo" id="UserVoList">
        <id     property="userId"       column="user_id"      />
        <result property="userName"     column="user_name"    />
        <result property="userAge" 	    column="user_age"    />
        <association property="organization"  javaType="organization" resultMap="organizationResult" />
    </resultMap>
	<select id="selectUserVoList" resultMap="UserVoList">
	SELECT u.user_id,
		         u.user_name,
		         u.user_age,
		         o.org_id,
		         o.org_name
		FROM user u
		LEFT JOIN organization o
		WHERE u.user_org_id = o.org_id
	</select>
public List<UserVo> selectUserVoList();

上述代码是伪代码,如果错误,欢迎指正,大致思想是这样的。

第二种

数据库层面单表查询 (循环查表,效率太低,不推荐)

这种办法没有在本博客中删除是因为想警示自己。这是本人初学时自己摸索的办法,那会刚入门,没有领路人走了许多弯路,能写出方法二的烂套路就能窥见一二,当时曾记得写出这洋洋洒洒的文章自己还怡然自得。

时隔几年才改正确是不该,因此添加了方法一,之前写的这方法二现在看看确实是屎山,或许在过几年回过头看方法一又是另外的风景。在此感谢评论区的指正,以后定当不断回顾,保持一颗学徒的心态继续积累。

创建 vo 包下 UserVo类

@Data
public class UserVo{
    private Integer userId;
    private String 	userName;
    private Integer userAge;
    private Integer  orgId;   //注意这里的数据类型和名称
}

在 service 包下的 UserService 接口定义查询方法

public interface UserService extends IService<User> {
    public List<UserVo> voList();     //定义一个返回我们需要得到的包装对象方法 返回的是UserVo泛型的List集合
}

在 service\impl 包下的 UserServiceImpl 重写方法 编写业务逻辑

首先要明白:我们需要的 UserVo类中信息有两部分,一部分是来自于User类,另外一部分是来自于根据User类的organizationId查询到的对应的Organization的name信息。

因此我们需要首先将UserMapper注入,通过UserMapper类中的 selectList 方法(传入条件为空)查询出所有的User信息

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;
    @Override
    public List<UserVo> voList() {
    List<User> userList = this.userMapper.selectList(null);   //封装的是一个User泛型的List集合
}

此时userList集合中有了所有的user信息(user_id,user_name,user_age,user_org_id),接下来我们对 userList 进行遍历,拿出user_org_id查询所有对应的组织名称 ==这一步操作=> userList.getUserOrgId(),这里就需要注入 OrganizationMapper ,通过this.organizationMapper.selectOne()方法进行条件查询

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private OrganizationMapper organizationMapper;
    @Override
    public List<UserVo> voList() {
    List<User> userList = this.userMapper.selectList(null);   //封装的是一个User泛型的List集合
      for (User user : userList) {		//重命名了userList集合
          QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();  
          queryWrapper.eq("org_id",user.getUserOrgId());		//比较数据库中org_id与传入的用户所属组织ID
          Organization org = this.organizationMapper.selectOne(queryWrapper); //将条件传入就能拿到一个组织信息
          org.getOrgName()		//通过get就能拿到这个组织信息中的名称信息
        }
}		//此时我们有了user信息,以及user对应的组织名称信息,接下来我们只需要封装就可以

封装UserVo

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private OrganizationMapper organizationMapper;
    @Override
    public List<UserVo> voList() {
        List<User> userList = this.userMapper.selectList(null);
        UserVo userVo = null;				//定义一个userVo对象
        for (User user : userList) {
            userVo = new UserVo();			//每次循环创建一个新的vo对象。下面就是给这个vo对象存值
            BeanUtils.copyProperties(user,userVo);  	//复制属性
            QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
             queryWrapper.eq("org_id",user.getUserOrgId())
            Organization org = this.organizationMapper.selectOne(queryWrapper);
            userVo.setOrgName(org.getOrgName());  //将组织名称信息赋值给userVo中的OrgName
        }
    }
}

注意这里每次封装的是一条UserVo信息,因此我们还需要创建一个数组,存储每次封装好的UserVo

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private OrganizationMapper organizationMapper;
    @Override
    public List<UserVo> voList() {
        List<User> userList = this.userMapper.selectList(null);
        UserVo userVo = null;	
        List<UserVo> result = new ArrayList<>();		//最终需要返回的结果集合
        for (User user : userList) {
            userVo = new UserVo();			
            BeanUtils.copyProperties(user,userVo);  	
            QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
             queryWrapper.eq("org_id",user.getUserOrgId())
            Organization org = this.organizationMapper.selectOne(queryWrapper);
            userVo.setOrgName(org.getOrgName()); 
            result.add(userVo);		//每次userVo封装好,就把它加到result集合中
        }
        return result;		//将结果集返回
    }
}

controller层调用

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;		//注入userService
    @GetMapping("/list")
    public List<UserVo> voList(){
        return this.userService.voList();
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java:com.netflix.client.ClientException错误解决

    Java:com.netflix.client.ClientException错误解决

    本文主要介绍了Java:com.netflix.client.ClientException错误解决,主要是指出客户端 module-sso 试图通过负载均衡器访问服务时,负载均衡器没有找到可用的服务器来处理请求,下面就来介绍一下解决方法
    2024-08-08
  • Java8中的LocalDateTime和Date一些时间操作方法

    Java8中的LocalDateTime和Date一些时间操作方法

    这篇文章主要介绍了Java8中的LocalDateTime和Date一些时间操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • servlet实现简单的权限管理和敏感词过滤功能

    servlet实现简单的权限管理和敏感词过滤功能

    JavaEE课要求用servlet和过滤器实现权限管理和敏感词过滤功能,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • JAVA TIMER简单用法学习

    JAVA TIMER简单用法学习

    Timer类是用来执行任务的类,它接受一个TimerTask做参数
    2013-07-07
  • SpringBoot异步实现的8种方式

    SpringBoot异步实现的8种方式

    异步执行对于开发者来说并不陌生,在实际的开发过程中,很多场景多会使用到异步,本文主要介绍了SpringBoot异步实现的8种方式,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • SpringBoot超详细讲解@Value注解

    SpringBoot超详细讲解@Value注解

    在使用spring框架的项目中,@Value是经常使用的注解之一。作用是将配置文件中的键对应的值分配给某类内带注解的属性。本文使您系统地了解@Value的用法。在使用Spring框架的项目中@Value是经常使用的注解之一,其作用是将配置文件中的键对应的值分配给某类内带注解的属性
    2022-07-07
  • Java中的NumberFormatException异常原因以及解决方案详解

    Java中的NumberFormatException异常原因以及解决方案详解

    这篇文章主要介绍了Java中的NumberFormatException异常原因以及解决方案详解,NumberFormatException 是 Java 中的一个异常类,通常在字符串转换为数字的过程中发生,它表示一个无效的数字格式,即字符串无法被正确解析为数字,需要的朋友可以参考下
    2024-02-02
  • JAVA String转化成java.sql.date和java.sql.time方法示例

    JAVA String转化成java.sql.date和java.sql.time方法示例

    这篇文章主要给大家分享了关于JAVA String转化成java.sql.date和java.sql.time的方法,文中给出了详细的示例代码,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-03-03
  • spring @Cacheable扩展实现缓存自动过期时间及自动刷新功能

    spring @Cacheable扩展实现缓存自动过期时间及自动刷新功能

    用过spring cache的朋友应该会知道,Spring Cache默认是不支持在@Cacheable上添加过期时间的,虽然可以通过配置缓存容器时统一指定,本文主要介绍了如何基于spring @Cacheable扩展实现缓存自动过期时间以及缓存即将到期自动刷新,
    2024-02-02
  • Java单线程程序实现实现简单聊天功能

    Java单线程程序实现实现简单聊天功能

    这篇文章主要介绍了Java单线程程序实现实现简单聊天功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10

最新评论