当前位置: 首页 > news >正文

Mybatis_day3_Mybatis的多表查询

Mybatis 多表查询

  • 本次案例主要以最为简单的用户和账户的模型来分析 Mybatis 多表关系。用户为 User 表,账户为Account表。一个用户(User)可以有多个账户(Account)。具体关系如下:

在这里插入图片描述


一对一查询(多对一)

  • 需求
    • 查询所有账户信息,关联查询下单用户信息。
  • 注意:
    • 因为一个账户信息只能供某个用户使用,所以从查询账户信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的账户信息则为一对多查询,因为一个用户可以有多个账户。
方式一
  1. 定义账户信息的实体类
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;public Integer getId() {return id;
}
public void setId(Integer id) {this.id = id;
}
public Integer getUid() {return uid;
}
public void setUid(Integer uid) {this.uid = uid;
}
public Double getMoney() {return money;
}
public void setMoney(Double money) {this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", uid=" + uid + ", money=" + money + "]";}
}

  1. 定义 AccountUser 类
public class AccountUser extends Account implements Serializable {
private String username;
private String address;public String getUsername() {return username;
}
public void setUsername(String username) {this.username = username;
}
public String getAddress() {return address;
}
public void setAddress(String address) {this.address = address;
}
@Override
public String toString() {
return super.toString() + " AccountUser [username=" + username + ", 
address=" + address + "]";}
}

  1. 编写 Sql 语句
实现查询账户信息时,也要查询账户所对应的用户信息。
SELECT  account.*, user.username, user.address
FROM account,user
WHERE account.uid = user.id

  1. 定义账户的持久层 Dao 接口
public interface IAccountDao {
/**
* 查询所有账户,同时获取账户的所属用户名称以及它的地址信息
* @return
*/
List<AccountUser> findAll();
}

  1. 定义 AccountDao.xml 文件中的查询配置信息
<mapper namespace="cn.myp666.dao.IAccountDao">
<!-- 配置查询所有操作-->
<select id="findAll" resultType="accountuser">select a.*,u.username,u.address from account a,user u where a.uid =u.id;
</select>
</mapper>
  • 注意: 因为上面查询的结果中包含了账户信息同时还包含了用户信息,所以我们的返回值类型 returnType的值设置为 AccountUser 类型,这样就可以接收账户信息和用户信息了。

  1. 创建 AccountTest 测试类
@Test
public void testFindAll() {
//6.执行操作List<AccountUser> accountusers = accountDao.findAll();for(AccountUser au : accountusers) {System.out.println(au);}

  1. 总结
  • 定义专门的 po 类作为输出类型,其中定义了 sql 查询结果集所有的字段。此方法较为简单,企业中使用普遍。


方式二
  • 使用 resultMap,定义专门的 resultMap 用于映射一对一查询结果。
  • 通过面向对象的(has a)关系可以得知,我们可以在 Account 类中加入一个 User 类的对象来代表这个账户是哪个用户的。
  1. 修改 Account 类

    在 Account 类中加入 User 类的对象作为 Account 类的一个属性。
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//添加User对象
private User user;public User getUser() {return user;
}
public void setUser(User user) {this.user = user;
}public Integer getId() {return id;
}
public void setId(Integer id) {this.id = id;
}
public Integer getUid() {return uid;
}
public void setUid(Integer uid) {this.uid = uid;
}
public Double getMoney() {return money;
}
public void setMoney(Double money) {this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", uid=" + uid + ", money=" + money + "]";}
}

  1. 修改 AccountDao 接口中的方法

    注意:第二种方式,将返回值改 为了 Account 类型。因为 Account 类中包含了一个 User 类的对象,它可以封装账户所对应的用户信息。
public interface IAccountDao {
/**
* 查询所有账户,同时获取账户的所属用户名称以及它的地址信息
* @return
*/
List<Account> findAll();
}

  1. 重新定义 AccountDao.xml 文件
<mapper namespace="cn.myp666.dao.IAccountDao"><!-- 建立对应关系 --><resultMap type="account" id="accountMap"><id column="aid" property="id"/><result column="uid" property="uid"/><result column="money" property="money"/><!-- 它是用于指定从表方的引用实体属性的 --><!--多对一的关系, property: 指的是属性的值, javaType:指的是属性的类型 --><association property="user" javaType="user"><id column="id" property="id"/><result column="username" property="username"/><result column="sex" property="sex"/><result column="birthday" property="birthday"/><result column="address" property="address"/></association></resultMap><select id="findAll" resultMap="accountMap">select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id;
</select>
</mapper>

  1. 在 AccountTest 类中加入测试方法
