springboot之聯(lián)表查詢方式
springboot 聯(lián)表查詢
業(yè)務(wù)分析
在開發(fā)管理系統(tǒng)時,遇到需要將 User 和 對應(yīng)的 Organization 聯(lián)表查詢起來,找到用戶所對應(yīng)的組織信息
數(shù)據(jù)庫
- 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è)務(wù)場景下可以引入vo
創(chuàng)建 vo 包下 UserVo類
@Data public class UserVo{ private Integer userId; private String userName; private Integer userAge; private Organization organization; //注意這里的數(shù)據(jù)類型和名稱 }
兩種辦法
推薦第一種,因為數(shù)據(jù)庫每次連接開銷較大,第二種與數(shù)據(jù)庫進(jìn)行了多次連接,而第一種與數(shù)據(jù)庫只需交互一次,效率較高。
第一種
直接sql做join連接,在數(shù)據(jù)庫層面聯(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();
上述代碼是偽代碼,如果錯誤,歡迎指正,大致思想是這樣的。
第二種
數(shù)據(jù)庫層面單表查詢 (循環(huán)查表,效率太低,不推薦)
這種辦法沒有在本博客中刪除是因為想警示自己。這是本人初學(xué)時自己摸索的辦法,那會剛?cè)腴T,沒有領(lǐng)路人走了許多彎路,能寫出方法二的爛套路就能窺見一二,當(dāng)時曾記得寫出這洋洋灑灑的文章自己還怡然自得。
時隔幾年才改正確是不該,因此添加了方法一,之前寫的這方法二現(xiàn)在看看確實是屎山,或許在過幾年回過頭看方法一又是另外的風(fēng)景。在此感謝評論區(qū)的指正,以后定當(dāng)不斷回顧,保持一顆學(xué)徒的心態(tài)繼續(xù)積累。
創(chuàng)建 vo 包下 UserVo類
@Data public class UserVo{ private Integer userId; private String userName; private Integer userAge; private Integer orgId; //注意這里的數(shù)據(jù)類型和名稱 }
在 service 包下的 UserService 接口定義查詢方法
public interface UserService extends IService<User> { public List<UserVo> voList(); //定義一個返回我們需要得到的包裝對象方法 返回的是UserVo泛型的List集合 }
在 service\impl 包下的 UserServiceImpl 重寫方法 編寫業(yè)務(wù)邏輯
首先要明白:我們需要的 UserVo類中信息有兩部分,一部分是來自于User類,另外一部分是來自于根據(jù)User類的organizationId查詢到的對應(yīng)的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 進(jìn)行遍歷,拿出user_org_id查詢所有對應(yīng)的組織名稱 ==這一步操作=> userList.getUserOrgId(),這里就需要注入 OrganizationMapper ,通過this.organizationMapper.selectOne()方法進(jìn)行條件查詢
@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()); //比較數(shù)據(jù)庫中org_id與傳入的用戶所屬組織ID Organization org = this.organizationMapper.selectOne(queryWrapper); //將條件傳入就能拿到一個組織信息 org.getOrgName() //通過get就能拿到這個組織信息中的名稱信息 } } //此時我們有了user信息,以及user對應(yī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; //定義一個userVo對象 for (User user : userList) { userVo = new UserVo(); //每次循環(huán)創(chuàng)建一個新的vo對象。下面就是給這個vo對象存值 BeanUtils.copyProperties(user,userVo); //復(fù)制屬性 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)建一個數(shù)組,存儲每次封裝好的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<>(); //最終需要返回的結(jié)果集合 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; //將結(jié)果集返回 } }
controller層調(diào)用
@RestController @RequestMapping("/user") public class UserController { @Resource private UserService userService; //注入userService @GetMapping("/list") public List<UserVo> voList(){ return this.userService.voList(); } }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Idea創(chuàng)建springboot不能選擇java8的解決
在IDEA 2023版本創(chuàng)建Spring Boot項目時,發(fā)現(xiàn)沒有Java 8選項,只有Java 17和Java 20,解決方法包括:通過修改服務(wù)器URL(推薦)或直接在創(chuàng)建后修改pom.xml文件中的Spring Boot和Java版本2025-01-01使用spring-task定時任務(wù)動態(tài)配置修改執(zhí)行時間
這篇文章主要介紹了使用spring-task定時任務(wù)動態(tài)配置修改執(zhí)行時間,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11