一个系列搞定MyBatis:Mybatis多表查询

MyBatis多表操作

经过了 MyBatis 基本增删改查的学习,而在实际的项目中,我们往往会接触到多表的操作,什么是多表呢, 在实际生活中,每个实体之间往往是存在关系的,而我们的项目却是要依赖数据库将这些实体之间的关系串联起来,从而实现我们的业务,所以这部分,我们着重讲解如何使用 MyBatis 框架处理多张数据表之间的联系,帮助我们更加理解数据库的映射关系

(一) 表间关系

A:一对多
  • 用户和订单/理财产品
    • 一个用户可以买好几个批次的理财产品
  • 部门和员工
    • 一个部门可以有很多员工
B:多对一
  • 订单和用户
    • 多个订单属于同一个用户
C:多对多
  • 学生选课和学生
    • 一个学生可以选择多门课,一门课可以被多个学生选择
D:一对一
  • 身份证、护照等证件
    • 一个证件只能属于一个人

可以看到,第二章内容我们直接进入了业务表的内容,而由于前几篇文章的铺垫,我将User的相关信息都没有讲解,缺失的内容只有用户实体类,以及对应 XML 映射文件,这个非常简单 以及对应测试类

(二) 根据业务创建表

文章中我们使用用户和账户之间的账户的关系,即:

  • 一个用户可以拥有多个账户,一个账户只能属于一个用户,多个账户也可以属于同一个用户

首先需要建立两张表:用户表和账户表

  • 让两者分别具备一对多的关系,我们需要在账户表中添加外键
User表
CREATE TABLE USER (
 `id`			INT(11)NOT NULL AUTO_INCREMENT,
 `username` 	VARCHAR(32) NOT NULL COMMENT '用户名',
 `telephone`    VARCHAR(11) NOT NULL COMMENT '手机',
 `birthday`		DATETIME DEFAULT NULL COMMENT '生日',
 `gender`  		CHAR(1) DEFAULT NULL COMMENT '性别',
 `address` 		VARCHAR(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY  (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
复制代码
Account表
CREATE TABLE `account` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `UID` int(11) default NULL COMMENT '用户编号',
  `MONEY` double default NULL COMMENT '金额',
  PRIMARY KEY  (`ID`),
  KEY `FK_Reference_8` (`UID`),
  CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码

(三) 账户表-单表查询

首先创建其对应Account实体类

public class Account implements Serializable {
   
	private Integer id;
	private Integer uid;
	private Double money;
    ......对应 get set 方法
}
复制代码

在其 AccountMappre 接口中增加查询所有的方法

public interface AccountMapper {
   

    /**
     * 查询所有账户
     * @return
     */
    List<Account> findAll();
}
复制代码

增加其映射文件,注:省略头部的一些引入代码

<mapper namespace="cn.ideal.mapper.AccountMapper">
    <!-- 根据查询所有用户 -->
    <select id="findAll" resultType="Account">
        select * from account
    </select>
</mapper>
复制代码

还是要再多啰嗦一句,resultType="Account" 这里是因为我们在主配置文件中已经,对omain中类都起了别名,所以可以直接用包下的类名,如果不了解的朋友,使用全类名也是一样的

测试一下:

/**
 * 测试查询所有
 */
@Test
public void testFindAll(){
   
	List<Account> accounts = accountMapper.findAll();
	for (Account account : accounts){
   
    	System.out.println(account);
    }
}
复制代码

看一下效果:

img

(四) Account 一对一查询

如何查询到 Acount 中信息的同时,根据用户的 id 值将对应的数据显示出来,这其实主要就是需要改变 SQL 的写法,我们在本地的 MySQL中先试一试

SELECT FROM account a,user u WHERE u.id=a.uid;
复制代码

执行结果

img

结果出来了,但是 user 表中的 id 属性由于和 account 表中的 id 属性名称是一致的,所以自动起了别名,更好的做法是,我们自己设置其对应的别名

SELECT u.*,a.id as aid,a.uid,a.money FROM account a,user u WHERE u.id=a.uid;
复制代码

img

这样看起来就条理了许多

到了这一步,我们就可以在代码中实现这样的功能了,即通过查询账户信息,同时查询出对应的用户信息,那由于注册时间,男女等信息,我并不想要,怎么办呢?我们可以再加一点约束,用户的信息只显示名称和地址两个字段

A:创建子类方式(不算太常用)

(1) 修改 Account 接口
/**
 * 查询所有账户,并且带有用户名称和地址信息
 * @return
 */
List<UserAccount> findAllAccount();
复制代码

大家可能注意到我们返回的 List 类型为 UserAccount,这是为什么呢?

既然我们想返回的信息中,需要包含两个表中的信息,似乎我们并没有一个实体可以承载这么多信息,所以我们创建一个 UserAccount 类

(2) 创建 UserAccount 类
public class UserAccount extends Account {
   
	private String username;
	private String address;
    ......对应 get set 方法
    
    @Override
    public String toString() {
   
        return super.toString() + "  UserAccount{" +
                "username='" + username + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}
复制代码

说明:由于我们只需要显示 名称 和 地址 这两个字段,所以只需要创建 username 和 address 两个字段就可以了,而继承 Account 可以方便我们调用输出查询到账户中的信息

(3) 修改 AccountMapper.xml
<select id="findAllAccount" resultType="UserAccount">
        select a.*,u.username,u.address from account a , user u where u.id = a.uid;
</select>
复制代码
(4) 测试代码
/**
 * 查询所有账户,并且带有用户名称和地址信息
 * @return
 */
@Test
public void testFindAllAccount(){
   
	List<UserAccount> uas 
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值