二.MyBatis多表查询的不同方式

                                                                一对多查询

 

1.首先建立实体对象,国家和州长,Country,Minister

国家和州是一对多的关系,一个国家对应多个州长,所以国家的对象中应该有一个属性来描述州长们,用Set集合是防止有重复

 二.MyBatis多表查询的不同方式

每一个州长也都得知道自己是属于哪一个国家的,所以州长类有一个描述自己是哪个国家的属性 country

 二.MyBatis多表查询的不同方式

 

写实体类时,属性不要用驼峰标志,可能会出错(现在我也不知道会出什么错,先记录着)

州长和国家的toString方法不能互相包括对方,不然会无限递归调用,只能有一方可以打印另一方的信息

 

2.然后建立数据库表

country表:

二.MyBatis多表查询的不同方式

minister表:

二.MyBatis多表查询的不同方式

 

在建数据库表时,如果把国家和州长的关系放大国家表中表示,则会产生大量冗余数据,是及其不合理的设计,放到州长表中是正确的,得出结论,一对多关系中,外键建立在多的一方上。

在封装对象的时候,作为一的,应该持有集合引用(包含多的的集合),作为多的,应该持有一的对象引用 

3.定义接口

定义接口的目的是让myBatis用动态代理帮我们创建实现类,不用再手动创建。

myBatis实现动态代理的要求:1.在接口中定义的方法和映射文件中的id相同,2.映射文件的namespace是接口的全限定性类名)

 二.MyBatis多表查询的不同方式

4.mapper映射文件

模拟需求:要求根据ID查询出国家以及国家下的所有州长的信息

根据需求可知,需要多表查询才可以实现,第一种查询方法如下所示

二.MyBatis多表查询的不同方式

查询出来的结果是一个Country对象,但是Country对象中含有一个集合属性,直接写resultType=Country”是无法实现把查询出的数据封装成Country对象的,所以用到了resultMap标签

二.MyBatis多表查询的不同方式

                                        图中的两条红线为对应关系

5.测试

 二.MyBatis多表查询的不同方式

 

结果:

DEBUG ==>  Preparing: select cname,cid,mid,mname from country,minister where cid = countryId and cid = ?

DEBUG ==> Parameters: 2(Integer)

DEBUG <==      Total: 2

Country [cid=2, cname=england, ministers=[Minister [mid=4, mname=ddd, country=null], Minister [mid=5, mname=eee, country=null]]]

还有一种查询方法

把两条sql语句分开写,这种方式比较常用,因为它可以使用缓存机制,如下图

二.MyBatis多表查询的不同方式


                                                                多对一查询

需求:根据id查询出州长的信息(州长对象中持有对国家的引用)

使用在Minister对象中封装Country属性

不使用Country对象中的那个集合属性

定义接口

二.MyBatis多表查询的不同方式

编写映射文件

二.MyBatis多表查询的不同方式

测试:

二.MyBatis多表查询的不同方式

测试结果

二.MyBatis多表查询的不同方式

mid为什么是null呢?翻看配置文件后发现,mid配置错了

二.MyBatis多表查询的不同方式


改正后测试结果为:

二.MyBatis多表查询的不同方式

查询成功,下面使用多表单独查询实现

更改mapper文件

二.MyBatis多表查询的不同方式

测试结果:

二.MyBatis多表查询的不同方式

查询成功

一次把需要的信息都查出来的用多标签直接赋值,需要多次查询的要查多次的需要使用select属性如下图

二.MyBatis多表查询的不同方式


                                                                       自关联查询

模拟一个环境:一个新闻栏目,有很多栏目,存在父子关系如下:

娱乐新闻    --->    港台明星

                 --->     内地影视

体育新闻    --->    NBA    --->    火箭

                                       --->    湖人

                  --->    CBA    --->     北京金隅

                                        --->    浙江广厦

                                        --->    青岛双星


需求:给定一个栏目查出该栏目下的所有栏目(不包括自身)

解决:

创建表

二.MyBatis多表查询的不同方式


定义新闻栏目实体类

二.MyBatis多表查询的不同方式

定义接口

二.MyBatis多表查询的不同方式

映射文件

二.MyBatis多表查询的不同方式

先根据传入的父id进行查询,查询出来的结果由resultMap解析,解析到集合的时候需要查询当前栏目有没有子栏目,所以再次调用了查询,触发递归查询,一直到没有子栏目为止。

测试:

二.MyBatis多表查询的不同方式

测试结果:

二.MyBatis多表查询的不同方式

又提出了需求:给定一个栏目查出该栏目下的所有栏目(包括自身)

只需要修改映射文件,如下图:

二.MyBatis多表查询的不同方式