Mybatis对于多对多关系下的查询提供了集合(collection)的概念来解决,collection属性是resultMap高级结果映射的子集,首先,在本例中我们使用的是集合元素来解决多对多的查询。 然后你会注意到有一个新的 “ofType” 属性。这个属性非常重要,它用来将 JavaBean(或字段)属性的类型和集合存储的类型区分开来。在集合中ofType指的是集合中元素的类型。

  首先介绍一下Demo情况:

  • 实体类:User(用户)类和Role(角色)类,类中的属性在后面代码中贴出
  • 关系:一个用户可以有多个角色,一个角色可以赋予多个用户中
  • 数据库表结构:用户表、角色表、中间表(用于存储用户和角色的关系)
  • 本例中实现查询的目标:查询用户时同时获取用户所拥有的角色的信息(当查询角色时同时获取角色所属用户的信息的情况和下面的例子原理一样,主要是修改select中的sql语句)

  1.用户实体类以及角色实体类

public class User implements Serializable{
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Role> roles; get和set方法省略 ......
}
public class Role implements Serializable{
private Integer roleId;
private String roleName;
private String roleDesc;
private List<User> users;
get和set方法省略 ......
}

  这里主要是增加用户所拥有的角色的List属性和角色所属用户的List属性,后面做resultMap结果映射的时候使用。

  2.数据库表结构

