高级映射(一对一、一对多、多对多)

一对一(resultType实现方式)

我们这里就利用订单和用户模型,从订单角度出发,一个订单只能给一个用户创建,所以是一对一,但是从用户角度出发,一个用户是可以创建多个订单的,所以是一对多。但是我们这里从订单角度出发,那么就可以当成一对一来处理
1.这样我们就建立一个需求:查询订单并关联查询下单用户

2.创建用户表和订单表并建立好关系
用户表

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

订单表

CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '下单用户id',
  `number` varchar(32) NOT NULL COMMENT '订单号',
  `createtime` datetime NOT NULL COMMENT '创建订单时间',
  `note` varchar(100) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

然后我们手动插入一点儿数据
高级映射(一对一、一对多、多对多)_第1张图片
高级映射(一对一、一对多、多对多)_第2张图片
3.针对需求编写sql语句
查询订单所有信息并关联查询订单用户信息
高级映射(一对一、一对多、多对多)_第3张图片
4.有了sql语句之后我们就可以根据创建pojo类
订单pojo,生成属性的getter和setter方法
高级映射(一对一、一对多、多对多)_第4张图片
既然订单用户只有三条属性,那么我们选择新建一个类继承这个订单pojo即可
高级映射(一对一、一对多、多对多)_第5张图片
5.既然pojo类也有了,那么将查询结果映射到哪儿呢?显然是映射到这个子类这里,因为子类是可以通过父类的getter方法得到父类的所有属性的(尽管这些属性是private的),所以就可以编写Mapper.xml文件了
高级映射(一对一、一对多、多对多)_第6张图片
6.那么就可以根据mapper.xml文件编写mapper接口了(使用mapper接口代理的方式开发dao)
在这里插入图片描述
7.好了这样就可以写个测试类来测试一下
高级映射(一对一、一对多、多对多)_第7张图片
8.我们采用debug的方式来查看一下结果
高级映射(一对一、一对多、多对多)_第8张图片

一对一(resultMap实现方式)

使用resultMap可以将关联查询出来的信息映射到某个pojo的属性上,比如这里我们可以在Orders类中引入一个用户pojo当作其属性,然后将关联结果映射到这个属性上即可。
1.新建一个User类
高级映射(一对一、一对多、多对多)_第9张图片
2.在Orders中添加User属性,生成getter和setter方法
在这里插入图片描述
3.采用resultMap的方式编写mapper.xml文件,编写这个resultMap时我们可以对应这数据库查询结果来做,会发现没这么乱,写好id的唯一标识,对着查询结果的字段和映射的pojo的属性名
高级映射(一对一、一对多、多对多)_第10张图片

  
    
        
        
        
        
        
        
        
        
        
            
            
            
            
            
            
            
        
    
    
    

4.编写Mapper接口
在这里插入图片描述
5.测试类(在上面测试类的基础上再加一个单元测试)
高级映射(一对一、一对多、多对多)_第11张图片
6.结果
高级映射(一对一、一对多、多对多)_第12张图片

一对一查询总结

1.resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射,所以如果没有查询结果的特殊要求建议使用resultType。

2.resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中,虽然resultMap麻烦,但是resultMap可以实现延迟加载

一对多查询(建议使用resultMap)

因为如果使用resultType可能会查询出重复的数据,如果要避免这种情况发生那么又要自己写循环判断条件来实先,比较麻烦,为什么这么说呢。我们先来分析一个需求先
1.实现一个查询订单的同时查询用户信息和订单的详情信息,订单详情里面肯定有商品信息把,所以要创建多一个商品表,然后我们就可以将查询出来的数据映射到这个订单表上,所以我们只在订单上添加订单详情属性,然后编写resultMap将关联信息映射到这个属性上即可
在这里插入图片描述
下面是商品表

CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL COMMENT '商品名称',
  `price` float(10,1) NOT NULL COMMENT '商品定价',
  `detail` text COMMENT '商品描述',
  `pic` varchar(64) DEFAULT NULL COMMENT '商品图片',
  `createtime` datetime NOT NULL COMMENT '生产日期',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

2.创建一个订单详情表,和订单表以及商品表构建好关系

