Mybatis的多表(多对多)查询

Mybatis的多表(多对多)查询


示例:用户和角色

一个用户可以有多个角色

一个角色可以赋予多个用户

解决办法

  1. 建立两张表:用户表,角色表

    让用户表和角色表具有多对多的关系。需要使用中间表,中间表包含各自的主键,在中间表中是外键。

  2. 建立两个实体类:用户实体类和角色实体类

    让用户和角色的实体类能体现出来多对多的关系

    各自包含对方一个集合引用

  3. 建立两个配置文件

    用户的配置文件

    角色的配置文件

  4. 实现配置

    当我们查询用户时,可以同时得到用户所包含的角色信息。

    当我们查询角色时,可以同时得到角色所赋予的用户信息。


多对多(可以理解为两个实体类互相一对多)

接口:IRoleDao,IUserDao
IRoleDao
 public interface IRoleDao {     //查询所有角色     List<Role> findAll(); }
IUserDao
 public interface IUserDao { ?     //查询所有用户,同时获取到用户下所有账户的信息     List<User> findAll(); ?     //根据id查询用户信息     User findById(Integer userId);      }
实体类:Role,User
Role
 package com.itheima.domain; ? import java.io.Serializable; import java.util.List; ? /**  * @Author: lijiahao  * @Description:  * @Data: Create in 21:31 2020/2/26  * @Modified By:  */ public class Role implements Serializable {     private Integer roleId;     private String roleName;     private String roleDesc; ?     //多对多的关系映射:一个角色可以对应多个用户     private List<User> users; ?     public List<User> getUsers() {         return users;     } ?     public void setUsers(List<User> users) {         this.users = users;     } ?     public Integer getRoleId() {         return roleId;     } ?     public void setRoleId(Integer roleId) {         this.roleId = roleId;     } ?     public String getRoleName() {         return roleName;     } ?     public void setRoleName(String roleName) {         this.roleName = roleName;     } ?     public String getRoleDesc() {         return roleDesc;     } ?     public void setRoleDesc(String roleDesc) {         this.roleDesc = roleDesc;     } ?     @Override     public String toString() {         return "Role{" +                 "roleId=" + roleId +                 ", roleName=‘" + roleName + ‘\‘‘ +                 ", roleDesc=‘" + roleDesc + ‘\‘‘ +                 ‘}‘;     } }
User
 package com.itheima.domain; ? import java.io.Serializable; import java.util.Date; import java.util.List; ? /**  * @Author: lijiahao  * @Description:  * @Data: Create in 21:37 2020/2/22  * @Modified By:  */ public class User implements Serializable {     private Integer id;     private String username;     private Date birthday;     private String sex;     private String address; ?     //添加多对多的映射关系:一个用户可以对应多个角色     private List<Role> roles; ?     public List<Role> getRoles() {         return roles;     } ?     public void setRoles(List<Role> roles) {         this.roles = roles;     } ?     public Integer getId() {         return id;     } ?     public void setId(Integer id) {         this.id = id;     } ?     public String getUsername() {         return username;     } ?     public void setUsername(String username) {         this.username = username;     } ?     public Date getBirthday() {         return birthday;     } ?     public void setBirthday(Date birthday) {         this.birthday = birthday;     } ?     public String getSex() {         return sex;     } ?     public void setSex(String sex) {         this.sex = sex;     } ?     public String getAddress() {         return address;     } ?     public void setAddress(String address) {         this.address = address;     } ?     @Override     public String toString() {         return "User{" +                 "id=" + id +                 ", username=‘" + username + ‘\‘‘ +                 ", birthday=" + birthday +                 ", sex=‘" + sex + ‘\‘‘ +                 ", address=‘" + address + ‘\‘‘ +                 ‘}‘;     } } ?
资源文件:连接池,日志,主配置文件,映射配置文件
连接池jdbcConfig.properties
 jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/eesy?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false jdbc.username=root jdbc.password=123456
日志log4j
 ### 设置### log4j.rootLogger = debug,CONSOLE,LOGFILE ? log4j.logger.org.apache.axis.enterprise=FATAL,CONSOLE ? log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n ? ### 输出ERROR 级别以上的日志到=E://logs/error.log ### log4j.appender.LOGFILE = org.apache.log4j.FileAppender log4j.appender.LOGFILE.FILE = F://logs/error.log log4j.appender.LOGFILE.Append = true log4j.appender.LOGFILE.layout = org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern = %d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
主配置文件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"> ? <!--mybatis的主配置文件--> <configuration> ?     <properties resource="jdbcConfig.properties"/> ?     <!--配置别名 类名就是别名,不区分大小写-->     <typeAliases>         <package name="com.itheima.domain" ></package>     </typeAliases> ?     <!--配置环境-->     <environments default="mysql">         <!--配置mysql的环境-->         <environment id="mysql">             <!--配置事务的类型-->             <transactionManager type="JDBC"></transactionManager>             <!--配置数据源(连接池)-->             <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> ?     <!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->     <mappers>         <package name="com.itheima.dao"></package>     </mappers> </configuration>
user的映射配置文件
 <?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.itheima.dao.IUserDao"> ?     <!--定义user的resultMap user为主表,account为从表,构成一对多关系-->     <resultMap id="userMap" type="user">         <id property="id" column="id"></id>         <result property="username" column="username"></result>         <result property="address" column="address"></result>         <result property="sex" column="sex"></result>         <result property="birthday" column="birthday"></result>         <!--配置user到role的配置 一个user对应多个role-->         <collection property="roles" ofType="role">             <id property="roleId" column="id"></id>             <result property="roleName" column="role_name"></result>             <result property="roleDesc" column="role_desc"></result>         </collection>     </resultMap>     <select id="findAll" resultMap="userMap">         select u.*,r.id as rid,r.role_name,r.role_desc from user u         left outer join user_role ur on u.id = ur.uid         left outer join role r on r.id = ur.rid     </select> ? ?     <!--根据id查找一个用户的信息-->     <select id="findById" parameterType="INT" resultType="user">         select * from user where id = #{userid}     </select> ? </mapper>
Role的映射配置文件
 <?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.itheima.dao.IRoleDao"> ?     <!--定义role的resultMap-->     <resultMap id="roleMap" type="role">         <id property="roleId" column="id"></id>         <result property="roleName" column="role_name"></result>         <result property="roleDesc" column="role_desc"></result>         <collection property="users" ofType="user">             <id property="id" column="id"></id>             <result property="username" column="username"></result>             <result property="address" column="address"></result>             <result property="sex" column="sex"></result>             <result property="birthday" column="birthday"></result>         </collection>     </resultMap>     <!--查询所有-->     <select id="findAll" resultMap="roleMap">         select u.*,r.id as rid,r.role_name,r.role_desc from role r         left outer join user_role ur on r.id = ur.rid         left outer join user u on u.id = ur.uid     </select> </mapper>
  • 测试类:user-role的一对多测试,role-user的一对多测试
    user-role的一对多测试
     package com.itheima; ? import com.itheima.dao.IUserDao; import com.itheima.domain.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; ? import java.io.IOException; import java.io.InputStream; import java.util.List; ? /**  * @Author: lijiahao  * @Description:  * @Data: Create in 22:56 2020/2/22  * @Modified By:  */ public class UserTest { ?     private InputStream in;     private SqlSession sqlSession;     private IUserDao userDao; ?     @Before     public void init() throws IOException {         //1.读取配置文件         in = Resources.getResourceAsStream("SqlMapConfig.xml");         //2.创建SqlSessionFactory工厂         SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();         SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);         sqlSession = sqlSessionFactory.openSession(true);         //3.使用工厂生产dao对象         userDao = sqlSession.getMapper(IUserDao.class);     } ?     @After     public void destory() throws IOException {         in.close();     } ?     @Test     public void testFindAll() throws IOException {         //5.使用代理对象执行方法         List<User> users = userDao.findAll();         for (User user : users) {             System.out.println(user);             System.out.println(user.getRoles());         }     } ? }
    role-user的一对多测试
     package com.itheima; ? import com.itheima.dao.IRoleDao; import com.itheima.dao.IUserDao; import com.itheima.domain.Role; import com.itheima.domain.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; ? import java.io.IOException; import java.io.InputStream; import java.util.List; ? /**  * @Author: lijiahao  * @Description:  * @Data: Create in 22:56 2020/2/22  * @Modified By:  */ public class RoleTest { ?     private InputStream in;     private SqlSession sqlSession;     private IRoleDao roleDao; ?     @Before     public void init() throws IOException {         //1.读取配置文件         in = Resources.getResourceAsStream("SqlMapConfig.xml");         //2.创建SqlSessionFactory工厂         SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();         SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);         sqlSession = sqlSessionFactory.openSession(true);         //3.使用工厂生产dao对象         roleDao = sqlSession.getMapper(IRoleDao.class);     } ?     @After     public void destory() throws IOException {         in.close();     } ?     @Test     public void testFindAll() throws IOException {         //5.使用代理对象执行方法         List<Role> roles = roleDao.findAll();         for (Role role : roles) {             System.out.println(role);         }     } ? }

原文地址:https://www.cnblogs.com/lijiahaoAA/p/12370119.html

时间: 2024-10-07 22:38:21

Mybatis的多表(多对多)查询的相关文章

mybatis学习笔记(11)-多对多查询

mybatis学习笔记(11)-多对多查询 mybatis学习笔记11-多对多查询 示例 多对多查询总结 resultMap总结 本文实现多对多查询,查询用户及用户购买商品信息. 示例 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表:orders.orderdetail.items sql SELECT orders.*, user.username, user.sex, user.address, orderdetail.id orderdeta

Django:表多对多查询、聚合分组、FQ查询、事务

1表多对多的关系查询 准备工作创建表结构 from django.db import models # Create your models here. class Publisher(models.Model): name = models.CharField(max_length=32, verbose_name="名称") def __str__(self): return self.name class Book(models.Model): title = models.Ch

mybatis 一对多和多对一关联查询

首先  数据库量表之间字段关系(没有主外键) studentmajor表的id字段对应student表里major字段 两个实体类 package com.model; import java.util.Date; public class Student { private Integer sno; private String sname; private String ssex; private Integer sclass; private StudentMajor studentmaj

SpringBoot使用Mybatis注解进行一对多和多对多查询(2)

SpringBoot使用Mybatis注解进行一对多和多对多查询 GitHub的完整示例项目地址kingboy-springboot-data 一.模拟的业务查询 系统中的用户user都有唯一对应的地址信息address,每个用户可以有多量车car,类似如下结构 |-- user |-- address |-- carList |-- car1 |-- car2 二.对应的实体类如下 /省略setter/getter public class Address { private Long id;

MyBatis框架——多表查询

MyBatis多表查询, 从表中映射主表,使用 association 标签,通过设置 javaType 属性关联实体类: 主表映射从表,使用 collection 标签,通过 ofType 属性关联实体类.    示例: 1.创建数据库 /* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50620 Source Host : 127.0.0.1:3306 Source Databas

MyBatis 用户表记录数查询

搭建MyBatis开发环境,实现用户表记录数查询 1.在MyEclipse中创建工程,导入MyBatis的jar包 2.创建MyBatis配置文件mybatis-config.xml配置数据库信息 mybatis-config.xml文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0

SpringBoot集成Mybatis实现多表查询的两种方式(基于xml)

 下面将在用户和账户进行一对一查询的基础上进行介绍SpringBoot集成Mybatis实现多表查询的基于xml的两种方式.   首先我们先创建两个数据库表,分别是user用户表和account账户表     user表:  account表:  然后创建实体类        **第一种通过创建子类的方式查询                             需求:查询所有的用户基础信息以及其所属的账户中的金额     1.创建想要得到多表查询数据的实体类(子类)            

20_高级映射:多对多查询

[需求] 查询用户及用户购买的商品信息. [SQL语句] 查询主表:用户user表 关联表:由于用户和商品没有直接关联,需通过订单和订单明细进行关联,所以关联的表是 orders.orderdetail.items [映射的思路] 将用户信息映射到user中. 在user类中添加订单列表属性List<Orders> orderlist,将用户创建的订单映射到orderslist. 在Orders中添加订单明细列表属性List<OrderDetail> orderdetails,将订

22Mybatis_订单商品数据模型_多对多查询以及对多对多查询的总结

之前讲了一对一,一对多查询,这篇文章讲的是多对多. 先给出需求:查询用户及用户购买商品信息. 我们由之前的文章知道,这个需求是多对多的. 还是那个终止我们的mybatis所做的不管是之前的一对一还是一对多还是多对多,都只是为了把查询出来的结果(每个字段)做好映射. 好,我们现在sqlyong上把数据查出来,然后做映射. 给出几张表的内容: User表: orderdetail表: orders表: items表: 我们根据需求(查询用户及用户购买商品信息)把sql语句写出来: sql: SELE