mybatis的对象关系映射-06

06-mybatis的对象关系映射

实际发中,一个业务可能会涉及到多个数据表的查询,那么多表查询就涉及到连接查询(等值连接),表与表之间有一个外键关联

但是程序中最终获取的表封装的对象, 对象与对象之间是没有外键关系的,对象和对象之间只有依赖关系

对象之间的关系主要有四种:

一对一关系: 一个人对应一个身份证id

一对多的关系: 一个用户对应多个订单(重点)

多对一关系: 多个订单对应一个用户(重点)

多对多的关系: 多个学生对应多个老师,多个老师对应多个学生

MyBatis框架支持多表查询封装对象之间关系

一对多查询

多对一和一对一查询

上述两个标签都在手动映射标签 中

1. 准备多表,表之间的关系用逻辑外键(用户表和订单表)

用户表:

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `pwd` varchar(30) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;


INSERT INTO `t_user` VALUES ('1', '梅超风', '123', '30');
INSERT INTO `t_user` VALUES ('2', '曲正风', '123', '40');
INSERT INTO `t_user` VALUES ('3', '黄药师', '123', '35');

订单表:


CREATE TABLE `t_order` (
  `oid` int(11) NOT NULL AUTO_INCREMENT,
  `onum` varchar(50) DEFAULT NULL,
  `oname` varchar(50) DEFAULT NULL,
  `oprice` decimal(10,0) DEFAULT NULL,
  `uid` int(10) NOT NULL,
  `createtime` datetime DEFAULT NULL,
  PRIMARY KEY (`oid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `t_order` VALUES ('1', '1001', '手机', '2000', '1', '2019-12-11 09:22:27');
INSERT INTO `t_order` VALUES ('2', '1002', 'ipad', '3000', '1', '2020-02-06 09:22:59');
INSERT INTO `t_order` VALUES ('3', '1003', '三体书籍', '70', '2', '2020-04-01 09:23:33');

2. 多对一查询

javabean对象的封装:

订单对象:
public class Order {

    private Integer oid;

    private String onum;

    private String oname;

    private Double oprice;

    private Integer uid;

    private Date createtime;
    
    // 以订单为中心  多个 订单 对应一个用户
    private User user;
}

用户对象

public class User {

    private Integer id;

    private String name;

    private String pwd;

    private Integer age;
}

Mapper接口:

    /**
     * 查询订单数据  
     * @return
     */
    List<Order> selectByOrderId();

mapper.xml 映射:


    <select id="selectByOrderId" parameterType="integer" resultMap="order_map">
        select * from t_order
    </select>

    <!--
    需要映射订单对象属性
    private User user;

   解决方案,使用关联查询
   <association property="user" column="uid" select=""/>
       property :需要映射的属性
       column :  要映射属性对应的外键列
       select :  对应的查询方案, 对应查询的命名空间+.+功能id
                  如果是同一个命名空间 可以省略前面的命名空间 
 -->
    <resultMap id="order_map" type="Order">

        <id column="oid" property="oid"></id>
        <result column="onum" property="onum"></result>
        <result column="oname" property="oname"></result>
        <result column="oprice" property="oprice"></result>
        <result column="onum" property="onum"></result>
        <result column="uid" property="uid"></result>

        <association property="user" column="uid" select="cn.demo01.mapper.Many2OneMapper.findUserById">
        </association>

    </resultMap>

    <select id="findUserById" parameterType="integer" resultType="User">
        select * from t_user where id = #{id}
    </select>

测试代码:

    @Test
    public void testMany2one(){

        SqlSession sqlSession = SqlSessionUtils.getSqlSession();


        Many2OneMapper mapper = sqlSession.getMapper(Many2OneMapper.class);

        List<Order> orders = mapper.selectByOrderId();

        orders.forEach(System.out::println);

    }

日志:

DEBUG [main] - ==>  Preparing: select * from t_order 
DEBUG [main] - ==> Parameters: 
TRACE [main] - <==    Columns: oid, onum, oname, oprice, uid, createtime
TRACE [main] - <==        Row: 1, 1001, 手机, 2000, 1, 2019-12-11 09:22:27.0
DEBUG [main] - ====>  Preparing: select * from t_user where id = ? 
DEBUG [main] - ====> Parameters: 1(Integer)
TRACE [main] - <====    Columns: id, name, pwd, age
TRACE [main] - <====        Row: 1, 梅超风, 123, 30
DEBUG [main] - <====      Total: 1
TRACE [main] - <==        Row: 2, 1002, ipad, 3000, 1, 2020-02-06 09:22:59.0
TRACE [main] - <==        Row: 3, 1003, 三体书籍, 70, 2, 2020-04-01 09:23:33.0
DEBUG [main] - ====>  Preparing: select * from t_user where id = ? 
DEBUG [main] - ====> Parameters: 2(Integer)
TRACE [main] - <====    Columns: id, name, pwd, age
TRACE [main] - <====        Row: 2, 曲正风, 123, 40
DEBUG [main] - <====      Total: 1
DEBUG [main] - <==      Total: 3
Order{oid=1, onum='1001', oname='手机', oprice=2000.0, uid=1, createtime=Wed Dec 11 09:22:27 CST 2019, user=User{id=1, name='梅超风', pwd='123', age='30'}}
Order{oid=2, onum='1002', oname='ipad', oprice=3000.0, uid=1, createtime=Thu Feb 06 09:22:59 CST 2020, user=User{id=1, name='梅超风', pwd='123', age='30'}}
Order{oid=3, onum='1003', oname='三体书籍', oprice=70.0, uid=2, createtime=Wed Apr 01 09:23:33 CST 2020, user=User{id=2, name='曲正风', pwd='123', age='40'}}

多个订单对应一个用户 (订单 1001,1002 对应用户 梅超风)
3.一对多查询

以用户为中心查询用户的所有信息(包括订单),一个用户对应多个订单

javabean对象:

用户对象:

public class User {

    private Integer id;

    private String name;

    private String pwd;

    private Integer age;

	// 一个用户对应多个订单 
    private Set<Order> orders;
}

订单对象:

public class Order {

    private Integer oid;

    private String onum;

    private String oname;

    private Double oprice;

    private Integer uid;

    private Date createtime;
}

mapper接口方法:

    /**
     * 通过id查询 user
     * @param uid
     * @return
     */
    User selectUserById(Integer uid);

mapper.xml的映射:

   <select id="selectUserById" resultType="integer" resultMap="rs_user">

        select * from t_user where id = #{id}

    </select>
    <!-- private Set<Order> orders;
        集合属性映射
         <collection property="orders" column="id" select=""/>
             property:需要映射得集合 orders
             column : 部门的主键 id
             select : 关联查询,去根据uid查询出对应的订单信息
                      值关联查询功能的  命名空间+.+功能id
     -->
    <resultMap id="rs_user" type="User">

        <id property="id" column="id"></id>
        <result property="name" column="name"/>
        <result property="pwd" column="pwd"/>
        <result property="age" column="age"/>

        <collection property="orders" column="id" select="selectOrderByOrderId"/>
    </resultMap>

<!--    关联查询
        通过uid 查询 查询对应的订单  -->
    <select id="selectOrderByOrderId" parameterType="integer" resultType="Order">
        select * from t_order where uid = #{uid}
    </select>

代码测试:

    @Test
    public void testMany2one(){

        SqlSession sqlSession = SqlSessionUtils.getSqlSession();

        One2ManyMapper mapper = sqlSession.getMapper(One2ManyMapper.class);

        User user = mapper.selectUserById(1);

        System.out.println(user);

    }

日志:

DEBUG [main] - ==>  Preparing: select * from t_user where id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: id, name, pwd, age
TRACE [main] - <==        Row: 1, 梅超风, 123, 30
DEBUG [main] - ====>  Preparing: select * from t_order where uid = ? 
DEBUG [main] - ====> Parameters: 1(Integer)
TRACE [main] - <====    Columns: oid, onum, oname, oprice, uid, createtime
TRACE [main] - <====        Row: 1, 1001, 手机, 2000, 1, 2019-12-11 09:22:27.0
TRACE [main] - <====        Row: 2, 1002, ipad, 3000, 1, 2020-02-06 09:22:59.0
DEBUG [main] - <====      Total: 2
DEBUG [main] - <==      Total: 1
User{id=1, name='梅超风', pwd='123', age=30, orders=[Order{oid=2, onum='1002', oname='ipad', oprice=3000.0, uid=1, createtime=Thu Feb 06 09:22:59 CST 2020}, Order{oid=1, onum='1001', oname='手机', oprice=2000.0, uid=1, createtime=Wed Dec 11 09:22:27 CST 2019}]}

Process finished with exit code 0

也可以通过等值连接查询:

修改mapper.xml 映射:


    <select id="selectUserById" parameterType="integer" resultMap="rs_user">
            select u.id,u.`name`,u.pwd,u.age,
			 o.oid,o.onum,o.oname,o.oprice,o.uid,o.createtime

            from t_user u join t_order o on u.id = o.uid
            where u.id = #{id}
    </select>

    <!-- private Set<Order> orders;
        集合属性映射
         <collection property="orders" column="id" select=""/>
             property:需要映射得集合 emps
             column : 部门的主键 id
             ofType : 需要映射集合的泛型的类型
             javaType: java的数据类型
     -->
    <resultMap id="rs_user" type="User">

        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="pwd" column="pwd"/>

        <collection property="orders" ofType="Order" javaType="list">
            <id property="oid" column="oid"/>
            <result property="onum" column="onum"/>
            <result property="oname" column="oname"/>
            <result property="oprice" column="oprice"/>
            <result property="createtime" column="createtime"/>
        </collection>
    </resultMap>

代码测试:

@Test
public void testMany2one(){

    SqlSession sqlSession = SqlSessionUtils.getSqlSession();

    One2ManyMapper mapper = sqlSession.getMapper(One2ManyMapper.class);

    User user = mapper.selectUserById(1);

    System.out.println(user);

}

日志:

DEBUG [main] - ==>  Preparing: select u.id,u.`name`,u.pwd,u.age, o.oid,o.onum,o.oname,o.oprice,o.uid,o.createtime from t_user u join t_order o on u.id = o.uid where u.id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: id, name, pwd, age, oid, onum, oname, oprice, uid, createtime
TRACE [main] - <==        Row: 1, 梅超风, 123, 30, 1, 1001, 手机, 2000, 1, 2019-12-11 09:22:27.0
TRACE [main] - <==        Row: 1, 梅超风, 123, 30, 2, 1002, ipad, 3000, 1, 2020-02-06 09:22:59.0
DEBUG [main] - <==      Total: 2
User{id=1, name='梅超风', pwd='123', age=30, orders=[Order{oid=1, onum='1001', oname='手机', oprice=2000.0, uid=null, createtime=Wed Dec 11 09:22:27 CST 2019}, Order{oid=2, onum='1002', oname='ipad', oprice=3000.0, uid=null, createtime=Thu Feb 06 09:22:59 CST 2020}]}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值