CREATE TABLE `orderdetail` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `orders_id` int(11) NOT NULL COMMENT '订单id',
  `items_id` int(11) NOT NULL COMMENT '商品id',
  `items_num` int(11) DEFAULT NULL COMMENT '商品购买数量',
  PRIMARY KEY (`id`),
  KEY `FK_orderdetail_1` (`orders_id`),
  KEY `FK_orderdetail_2` (`items_id`),
  CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8

3.手动插入一下数据到新建的两个表中
高级映射(一对一、一对多、多对多)_第13张图片
高级映射(一对一、一对多、多对多)_第14张图片
4.针对需求查询一下结果
高级映射(一对一、一对多、多对多)_第15张图片
5.针对sql语句就可以编写resultMap以及mapper.xml文件了
根据分析可以知道,前面一对一我们已经进行了订单和用户的关联查询,且也编写了resultMap,那么就可以使用extends继承已经编写好的resultMap,然后再写新的就行了,和java的继承类似

 
    
            
            
        
            
            
            
            
            
        
    
    

6.编写mapper接口
在这里插入图片描述
7.编写测试类
高级映射(一对一、一对多、多对多)_第16张图片
8.查看测试结果
高级映射(一对一、一对多、多对多)_第17张图片
展开来看看具体
高级映射(一对一、一对多、多对多)_第18张图片

一对多总结

可以看出,使用resultMap可以轻松的将关联查询数据映射到一个list集合中,只需要在映射类中添加相应的类型的集合,然后生成getter和setter方法,然后在resultMap配置好查询字段和pojo类的映射关系即可

多对多

有了上面的数据表已经一对多的查询基础,那么我们就可以实现一个多对多查询

1.实现一个查询用户的同时查询用户购买的商品,通过上面的表分析我们可以知道用户和商品之间是没有联系的,但是用户和订单有联系,订单和订单详情有联系,然后订单详情和商品有联系,那么这样是不是用户和商品之间有了间接联系呢?然后一个用户是不是可以购买多种商品,一种商品是不是也可以给多个不同的用户购买,所以他们之间是多对多关系

2.需求是要查询用户然后关联查询商品,那么就可以将最终的查询信息映射到用户表中。

3.然后在user类中添加订单属性,这样就可以把订单属性映射到这个属性上(有了订单才能关联到订单详情)
在这里插入图片描述
4.然后在订单中添加订单详情属性,这样就可以把订单详情映射到该属性种(有了订单详情才能关联商品)
在这里插入图片描述

5.最后就在订单详情中添加商品属性,把商品信息映射到这个属性上即可
在这里插入图片描述
6.分析上述可知,它们之间是一级一级之间联系起来的,4个类之间互相依赖形成嵌套关系,最后查询结果也是符合下图的嵌套关系的
高级映射(一对一、一对多、多对多)_第19张图片
7.编写sql查询语句
高级映射(一对一、一对多、多对多)_第20张图片
8.编写mapper.xml文件
虽然看上去非常的长,但其实理解起来并不难的,对着图的分析,最外层就是最终映射结果,然后处理好表与表之间的关系决定采用association还是collection,看好表与表之间的联系之处(外键)对应的字段名和其pojo对应的属性名,只要配好了唯一标识,普通字段就简单了

   
    
        
        
        
        
        
        
        
            
            
            
            
            
            
            
            
                
                
                
                
                
                
                
                    
                    
                    
                    
                    
                
            
        
    
    
    

9.编写mapper接口
在这里插入图片描述
10.测试类
高级映射(一对一、一对多、多对多)_第21张图片
11.查看结果
高级映射(一对一、一对多、多对多)_第22张图片
高级映射(一对一、一对多、多对多)_第23张图片
高级映射(一对一、一对多、多对多)_第24张图片
高级映射(一对一、一对多、多对多)_第25张图片
高级映射(一对一、一对多、多对多)_第26张图片
通过一层一层的展开信息,我们发现是不是符合上面的包含关系啊,真神奇啊,这样就可以实现很多有趣的功能

总结

1.没有特殊要求时使用resultTypt

2.使用resultMap时确定好对应关系,采用association还是collection

3.注意pojo类之间的依赖关系

4.由此就可以知道mybatis比hibernate灵活太多了

高级映射就写到了这里了,毕竟是自己的学习笔记,可能不太全面,但是我个人感觉还是很好的理解了这个映射。哈哈真神奇啊

你可能感兴趣的:(MyBatis)