在这篇博客中,我来介绍下mybatis中的多对多查询的案例,在mybatis中,如何使用ResultMap来实现多对多的查询?

案例:一个user可以有很多role,一个role可以有很多entitlement.

一,数据库表的准备

<span style="font-size:18px;">DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(20) COLLATE utf8_bin NOT NULL,`sex` varchar(20) COLLATE utf8_bin NOT NULL,`birthday` date NOT NULL,`address` varchar(20) COLLATE utf8_bin NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('5', '步惊云', '男', '2016-03-12', '安徽');
INSERT INTO `user` VALUES ('6', '聂风', '男', '2016-03-01', '上海');
INSERT INTO `user` VALUES ('7', '杨康', '男', '2016-03-03', '杭州');</span>
<span style="font-size:18px;">-- ----------------------------
-- Table structure for `role`
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (`id` int(11) NOT NULL AUTO_INCREMENT,`rolename` varchar(20) COLLATE utf8_bin NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', '管理员');
INSERT INTO `role` VALUES ('2', '用户模块管理员');
INSERT INTO `role` VALUES ('3', '国家模块管理员');</span>
<span style="font-size:18px;">DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (`user_id` int(11) NOT NULL,`role_id` int(11) NOT NULL,KEY `user_foreign_key` (`user_id`),KEY `role_foreign_key` (`role_id`),CONSTRAINT `role_foreign_key` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),CONSTRAINT `user_foreign_key` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES ('5', '1');
INSERT INTO `user_role` VALUES ('5', '2');
INSERT INTO `user_role` VALUES ('6', '2');
INSERT INTO `user_role` VALUES ('7', '1');
INSERT INTO `user_role` VALUES ('7', '2');
INSERT INTO `user_role` VALUES ('7', '3');</span>
<span style="font-size:18px;">DROP TABLE IF EXISTS `entitlement`;
CREATE TABLE `entitlement` (`id` int(11) NOT NULL AUTO_INCREMENT,`entitlementname` varchar(20) COLLATE utf8_bin NOT NULL,`role_id` int(11) NOT NULL,PRIMARY KEY (`id`),KEY `role_entitlement_foreign_key` (`role_id`),CONSTRAINT `role_entitlement_foreign_key` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;-- ----------------------------
-- Records of entitlement
-- ----------------------------
INSERT INTO `entitlement` VALUES ('1', '添加', '1');
INSERT INTO `entitlement` VALUES ('2', '修改', '1');
INSERT INTO `entitlement` VALUES ('3', '添加', '2');
INSERT INTO `entitlement` VALUES ('4', '修改', '2');
INSERT INTO `entitlement` VALUES ('5', '删除', '2');
INSERT INTO `entitlement` VALUES ('6', '添加', '3');</span>

二,与数据库表对应的entity的类结构

package com.npf.entity;import java.io.Serializable;
import java.util.Date;
import java.util.List;public class User implements Serializable {private static final long serialVersionUID = 8341195547209659206L;private int id;private String username;private String sex;private Date birthday;private String address;private List<Role> roles;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public List<Role> getRoles() {return roles;}public void setRoles(List<Role> roles) {this.roles = roles;}@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + ", sex=" + sex+ ", birthday=" + birthday + ", address=" + address+ ", roles=" + roles + "]";}
}
package com.npf.entity;import java.io.Serializable;
import java.util.List;/*** * @author Jack**/
public class Role implements Serializable{private static final long serialVersionUID = -3687052298547500972L;private Integer id;private String rolename;private List<Entitlement> entitlements;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getRolename() {return rolename;}public void setRolename(String rolename) {this.rolename = rolename;}public List<Entitlement> getEntitlements() {return entitlements;}public void setEntitlements(List<Entitlement> entitlements) {this.entitlements = entitlements;}@Overridepublic String toString() {return "Role [id=" + id + ", rolename=" + rolename + ", entitlements="+ entitlements + "]";}
}
package com.npf.entity;import java.io.Serializable;/*** * @author Jack**/
public class Entitlement implements Serializable{private static final long serialVersionUID = -1630305760044848905L;private Integer id;private String entitlementname;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getEntitlementname() {return entitlementname;}public void setEntitlementname(String entitlementname) {this.entitlementname = entitlementname;}@Overridepublic String toString() {return "Entitlement [id=" + id + ", entitlementname=" + entitlementname+ "]";}}

三,mapper接口和mapper.xml配置文件(注意这两个文件需要放在同一个包下面)

package com.npf.user.mapper;import java.util.List;
import java.util.Map;import com.npf.entity.User;
import com.npf.entity.vo.UserQueryVO;public interface UserMapper {

 public List<User> findUserRoleEntitlement() throws Exception;}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.npf.user.mapper.UserMapper"><resultMap type="com.npf.entity.User" id="findUserRoleEntitlementResultMap"><id column="user_id" property="id"/><result column="username" property="username"/><result column="sex" property="sex"/><result column="birthday" property="birthday"/><result column="address" property="address"/><collection property="roles" ofType="com.npf.entity.Role"><id column="role_id" property="id"/><result column="rolename" property="rolename"/><collection property="entitlements" ofType="com.npf.entity.Entitlement"><id column="entitlement_id" property="id"/><result column="entitlementname" property="entitlementname"/></collection></collection></resultMap>
<select id="findUserRoleEntitlement" resultMap="findUserRoleEntitlementResultMap">select `user`.id as user_id,`user`.username as username,`user`.sex as sex,`user`.birthday as birthday,`user`.address as address,user_role.role_id,role.rolename as rolename,entitlement.entitlementname,entitlement.id as entitlement_idfrom user inner JOIN user_role ON `user`.id = user_role.user_id inner JOIN role on role.id = user_role.role_idinner JOIN entitlement ON entitlement.role_id = role.id;</select>
</mapper>

四,mybatis的核心配置文件

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="db.properties"></properties><!-- 和spring整合后 environments配置将废除--><environments default="development"><environment id="development"><!-- 使用jdbc事务管理,事务控制由mybatis--><transactionManager type="JDBC" /><!-- 数据库连接池,由mybatis管理--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></dataSource></environment></environments><!-- 加载映射文件 --><mappers><package name="com.npf.user.mapper"/></mappers>
</configuration>

五,获取SqlSessionFactory的工具类

package com.npf.utils;import java.io.IOException;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;public final class MyBatisUtils {private static SqlSessionFactory sqlSessionFactory;private static final String resource = "SqlMapConfig.xml";private MyBatisUtils(){}public static SqlSessionFactory getSqlSessionFactory(){if(sqlSessionFactory==null){synchronized (MyBatisUtils.class) {if(sqlSessionFactory==null){try {sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(resource));} catch (IOException e) {e.printStackTrace();}}}}return sqlSessionFactory;}}

