欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mybatis多表查询(一对多,多对一,多对多)

程序员文章站 2022-05-23 17:53:25
...

多对一、一对多

准备阶段

建立一个部门表和员工表:
多个员工可以同属一个部门:这是多对一
一个部门有多个员工:这是一对多
首先在mysql数据库中建表。建立dept表和emp表
mybatis多表查询(一对多,多对一,多对多)
dept表
mybatis多表查询(一对多,多对一,多对多)
emp表

建立dept实体类和emp实体类

emp实体类(其中包含部门的实体类对象)
mybatis多表查询(一对多,多对一,多对多)
dept实体类(包含员工的实体类对象集合)
mybatis多表查询(一对多,多对一,多对多)

建立Dao接口

查询所有员工的Dao接口

public interface IEmpDao {

    /**
     *查询所有操作
     * @return
     */
    List<Emp> findAll();
}

查询所有部门的Dao接口

public interface IDeptDao {
    /**
     *查询所有操作
     * @return
     */
    List<Dept> findAll();
}

写Dao的Mapper映射

Emp的Mapper映射文件
mybatis多表查询(一对多,多对一,多对多)
完整配置如下:

<?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.jjp.dao.IEmpDao">
    <!--这边配置java对应的数据库映射-->
    <resultMap type="emp" id="empMap">
        <!--配置主键-->
        <id property="e_id" column="e_id"/>
        <!--配置非主键-->
        <result property="e_name" column="e_name"/>
        <result property="e_tel" column="e_tel"/>
        <result property="e_dept" column="e_dept"/>
        <result property="e_time" column="e_time"/>
        <!--里面为另一张表的关联-->
        <association property="type" javaType="dept">
            <id property="d_id" column="d_id"/>
            <result property="d_name" column="d_name"/>
        </association>
    </resultMap>

    <!--查询所有-->
    <select id="findAll" resultMap="empMap">
          select *from emp left join dept on emp.e_dept=dept.d_id
    </select>

</mapper>

dept的Mapper映射文件
mybatis多表查询(一对多,多对一,多对多)

完整配置如下:

<?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.jjp.dao.IDeptDao">
    <!--这边配置java对应的数据库映射-->
    <resultMap type="dept" id="deptMap">
        <!--配置主键-->
        <id property="d_id" column="d_id"/>
        <!--配置非主键-->
        <result property="d_name" column="d_name"/>
        <collection property="empType" ofType="emp">
            <!--配置主键-->
            <id property="e_id" column="e_id"/>
            <!--配置非主键-->
            <result property="e_name" column="e_name"/>
            <result property="e_tel" column="e_tel"/>
            <result property="e_dept" column="e_dept"/>
            <result property="e_time" column="e_time"/>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="deptMap">
        select * from dept d left join emp e on d.d_id=e.e_dept
    </select>
</mapper>

主配置文件中的别名配置
mybatis多表查询(一对多,多对一,多对多)
完整配置如下:

<?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>
        <property name="driver" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/ssmdemo?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT" />
        <property name="username" value="root" />
        <property name="password" value="J123" />
    </properties>
    <typeAliases>
        <typeAlias type="com.jjp.domain.Emp" alias="emp"/>
        <typeAlias type="com.jjp.domain.Dept" alias="dept"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" />
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com\jjp\dao\IEmpDao.xml"/>
        <mapper resource="com\jjp\dao\IDeptDao.xml"/>
    </mappers>
</configuration>

然后在测试文件中编写测试类
多对一测试类EmpTest

package com.jjp.test;

import com.jjp.dao.IEmpDao;
import com.jjp.dao.IUserDao;
import com.jjp.domain.Emp;
import com.jjp.domain.QueryVo;
import com.jjp.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.InputStream;
import java.util.Date;
import java.util.List;
public class EmpTest {

    private InputStream in;
    private SqlSession sqlSession;
    private IEmpDao EmpDao;

    @Before
    /**用于在测试方法执行之前执行*/
    public void init() throws Exception {
        /**1.读取配置文件,生成字节输入流*/
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        /**2.获取SqlSessionFactory*/
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        /**3.获取SqlSession对象*/
        sqlSession = factory.openSession();
        /**4.获取dao的代理对象*/
        EmpDao = sqlSession.getMapper(IEmpDao.class);
    }


    @After
    /**用于在测试方法执行之后执行*/
    public void destory() throws Exception {
        /**提交事务*/
        sqlSession.commit();
        /**释放资源*/
        sqlSession.close();
        in.close();
    }


    /**
     * 测试查询所有
     */
    @Test  /**多对一查询*/
    public void testFindAll() {
        /**执行查询的所有方法*/
        List<Emp> Emps = EmpDao.findAll();
        for(Emp emp:Emps){
            System.out.println(emp);
        }
    }

}

运行结果如下:

Emp{e_id=41, e_name='老王', e_tel='133', e_dept=1, e_time=Tue Feb 27 17:47:08 CST 2018, type=Dept{d_id=1, d_name='产品部', empType=null}}
Emp{e_id=42, e_name='老李', e_tel='135', e_dept=2, e_time=Tue Feb 27 17:47:08 CST 2018, type=Dept{d_id=2, d_name='市场部', empType=null}}
Emp{e_id=43, e_name='老宋', e_tel='138', e_dept=2, e_time=Tue Feb 27 17:47:08 CST 2018, type=Dept{d_id=2, d_name='市场部', empType=null}}
Emp{e_id=44, e_name='老杨', e_tel='137', e_dept=3, e_time=Tue Feb 27 17:47:08 CST 2018, type=Dept{d_id=3, d_name='销售部', empType=null}}