@Test
public void testFindAll() {List<Account> accounts = accountDao.findAll();for(Account au : accounts) {System.out.println(au);System.out.println(au.getUser());}
}



一对多查询

  • 需求:

    • 查询所有用户信息及用户关联的账户信息。
  • 分析:

    • 用户信息和他的账户信息为一对多关系,并且查询过程中如果用户没有账户信息,此时也要将用户信息查询出来,我们想到了左外连接查询比较合适。
  • 步骤如下:

  1. 编写 SQL 语句
SELECTu.*, acc.id as aid,acc.uid,acc.money
FROMuser u
LEFT JOIN account acc ON u.id = acc.uid

  1. User 类加入 List< Account >
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Account> accounts;public List<Account> getAccounts() {return accounts;
}
public void setAccounts(List<Account> accounts) {this.accounts = accounts;
}
public Integer getId() {return id;
}
public void setId(Integer id) {this.id = id;
}
public String getUsername() {return username;
}
public void setUsername(String username) {this.username = username;
}
public Date getBirthday() {return birthday;
}
public void setBirthday(Date birthday) {this.birthday = birthday;
}
public String getSex() {return sex;
}
public void setSex(String sex) {this.sex = sex;
}
public String getAddress() {return address;
}
public void setAddress(String address) {this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", birthday=" + birthday
+ ", sex=" + sex + ", address="
+ address + "]";}
}

  1. 用户持久层 Dao 接口中加入查询方法
List<User> findAll();

  1. 用户持久层 Dao 映射文件配置
<mapper namespace="cn.myp666.dao.IUserDao"><resultMap type="user" id="userMap"><id column="id" property="id"></id><result column="username" property="username"/><result column="address" property="address"/><result column="sex" property="sex"/><result column="birthday" property="birthday"/><!-- collection 是用于建立一对多中集合属性的对应关系
ofType 用于指定集合元素的数据类型
--><collection property="accounts" ofType="account"><id column="aid" property="id"/><result column="uid" property="uid"/><result column="money" property="money"/></collection></resultMap><!-- 配置查询所有操作 -->
<select id="findAll" resultMap="userMap">select u.*,a.id as aid ,a.uid,a.money from user u left outer join account 
a on u.id =a.uid
</select>
</mapper>
  • collection
    部分定义了用户关联的账户信息。表示关联查询结果集
  • property=“accounts”:
    关联查询的结果集存储在 User 对象的上哪个属性里。
  • ofType=“account”:
    指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。

  1. 测试方法
@Test
public void testFindAll() {
//6.执行操作List<User> users = userDao.findAll();for(User user : users) {System.out.println("-------每个用户的内容---------");System.out.println(user);System.out.println(user.getAccounts());}
}

http://www.taodudu.cc/news/show-1476409.html

相关文章:

  • PCIE协议-2-事务层规范-Handling of Received TLPs
  • SpringBoot(二)之parent解析
  • 浅谈音频鉴黄技术
  • 【数据结构与算法】LeetCode:哈希表
  • 数据库原理与应用实验八 存储过程
  • RGMII基于V2.0规范解读
  • Mybatis_day4_Mybatis的延迟加载
  • Mybatis_day4_Mybatis的缓存
  • Mybatis_day4_Mybatis的注解开发
  • Mybatis遇坑
  • 关于java中的位运算
  • Spring_day1
  • Spring_day2
  • Spring_day3
  • Spring_day4
  • SpringMVC_day1
  • SpringMVC_day1_常用注解
  • SpringMVC_02
  • Error creating bean with name 'dataSource' defined in class path resource [spring/spring-dao.xml]:
  • SpringSecurity入门
  • 服务注册不进eureka
  • Spring Cloud总结
  • 在此之前的博客地址
  • golang利用反射写入excel的简单工具类
  • 实习工作难点记录
  • c 结构体之位域(位段)
  • 辗转相除求最大公约数,最大公倍数
  • Ubuntu“无法解析或打开软件包的列表或是状态文件”的解决办法。
  • 错误:cc1: error: unrecognized command line option “-m32”
  • 在编写mini2440 helloworld驱动遇到的问题
  • [leetcode] Median of Two Sorted Arrays 寻找两个有序数组的中位数
  • [leetcode] Reverse Integer 反转一个整数
  • [leetcode] Palindrome Number 回文数判断
  • [leetcode] Longest Common Prefix 字符窜最长公共前缀判断
  • [leetcode] Single Number 查找数组中的单数
  • [leetcode] Power of Two 判断一个数是否是2的平方