文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Mybatis-多表联查

2023-09-02 14:10

关注

多表联查

在数据库查询中,很多时候不只是查询一张表,而是需要将多张表结合起来才能获得需要的数据,下面介绍在mybatis中怎么实现多表联查(前提是所有的依赖均已配置完成)

一、步骤一:创建pojo实体类

将需要用到的表全部创建成java的实体类,导入lombok依赖(自动生成get、set等方法)
User 用户表 Order 订单表

@Datapublic class User {    private Integer ID;    private String username;    private String PASSWORD;    private String sex;    private Date brithday;    private String address;}

二、步骤二:明确两个实体类之间的关系

一个用户可以有多条订单,而一条订单只属于一个用户
所以;:用户对订单是1对多的关系
 
在设计数据库时(黄色部分):在多的一方(tb_order)中添加一个外键,与tb_user的主键对应(图中为uid)
 
在设计java对象时(红色部分): 需要根据题目进行pojo类的编写(具体看步骤三)

在这里插入图片描述


三、步骤三:修改pojo实体类

先分析清楚题目 如:

①:根据id查询订单以及订单的所属用户信息
=> 返回的数据是tb_order表中的数据+tb_user表中的数据,需要修改的实体类是Order,因为是根据order的id查询的

//需要在Order的实体类中引入User对象public class Order {    private Integer id;    private Integer userid;    private Date createtime;    private String state;//    多对一    private User user = new User();}

②:根据用户id查询她的各类订单
=>返回的数据是tb_user+tb_order表中的数据,但是不同与上面的是:由于订单有多条所以订单需要用集合来装,而查询出的数据是要根据用户的id查询所有需要修改User类

// 需要在User表中的实体类中引入数据类型为Order的集合public class User implements Serializable {    private Integer ID;    private String username;    private String PASSWORD;    private String sex;    private Date brithday;    private String address;//    一对多    private List<Order> orders = new ArrayList<>();}

四、步骤四:编写Mapper接口

public interface UserMapper {//    通过订单id查询订单详情以及所属用户    Order selectOrderAndInfoById(@Param("oid") int id);//    通过用户id查询该用户的所有订单    User selectByUserIdForOrder(@Param("uid") int id);//    根据id查询用户    User selectUserByid(@Param("uid") int id);}

五、步骤五:编写Mapper映射文件

需要指定该映射文件是步骤四的Mapper,在namespace中指定

重点来了:

题目1:通过订单id查询订单详情以及所属用户

需要知道的是我们关联的是两张表,如果直接用下面的sql语句则只能查出订单的信息而订单所属用户则为空,这是因为在执行过程中Order会自动映射到tb_order的内容,但是在Order表中定义的User对象则无法自动映射到tb_user表中的内容

SELECT  u.ID ,u.username,u.PASSWORD,u.sex,u.brithday,u.address,o.id oid,o.userid,o.createtime,o.stateFROM tb_user u JOIN tb_order oON u.ID  = o.useridWHERE u.id= #{uid}

所以我们得手动映射User类,需要使用到resultMap
总体代码如下:

 <!--  todo  根据id查询订单以及对应的用户 -->    <sql id="selectById">        u.ID ,u.username,u.PASSWORD,u.sex,u.brithday,u.address,        o.id oid,o.userid,o.createtime,o.state    </sql>    <resultMap id="selectParent" type="Order">        <id property="id" column="oid"/>        <result property="userid" column="userid"/>        <result property="createtime" column="createtime"/>        <result property="state" column="state"/>    </resultMap>    <resultMap id="selectChildren" type="Order" extends="selectParent">        <association property="user" javaType="User" select="selectUserByid" column="userid"/>    </resultMap>    <select id="selectOrderAndInfoById" resultMap="selectChildren">        SELECT        <include refid="selectById"/>        FROM tb_user u JOIN tb_order o        ON u.ID = o.userid        WHERE o.id = #{oid}    </select>    <!--    根据id查询用户-->    <select id="selectUserByid" resultType="User">        SELECT * FROM tb_user WHERE ID = #{uid}    </select>

selectParent为手动映射的Order类的Map,selectChildren为手动映射的User类的Map,由于需要返回的订单类的数据所有type中填写Order类,children继承了parent那么children中也会有parent的映射,所有selectChildren的map中就有了Order+User的映射
在这里插入图片描述
这个时候再