六,测试

package com.npf.test;import java.util.List;import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Before;
import org.junit.Test;import com.npf.entity.User;
import com.npf.user.mapper.UserMapper;
import com.npf.utils.MyBatisUtils;public class UserMapperTest {private SqlSessionFactory sessionFactory;@Beforepublic void setup(){sessionFactory = MyBatisUtils.getSqlSessionFactory();}@Testpublic void findUserRoleEntitlementTest() throws Exception{SqlSession session = sessionFactory.openSession();UserMapper usermapper = session.getMapper(UserMapper.class);List<User> users = usermapper.findUserRoleEntitlement();for(User user : users){System.out.println(user);}}}

七,运行结果

DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 939437404.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@37fead5c]
DEBUG [main] - ==>  Preparing: select `user`.id as user_id, `user`.username as username, `user`.sex as sex, `user`.birthday as birthday, `user`.address as address, user_role.role_id, role.rolename as rolename, entitlement.entitlementname, entitlement.id as entitlement_id from user inner JOIN user_role ON `user`.id = user_role.user_id inner JOIN role on role.id = user_role.role_id inner JOIN entitlement ON entitlement.role_id = role.id;
DEBUG [main] - ==> Parameters:
DEBUG [main] - <==      Total: 14
User [id=5, username=步惊云, sex=男, birthday=Sat Mar 12 00:00:00 CST 2016, address=安徽, roles=[Role [id=1, rolename=管理员, entitlements=[Entitlement [id=1, entitlementname=添加], Entitlement [id=2, entitlementname=修改]]], Role [id=2, rolename=用户模块管理员, entitlements=[Entitlement [id=3, entitlementname=添加], Entitlement [id=4, entitlementname=修改], Entitlement [id=5, entitlementname=删除]]]]]
User [id=6, username=聂风, sex=男, birthday=Tue Mar 01 00:00:00 CST 2016, address=上海, roles=[Role [id=2, rolename=用户模块管理员, entitlements=[Entitlement [id=3, entitlementname=添加], Entitlement [id=4, entitlementname=修改], Entitlement [id=5, entitlementname=删除]]]]]
User [id=7, username=杨康, sex=男, birthday=Thu Mar 03 00:00:00 CST 2016, address=杭州, roles=[Role [id=1, rolename=管理员, entitlements=[Entitlement [id=1, entitlementname=添加], Entitlement [id=2, entitlementname=修改]]], Role [id=2, rolename=用户模块管理员, entitlements=[Entitlement [id=3, entitlementname=添加], Entitlement [id=4, entitlementname=修改], Entitlement [id=5, entitlementname=删除]]], Role [id=3, rolename=国家模块管理员, entitlements=[Entitlement [id=6, entitlementname=添加]]]]]

八,总结

1. 使用resultMap是针对那些对查询结果映射有特殊要求的功能,,比如特殊要求映射成list中包括 多个list。

2. resultType:作用:将查询结果按照sql列名pojo属性名一致性映射到pojo中。

