【07】Mybatis笔记--多表查询

【07】Mybatis笔记–多表查询

一、表之间的关系:

  • 一对多
  • 多对多
  • 一对一

1)一对多

示例:一个用户可以有多个银行账户,但一个账户只能属于一个用户(一对多

要求:查询所有用户和它所拥有的账户

步骤:

  1. 创建用户表和账户表
-- 账户表
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;

-- 用户表
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` datetime DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性别',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8;

  1. 创建对应的实体类
/**
 * @author a_apple
 * @create 2020-02-05 14:02
 */
public class Account implements Serializable {

    private Integer id;
    private Integer uid;
    private Double money;

    //一对一关系体现。    ”多“方添加一个”一“方的对象
    private User user;

    //getter(),setter(),toString() ...
}
public class User implements Serializable {

    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

    //一对多关系体现。    在“一”方添加"多“方的集合
    private List<Account> accounts;

    //getter(),setter(),toString() ...
}

  1. 创建Dao接口
//AccountDao
public interface AccountDao {

    /**
     * 查询所有账户,及其账户所属用户
     */
    List<Account> list();
}

//UserDao
public interface UserDao {

    /**
     * 查询所有用户,同时获取用户下所有账户信息
     */
    List<User> list();

}


  1. 配置对应的映射配置文件(UserDao.xml、AccountDao.xml

关键:

UserDao.xml

新使用的标签:<collection>

标签内的属性:

  • property:主表实体类里面集合名(这里指Account集合
  • ofType:指的是集合元素的类型,要写全限定类名。(这里使用了别名

映射配置文件

<?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="indi.xu.dao.UserDao">

    <resultMap id="userAccountMap" type="user">
        <id property="id" column="id"></id>

        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>

        <!--主附表一对多体现-->
        <!--配置user对象中accounts集合的映射
            ofType:指的是集合元素类型,要写全限定类名。(这里使用了别名
        -->
        <collection property="accounts" ofType="account">
            <!--注,当主表主键名和副表相同要使用别名区分-->
            <id property="id" column="aid"></id>
            <!--非主键字段对应-->
            <result property="uid" column="uid"></result>
            <result property="money" column="money"></result>
        </collection>
    </resultMap>

    <!-- 查询所有-->
    <select id="list" resultMap="userAccountMap">
        SELECT u.*,a.id as aid,a.uid,a.money 
        FROM USER u 
        LEFT JOIN account a ON u.id = a.uid;
    </select>

</mapper>

几点注意:

  1. sql语句的书写:由于主表和副表的主键名称都为"id",在mybatis中,写sql语句需要用别名把这2个区分

错误写法:

SELECT * FROM USER u 
LEFT JOIN account a 
ON u.id = a.uid;
-- 虽然在也能实现正常的查询,但放到mybatis中就会出现封装对象错误

正确写法:

 SELECT u.*,a.id as aid,a.uid,a.money 
 FROM USER u 
 LEFT JOIN account a 
 ON u.id = a.uid;
 -- 上面account的id使用了别名aid,这样就能正确封装对象

  1. 上面的select标签使用了resultMap属性而不是resultType。是因为resultType只能封装一个对象,这里要求查询用户的同时还要获取其账户。所以使用resultMap


2)一对一

要求:查询所有账户及其对应的用户

即:在查询所有Account时,需要把Account类里面的User对象也查出来

AccountDao.xml配置:

新使用的标签:<association>

标签中的属性:

  • column:指的是与主表关联的外键
  • property:副表实体类里面主表对象名
  • javaType:指的是主表对应的实体类
<?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="indi.xu.dao.AccountDao">
    
    <resultMap id="AccountMap" type="Account">
        <!--主键字段对应-->
        <id property="id" column="id"></id>
        <!--非主键字段对应-->
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>

        <!--一对一的关系映射,配置封装user的内容-->
        <!--就是在副表里面添加主表对象,以获取主表内容
            column:指的是与主表关联的外键
            javaTyep:指的是主表对应的实体类
            property:副表实体类里面主表对象名
        -->
        <association property="user" column="uid" javaType="user">
            <id property="id" column="id"></id>

            <result property="username" column="username"></result>
            <result property="address" column="address"></result>
            <result property="sex" column="sex"></result>
            <result property="birthday" column="birthday"></result>
        </association>
    </resultMap>

    <!--查询所有账户同时包含用户名和地址信息-->
    <select id="list" resultMap="AccountMap">
        SELECT u.*,a.id ,a.uid,a.money 
        FROM account a,USER u 
        WHERE u.id = a.uid;
    </select>

</mapper>



3)多对多

示例:

  • 一个读者可借阅多本书,一本书可以被多个读者借阅过。产生一个借阅关系(也就是中间表)
  • 一个人可以有多种角色,一种角色可以多个人扮演。

步骤:

  1. 创建表。用户表,用户角色表(中间表),角色表
  2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0wYq7jgz-1581479052109)(C:\Users\Yang xu\Desktop\Mybatis\img\1581142238963.png)]

3.创建对应实体类。分别在User类和Role类中放入对方的集合

public class User implements Serializable {

    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

    //一对多体现
    private List<Role> roles;

    //getter(),setter(),toString()
}
public class Role implements Serializable {

    private Integer id;
    private String roleName;
    private String roleDesc;
    //多对多的关系映射:一个角色可以赋予多个用户
    private List<User> users;

    //getter(),setter(),toString()
}

  1. 创建Dao接口
public interface UserDao {

    /**
     * 查询所有用户及其角色
     */
    List<User> list();
}

  1. 配置UserDao.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="indi.xu.dao.UserDao">

    <resultMap id="userRoleMap" type="user">
        <id property="id" column="id"></id>

        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>

        <collection property="roles" ofType="role">
            <id property="id" column="rid"></id>
            <result property="roleName" column="role_name"></result>
            <result property="roleDesc" column="role_desc"></result>
        </collection>
    </resultMap>

    <!-- 查询所有-->
    <select id="list" resultMap="userRoleMap">
        SELECT u.*,r.id AS rid,r.role_name,r.role_desc 
        FROM USER u
        LEFT JOIN user_role ur ON u.id = ur.uid
        LEFT JOIN role r ON r.id = ur.rid;
    </select>

</mapper>
  1. 注:多对多关系一般是通过操作中间表来实现的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis-Plus是一个基于Mybatis的增强工具,可以简化Mybatis的开发流程。根据提供的引用内容,可以看出Mybatis-Plus的依赖有两个版本,分别是3.5.2和3.3.1。其中,引用\[1\]和引用\[2\]都是使用的3.5.2版本的依赖,而引用\[3\]使用的是3.3.1版本的依赖。具体的依赖配置如下: 引用\[1\]和引用\[2\]的依赖配置: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> ``` 引用\[3\]的依赖配置: ```xml <!--Mybatis-plus的依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.1</version> </dependency> <!--mysql的依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--lombok的依赖,为了优化实体类,可以不去实现实体类的set()、get()--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> ``` 所以,根据你的需求,你可以根据自己的项目需要选择使用3.5.2版本的依赖还是3.3.1版本的依赖。 #### 引用[.reference_title] - *1* *2* [[Mybatis-Plus笔记] MybatisPlus-07-代码生成器及相关依赖](https://blog.csdn.net/Cey_Tao/article/details/127012002)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [MyBatisPlus](https://blog.csdn.net/m0_60213304/article/details/124203155)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值