一对多测试类DeptTest

package com.jjp.test;

import com.jjp.dao.IDeptDao;
import com.jjp.dao.IEmpDao;
import com.jjp.domain.Dept;
import com.jjp.domain.Emp;
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.InputStream;
import java.util.List;

public class DeptTest {

    private InputStream in;
    private SqlSession sqlSession;
    private IDeptDao DeptDao;

    @Before
    /**用于在测试方法执行之前执行*/
    public void init() throws Exception {
        /**1.读取配置文件,生成字节输入流*/
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        /**2.获取SqlSessionFactory*/
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        /**3.获取SqlSession对象*/
        sqlSession = factory.openSession();
        /**4.获取dao的代理对象*/
        DeptDao = sqlSession.getMapper(IDeptDao.class);
    }


    @After
    /**用于在测试方法执行之后执行*/
    public void destory() throws Exception {
        /**提交事务*/
        sqlSession.commit();
        /**释放资源*/
        sqlSession.close();
        in.close();
    }


    /**
     * 测试查询所有
     */
    @Test
    /**多对一查询*/
    public void testFindAll() {
        /**执行查询的所有方法*/
        List<Dept> Depts = DeptDao.findAll();
        for(Dept dept:Depts){
            System.out.println(dept);
        }
    }
}

运行结果如下:

Dept{d_id=1, d_name='产品部', empType=[Emp{e_id=41, e_name='老王', e_tel='133', e_dept=1, e_time=Tue Feb 27 17:47:08 CST 2018, type=null}]}
Dept{d_id=2, d_name='市场部', empType=[Emp{e_id=42, e_name='老李', e_tel='135', e_dept=2, e_time=Tue Feb 27 17:47:08 CST 2018, type=null}, Emp{e_id=43, e_name='老宋', e_tel='138', e_dept=2, e_time=Tue Feb 27 17:47:08 CST 2018, type=null}]}
Dept{d_id=3, d_name='销售部', empType=[Emp{e_id=44, e_name='老杨', e_tel='137', e_dept=3, e_time=Tue Feb 27 17:47:08 CST 2018, type=null}]}

多对多

多对多配置就是两个一对多的结合,再加上一个中间表
一个用户可能有多种角色
一个角色也可能对应多个用户。
在mysql中创建user表 role表 以及user_role中间映射表

role表:
mybatis多表查询(一对多,多对一,多对多)
user表:
mybatis多表查询(一对多,多对一,多对多)
user_role表
mybatis多表查询(一对多,多对一,多对多)
然后表创建好后,按照上述流程创建user表和role表的实体类,以及在主配置文件中起好实体类的别名。并创建user类和role类的Dao接口。接着配置映射文件。如下所示
IUserDao.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.jjp.dao.IUserDao">
    <!-- 定义User的resultMap-->
    <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>
        <!-- 配置角色集合的映射 -->
        <collection property="roles" ofType="role">
            <id property="roleId" column="rid"></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>
</mapper>

IRoleDao.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.jjp.dao.IRoleDao">
    <!--定义role表的ResultMap-->
    <resultMap id="roleMap" type="role">
        <id property="roleId" column="rid"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
        <collection property="users" ofType="user">
            <id column="id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="address" property="address"></result>
            <result column="sex" property="sex"></result>
            <result column="birthday" property="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>

接下来编写测试类。并测试得到结果如下:
运行UserTest

-----每个用户的信息------
User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京', roles=[Role{roleId=1, roleName='院长', roleDesc='管理整个学院', users=null}, Role{roleId=2, roleName='总裁', roleDesc='管理整个公司', users=null}]}
-----每个用户的信息------
User{id=45, username='传智播客', birthday=Sun Mar 04 12:04:06 CST 2018, sex='男', address='北京金燕龙', roles=[Role{roleId=1, roleName='院长', roleDesc='管理整个学院', users=null}]}
-----每个用户的信息------
User{id=42, username='小二王', birthday=Fri Mar 02 15:09:37 CST 2018, sex='女', address='北京金燕龙', roles=[]}
-----每个用户的信息------
User{id=43, username='小二王', birthday=Sun Mar 04 11:34:34 CST 2018, sex='女', address='北京金燕龙', roles=[]}
-----每个用户的信息------
User{id=46, username='老王', birthday=Wed Mar 07 17:37:26 CST 2018, sex='男', address='北京', roles=[]}
-----每个用户的信息------
User{id=49, username='modify,User property', birthday=Mon Nov 04 21:49:45 CST 2019, sex='男', address='北京市顺义区', roles=[]}
-----每个用户的信息------
User{id=50, username='mybastis update user', birthday=Mon Nov 04 21:53:56 CST 2019, sex='女', address='北京市顺义区', roles=[]}

运行RoleTest

---每个角色的信息----
Role{roleId=1, roleName='院长', roleDesc='管理整个学院', users=[User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京', roles=null}, User{id=45, username='传智播客', birthday=Sun Mar 04 12:04:06 CST 2018, sex='男', address='北京金燕龙', roles=null}]}
---每个角色的信息----
Role{roleId=2, roleName='总裁', roleDesc='管理整个公司', users=[User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京', roles=null}]}
---每个角色的信息----
Role{roleId=3, roleName='校长', roleDesc='管理整个学校', users=[]}

这就是多对多配置