场合:常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用                   resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。

resultMap:使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。

association:作用:将关联查询信息映射到一个pojo对象中。

场合:为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单                及关联用户信息。使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需              要选择使用resultType还是resultMap。

collection:作用:将关联查询信息映射到一个list集合中。

场合:为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块       及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的       作的目的也是方便对查询结果集进行遍历查询。如果使用resultType无法将查询结果映射到list集合中。

mybatis高级映射多对多查询(二)相关推荐

  1. 【MyBatis框架】高级映射-多对多查询

    多对多查询 1.需求 查询用户及用户购买商品信息. 2.sql语句 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表: orders.orderdetai ...

  2. mybatis高级映射一对多查询(一)

    最近一直在研究mybatis,查询是并不可少的研究内容.mybatis的一对多的查询,个人觉得比hibernate简单的很多.好了,废话不多说了,下面以一个简单的例子解释一下mybatis的一对多的查 ...

  3. mybatis 高级映射 - 一对多查询 - collection

    方法一 连接表查询 案例:查询所有订单信息及订单下的订单明细信息. 订单信息与订单明细为一对多关系. 使用resultMap实现如下: Sql语句: SELECT orders.*,user.user ...

  4. 【Mybatis高级映射】一对一映射、一对多映射、多对多映射

    前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...

  5. mybatis高级映射(一对一,一对多,多对多)

    http://www.cnblogs.com/selene/p/4627446.html 阿赫瓦里 生命对于某些人来说,一直都是美丽的,因为这些人的一生都在为某个梦想而奋斗!!! 博客园 首页 新随笔 ...

  6. mybatis由浅入深day02_4多对多查询_多对多查询总结

    4 多对多查询 4.1 需求(查询用户及用户购买商品信息) 查询用户及用户购买商品信息. 4.2 sql语句 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关 ...

  7. 6.2 、MyBatis 高级映射(resultMap 标签多表联查 , 一对多,多对一关系)

    文章目录 一.创建表结构,添加数据,实现表中数据的关联关系 二. association 标签:用于一对一.多对一场景使用 1.实现一对一,多对一关系结果集映射 1.1 按照查询嵌套处理 1.2 按照 ...

  8. 【MyBatis框架】高级映射-一对多查询

    前面学习了一对一的查询,现在我们在刚才的数据模型基础上进行一对多的查询. 一对多查询 1.需求 查询订单及订单明细的信息. 2.sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查 ...

  9. mybatis映射多对多查询实现

    1.同以前一样,首先给一个使用多对多的需求, 要查询用户以及用户所购买的商品信息,经过分析用户和商品数据库级别没有任何关系,用户和商品需要建立关系,要通过订单,订单明细建立关系.根据这个需求,可以分析 ...

最新文章

  1. 【 MATLAB 】MATLAB帮助文档中对 MP 算法以及 OMP 算法的讲解(英文版)
  2. 简介nandflash、norflash、ram、sram、dram、rom、eeprom、flash的区别
  3. 智能汽车带火汽车存储产品 三星/东芝/SK海力士/美光纷纷“下手”
  4. Objective-C入门
  5. matlab期末试题,Matlab期末考试试题库(共12套卷)
  6. java.equal例子_Java中的== 和equals()方法详解与实例
  7. linux 运行springboot 项目 (后台运行,并且打印实时日志)
  8. yum [Errno 256] No more mirrors to try 解决方法
  9. [投稿] Speex回声消除原理深度解析
  10. 【2012百度之星/初赛上】小小度刷礼品
  11. Python利用GUI界面制作B站弹幕分析工具
  12. 【引用】43种名车标志及来历
  13. c++ string常用函数
  14. 我走进了微缩的“物联国”
  15. 抑郁症治疗过程中有哪些变化?
  16. maven修改为阿里巴巴的仓库地址
  17. 购买云服务器如何选择cpu与内存搭配
  18. 治疗“实火”引起的急性口腔溃疡及清新口气的方法
  19. Python量化编程如何判断均线数据是金叉还是死叉?-股市数据均线策略编程分析
  20. 如何在Android中使用离线的谷歌地图Google maps

热门文章

  1. 计算机毕业设计Java医院药品管理系统(系统+源码+mysql数据库+Lw文档)
  2. 智慧物流:车载监控技术下的物流运输车辆智慧化监管
  3. cs python课程 加州大学_cs选uci还是ucsd呢?
  4. 卷积神经网络(CNN)系列介绍之一 (LeNet-5 / AlexNet / GoogLeNet / VGGNet / BNInception / Inceptionv3)
  5. Linux-查询登入用户信息
  6. 0x00000090 - 该内存不能read written
  7. Tabu Search求解作业车间调度问题(Job Shop Scheduling)-附Java代码
  8. nginx 反向代理proxy_pass 后加斜杠和不加斜杆的区别
  9. 为什么Java需要序列化
  10. QEventLoop事件循环的使用