表之间的关系有几种
- 一对多:一个用户可以有多个订单,用户和订单间的关系就是一对多的关系
- 多对一:多个订单属于同一个用户,订单和用户之间的关系就是一个多对一的关系
- 一对一:一个人只能由一个身份证号,一个身份证号只能属于一个人,人和身份证号之间的关系就属于一对一
- 多对多:一个学生可以被多个老师交过,一个老师可以交多个学生,老师和学生之间就是多对多
特例:
如果拿出每一个订单,他都只能属于一个用户。所以mybatis就把多对一看成了一对一
mybatis中的多表查询
示例:账户和用户
一个用户可以有多个账户
一个账户只能属于一个用户(多个账户也可以属于同一个用户)
我们的两张表分别为
account表
user表
我们想执行如下sql语句
那么需要
先创建我们的实体类
然后写我们的dao层的account表的接口
然后配置我们的映射文件
最后记得配置SqlMapConfig.xml中的映射关系
注意id为findAll的select标签中的sql语句为测试语句,不是我们要执行的语句。上面的那个图片中的sql语句才是我们要执行的语句,,显然我们现有的封装结果集的对象是无法完成这个封装的,所以我们需要创建一个新的类
,然后在接口和配置文件中添加对应的方法和执行的sql语句
最终执行单元测试类
得到如下的结果
说明我们查询成功
但是很显然样子实体类继承的写法我们是并不会常用的,而我们使用下面这些方式进行mybatis的多表查询
mybatis中的一对一查询
其实就是一对多
这样理解:一个账户只能对应一个用户,但是一个用户可以对应多个账户,但是下面的写法是以账户一端写的,所以可以认为是一对一查询
mybatis中认为从表的实体类要和主表的实体类体现出他们的关系,那我们如何体现出一对一的关系呢?其实就是从表实体类应该包含一个主表实体的对象引用
其中user就是主表实体类的引用
,然后我们需要配置配置文件中的sql语句
显然这个封装结果肯定是不对的,因为我们不仅有account表中的字段信息,我们还有主表user中的信息,可是实体类中只有user类属性,没办法直接把查询得到的结果中属于user表中的字段信息封装到user属性中,这时候我们需要,使用resultMap来解决这个问题,,,,
注意这里的column没有实际意义,写不写都行因为,该属性用于和select属性同时使用
association标签中的column属性没有实际含义,加不加都行,有他没他都一样
,association标签中的property代表的是外面resultMap标签设置的封装类型中的属性,也就是主表的对象引用。而association标签中的column表示的就是从表中消除笛卡尔积的字段名,,,,然后association标签中的属性javaType用于提示封装到哪一个对象
这时候我们重新配置sql语句
,然后执行测试类
得到的结果如下
这样我们就成功实现了一对一的多表查询
mybatis中的一对多查询
其实上面的也是一对多查询,只不过上面的是以账户为主写的(一个账户只能属于一个用户)
这个就是一个用户能有多个账户,就是以用户为主写的
我们在user类中添加一个从表集合的引用,用这样的方式来表示一对多的关系。
然后我们配置配置文件中的sql语句,和resultMap
collection标签中的property属性表示的是外面resultMap设置的封装对象的类型的acounts集合的属性,,oftype属性表示的是list集合中的泛型类型,也就是从表的实体类(注意这里如果没有写typealises标签封装实体类的话,必须要写全类名)这里是account类型
然后执行测试类
得到如下结果
mybatis中的多对多查询
示例:用户和角色
一个用户可以有多个角色
一个角色可以赋予多个用户
下面是role表的内容
下面是中间表user_role
下面是user表
使用mybatis编写当我们查询用户的时候,可以同时得到用户所包含的角色信息
首先创建role的实体类
我们通过和一对多同样的方式来编写实体类,,,
然后我们编写我们的IRoleDao.xml配置文件
这里我们注意一个细节,就是这么长的sql语句,我们在换行的时候一定记得有空格,不然就会咱们看起来换行了,实际上是这样
所以千万注意空格
最后编写单元测试,
执行成功,,如下
使用mybaits当我们查询用户时获取用户所包含的角色信息
给user类中添加roles属性表示role集合
然后配置IUserDao.xml里面的新的select标签的sql语句
编辑单元测试
执行结果如下