springboot之聯(lián)表查詢方式
springboot 聯(lián)表查詢
業(yè)務分析
在開發(fā)管理系統(tǒng)時,遇到需要將 User 和 對應的 Organization 聯(lián)表查詢起來,找到用戶所對應的組織信息
數據庫
- 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
故,此業(yè)務場景下可以引入vo
創(chuàng)建 vo 包下 UserVo類
@Data
public class UserVo{
private Integer userId;
private String userName;
private Integer userAge;
private Organization organization; //注意這里的數據類型和名稱
}兩種辦法
推薦第一種,因為數據庫每次連接開銷較大,第二種與數據庫進行了多次連接,而第一種與數據庫只需交互一次,效率較高。
第一種
直接sql做join連接,在數據庫層面聯(lián)表查詢。
集成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();
上述代碼是偽代碼,如果錯誤,歡迎指正,大致思想是這樣的。
第二種
數據庫層面單表查詢 (循環(huán)查表,效率太低,不推薦)
這種辦法沒有在本博客中刪除是因為想警示自己。這是本人初學時自己摸索的辦法,那會剛入門,沒有領路人走了許多彎路,能寫出方法二的爛套路就能窺見一二,當時曾記得寫出這洋洋灑灑的文章自己還怡然自得。
時隔幾年才改正確是不該,因此添加了方法一,之前寫的這方法二現在看看確實是屎山,或許在過幾年回過頭看方法一又是另外的風景。在此感謝評論區(qū)的指正,以后定當不斷回顧,保持一顆學徒的心態(tài)繼續(xù)積累。
創(chuàng)建 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 重寫方法 編寫業(yè)務邏輯
首先要明白:我們需要的 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(); //每次循環(huán)創(chuàng)建一個新的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信息,因此我們還需要創(chuàng)建一個數組,存儲每次封裝好的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();
}
}總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Idea創(chuàng)建springboot不能選擇java8的解決
在IDEA 2023版本創(chuàng)建Spring Boot項目時,發(fā)現沒有Java 8選項,只有Java 17和Java 20,解決方法包括:通過修改服務器URL(推薦)或直接在創(chuàng)建后修改pom.xml文件中的Spring Boot和Java版本2025-01-01
使用spring-task定時任務動態(tài)配置修改執(zhí)行時間
這篇文章主要介紹了使用spring-task定時任務動態(tài)配置修改執(zhí)行時間,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11