DROP TABLE IF EXISTS user;
CREATE TABLE user (
id INT(11) NOT NULL auto_increment,
username VARCHAR(32) NOT NULL COMMENT '用户名称',
birthday datetime default NULL COMMENT '生日',
sex char(1) default NULL COMMENT '性别',
address varchar(256) default NULL COMMENT '地址',
PRIMARY KEY (id)
)ENGINE=InnoDB default CHARSET=utf8
INSERT INTO `user` VALUES ('41', '老王', '2018-02-27 17:47:08', '男', '石家庄');
INSERT INTO `user` VALUES ('45', '老李', '2018-02-27 17:47:08', '男', '石家庄');
INSERT INTO `user` VALUES ('46', '老郭', '2018-02-27 17:47:08', '男', '石家庄');
INSERT INTO `user` VALUES ('47', 'mde', '2019-06-26 15:04:25', '女', '河南');
INSERT INTO `user` VALUES ('48', 'nan', '2019-08-01 15:04:54', '女', '合肥'); DROP TABLE IF EXISTS role;
CREATE TABLE role(
ID int(11) NOT NULL COMMENT '编号',
ROLE_NAME VARCHAR(30) DEFAULT NULL COMMENT '角色名称',
ROLE_DESC VARCHAR(60) DEFAULT NULL COMMENT '角色描述',
PRIMARY KEY (ID)
)ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO role (ID,ROLE_NAME,ROLE_DESC) VALUES (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校'); DROP TABLE IF EXISTS user_role;
CREATE TABLE user_role(
UID int(11) NOT NULL COMMENT '用户编号',
RID INT(11) NOT NULL COMMENT '角色编号',
PRIMARY KEY (UID,RID),
CONSTRAINT FK_Reference_10 FOREIGN KEY(RID) REFERENCES role(ID),
CONSTRAINT FK_Reference_9 FOREIGN KEY(UID) REFERENCES user(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO user_role(UID,RID) VALUES(41,1),(45,1),(41,2);

这里主要是增加了中间表。

  3.在UserDao接口中声明查询所有用户的方法findAll();

    /**
* 查询所有的用户同时查询出所拥有的角色的信息
*
* @return
*/
List<User> findAll();

  4.在UserDao.xml中配置findAll()方法

<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.dao.UserDao">
<resultMap id="userMap" type="com.example.domain.User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<collection property="roles" ofType="com.example.domain.Role" resultMap="roleMap"/>
</resultMap>
<resultMap id="roleMap" type="com.example.domain.Role">
<id property="roleId" column="rid"/>
<result property="roleName" column="ROLE_NAME"/>
<result property="roleDesc" column="ROLE_DESC"/>
</resultMap>
<select id="findAll" resultMap="userMap">
SELECT u.*,r.ID as rid,r.ROLE_DESC,r.ROLE_NAME FROM user u
LEFT OUTER JOIN user_role ur on u.id = ur.UID
LEFT OUTER JOIN role r on ur.RID = r.ID
</select>
</mapper>

  实现多对多关系查询的主要工作都放在了这里,首先通过resultMap 声明用户类的结果映射,id以及result等标签就是User类中的基本属性,User类中的角色属性roles通过collection集合标签来映射到结果集中,<collection property="roles" ofType="com.example.domain.Role" resultMap="roleMap"/>,property对应User类中声明的roles属性,ofType用于标识集合中元素的类型,resultMap用于引用其他的结果映射来说明集合中元素的属性,在这里为roleMap。如果roleMap不在其他地方使用,也可以直接将角色的属性直接配置在collection属性的子集里,如以下形式也可以使用。

    <resultMap id="userMap" type="com.example.domain.User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!--<collection property="roles" ofType="com.example.domain.Role" resultMap="roleMap"/>-->
<collection property="roles" ofType="com.example.domain.Role">
        <!--这里的rid是role表中的id,在select语句中为了防止id字段在两个表中都出现导致的重复,所以给role的字段id 起了别名 注意要与select中的别名保持一致-->
<id property="roleId" column="rid"/>
<result property="roleName" column="ROLE_NAME"/>
<result property="roleDesc" column="ROLE_DESC"/>
</collection>
</resultMap>

select中的SQL查询语句解释:

 <select id="findAll" resultMap="userMap">
SELECT u.*,r.ID as rid,r.ROLE_DESC,r.ROLE_NAME FROM user u
LEFT OUTER JOIN user_role ur on u.id = ur.UID
LEFT OUTER JOIN role r on ur.RID = r.ID
</select>

  u.*:查询USER表中所有的属性

  r.ID as rid:对于role表中的id起一个别名rid

  user u LEFT OUTER JOIN user_role ur on u.id = ur.UID:前面的表左连接后面的表,并且连接条件是User表中的id与User_role表中的uid相等

  5.测试代码

 public class UserDaoTest {
private InputStream in;
private SqlSession session; private UserDao userDao;
private SqlSessionFactory factory;
@Before
public void init()throws Exception{
//获取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//获取工厂
factory = new SqlSessionFactoryBuilder().build(in); session = factory.openSession(); userDao = session.getMapper(UserDao.class);
}
@After
public void destory()throws Exception{
session.commit();
session.close();
in.close();
}
@Test
public void findAllTest(){
List<User> userList = userDao.findAll();
for (User user: userList){
System.out.println("每个用户的信息");
System.out.println(user);
System.out.println(user.getRoles());
}
}

6.测试结果

mybatis多表查询之多对多关系查询的实现-xml方式的更多相关文章

  1. mybatis实战教程二:多对一关联查询(一对多)

    多对一关联查询 一.数据库关系.article表和user表示多对一的关系 CREATE TABLE `article` ( `id` ) NOT NULL AUTO_INCREMENT, `user ...

  2. Hibernate 、多表关联映射 - 多对多关系映射(many-to-many)

    hibernate.cfg.xml: <hibernate-configuration> <session-factory name="sessionFactory&quo ...

  3. 数据表设计:多对多关系E-R图转换——中间表

    链接:https://blog.csdn.net/vainfanfan/article/details/80568784 链接2:https://www.cnblogs.com/hiwangzi/p/ ...

  4. Hibernate 、多表关联映射-多对一关系(many-to-one)

    Hibernate.cfg.xml: <session-factory name="sessionFactory"> <property name="h ...

  5. mybatis的动态sql编写以及一对一关系查询和一对多的查询

    创建mybatis数据库,运行以下sql语句 /* SQLyog Ultimate v8.32 MySQL - 5.5.27 : Database - mybatis **************** ...

  6. Django-多对多关系的三种创建方式-forms组件使用-cookie与session-08

    目录 表模型类多对多关系的三种创建方式 django forms 组件 登录功能手写推理过程 整段代码可以放过来 forms 组件使用 forms 后端定义规则并校验结果 forms 前端渲染标签组件 ...

  7. [NHibernate]多对多关系(关联查询)

    目录 写在前面 文档与系列文章 多对多关系关联查询 总结 写在前面 上篇文章介绍了nhibernate中对一对多关系进行关联查询的几种方式,以及在使用过程需要注意的问题.这篇文章对多对多关系的查询处理 ...

  8. [转]NHibernate之旅(11):探索多对多关系及其关联查询

    本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...

  9. MySQL基础9-主键约束、外键约束、等值连接查询、一对一和多对多关系

    1.主键约束和外键约束 外键约束 * 外键必须是另一表的主键的值(外键要引用主键!) * 外键可以重复 * 外键可以为空 * 一张表中可以有多个外键! 概念模型在数据库中成为表 数据库表中的多对一关系 ...

随机推荐

  1. 个人永久性免费-Excel催化剂功能第81波-指定单元格区域内容及公式填充

    在日常数据处理过程中,需要对缺失数据进行填充时,按一定逻辑规则进行处理,实现快速填充,规范数据源.此篇给大家带来多种填充数据的场景. 业务使用场景 对各种系统中导出的数据,很多时候存在数据缺失的情况, ...

  2. RDB和AOF的区别

    redis的持久化方式RDB和AOF的区别   1.前言 最近在项目中使用到Redis做缓存,方便多个业务进程之间共享数据.由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据 ...

  3. C#中Thread.IsBackground 属性

    Thread  thread.IsBackground =true; //Gets or sets a value indicating whether or not a thread is a ba ...

  4. Linux 安装MySql——ubuntu版

    这里简单地阐述一下rpm.deb.tar.gz的区别. rpm格式的软件包适用于基于Red Hat发行版的系统,如Red Hat Linux.SUSE.Fedora. deb格式的软件包则是适用于基于 ...

  5. springcloud-eureka

    作者:纯洁的微笑出处:http://www.ityouknow.com/ 版权归作者所有,转载请注明出处 Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service ...

  6. 色彩缤纷的python(改变字体颜色及样式不完全版)

    色彩缤纷的python(改变字体颜色及样式) *补上昨天随笔中提到的改变字体颜色样式的方法,昨日随笔https://www.cnblogs.com/Du704/p/11265958.html 在项目过 ...

  7. (12)ASP.NET Core 中的配置二(Configuration)

    1.内存配置 MemoryConfigurationProvider使用内存中集合作为配置键值对.若要激活内存中集合配置,请在ConfigurationBuilder的实例上调用AddInMemory ...

  8. Spring MVC浅入浅出——不吹牛逼不装逼

    Spring MVC浅入浅出——不吹牛逼不装逼 前言 上文书说了Spring相关的知识,对Spring来了个浅入浅出,大家应该了解到,Spring在三层架构中主做Service层,那还有Web层,也就 ...

  9. MariaDB 修改存储路径后启动失败问题解决

    修改 MariaDB 路径到 home 路径下, 执行 systemctl start mariadb 启动MariaDB 时,报错提示: Job for mariadb.service failed ...

  10. excel 导入 下载模板 demo

    import org.apache.commons.beanutils.PropertyUtils;import org.apache.commons.lang3.StringUtils;import ...