MyBatis的对象关系映射---一对多N+1策略★★★★★

在实际开发中,一个业务可能涉及到多个数据表的查询,那么多表查询就涉及连接查询(等值连接), 等值连接 表与表之间有一个外键关键,但是程序中最终获取的表封装的对象, 对象与对象之间是没有外键关系的,对象和对象之间只有依赖关系;

对象之间关系主要是四种:

一对一 关系
一个人对应身份证id,一个QQ号对应一个QQ空间

一对多 关系

一个部门对应多个员工

多对一 关系

多个员工对应一个部门

多对多 关系

多个学生对应多个老师,多个学生对应多个课程

什么关系应该从哪个对象作为中心点来看

一对多, 以one方作为中心点

MyBatis框架支持多表查询封装对象之间关系

<collection> 一对多查询 <association>多对一和一对一查询

MyBatis的对象关系映射---一一对多N+1策略:

mapper表:

 1 package top.abcdit.mybatis.mapper;
 2
 3 import top.abcdit.mybatis.pojo.Department;
 4
 5 public interface One2ManyMapper {
 6
 7     /**
 8      * 根据id查询出部门的所有信息(包括部门下面的所有员工)
 9      * @param id 部门id
10      * @return 部门对象
11      */
12
13     Department selectByPrimaryKey(Integer id);
14
15 }

One2ManyMapper.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">

<!--  映射标签,内部就编写具体的映射sql语句
    namespace :命名空间,值 必须是 对应接口的全限定名 = 包名 +简单类名
        top.abcdit.mybatis.mapper.One2ManyMapper
 -->

<mapper namespace="top.abcdit.mybatis.mapper.One2ManyMapper">

    <select id="selectByPrimaryKey" parameterType="int" resultMap="dept_map">
        select * from department where id = #{id}
    </select>

    <resultMap type="top.abcdit.mybatis.pojo.Department" id="dept_map">
        <id column="id" property="id"/>
        <result column="name" property="name"/>

        <!--
              问题: private List<Employee> employees; 员工集合如何映射?
              解决方案:使用 <collection>集合标签
              <collection property="" column="" select=""/>
              property :需要映射的属性 此时就是 employees
              column:当前部门的主键 id
              select : 需要去查询的对应员工的功能id
           -->

        <collection property="employees" column="id" select="selectEmployeesByDeptId"/>

    </resultMap>

    <!-- 联合查询的功能 -->
      <!-- 根据部门的id查询出所有的员工 -->

      <select id="selectEmployeesByDeptId" parameterType="int" resultType="top.abcdit.mybatis.pojo.Employee">
          select * from employee where dept_id = #{id}
      </select>

</mapper>

mybatis-config.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配置标签 内部就是mybatis具体配置 -->
<configuration>
    <!-- mybatis的配置环境
        default:默认使用环境,值就是下面的环境id
    -->
    <settings>
    <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

  <environments default="mysql">
      <!-- 具体某一个环境 -->
    <environment id="mysql">
    <!-- MyBatis操作需要事务管理,默认使用JDBC
            JDBC:mybatis的别名
     -->
      <transactionManager type="JDBC"/>
      <!--配置mybatis的数据源(连接池)
      POOLED(别名) :mybatis内置的一个连接池
          后期和spring集成使用,druid阿里巴巴连接池
 -->
      <dataSource type="POOLED">
          <!-- 数据库驱动 -->
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <!-- url地址 -->
        <property name="url" value="jdbc:mysql://localhost:3306/gzmybatis1?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT"/>
        <!-- 数据库的账号 -->
        <property name="username" value="root"/>
        <!-- 数据库的密码 -->
        <property name="password" value="myroot"/>
      </dataSource>
    </environment>
  </environments>

  <!-- 配置映射文件 -->
  <mappers>
          <!-- 读取单个映射文件 -->
    <mapper resource="top/abcdit/mybatis/mapper/One2ManyMapper.xml"/>
  </mappers>
</configuration>

员工和部门表:

package top.abcdit.mybatis.pojo;

import java.util.List;

public class Department {
    private Integer id;
    private String name;

    //一个部门对应多个员工:一对多关系
    //此时我们必须有集合来描述
    private List<Employee> employees;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public String toString() {
        return "Department [id=" + id + ", name=" + name + ", employees=" + employees + "]";
    }

}
package top.abcdit.mybatis.pojo;

public class Employee {

    private Integer id;
    private String name;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + "]";
    }

}

Util工具表:

package top.abcdit.mybatis.util;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisUtil {
    private MyBatisUtil() {}
    private static SqlSessionFactory sqlSessionFactory;

        static {
            //读取主配置文件
            String resource = "mybatis-config.xml";

            //java7(jdk1.7)开始,支持在try()括号里直接自动释放资源
            try(InputStream inputStream = Resources.getResourceAsStream(resource);) {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    public static SqlSession openSession() {
        //创建sqlSession回话对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;

    }

    public static void main(String[] args) {
        SqlSession sqlSession = openSession();
        System.out.println(sqlSession);
    }
}

测试表:

 1 package top.abcdit.mybatis.mapper;
 2
 3 import static org.junit.Assert.*;
 4
 5 import org.apache.ibatis.session.SqlSession;
 6 import org.junit.Test;
 7
 8 import top.abcdit.mybatis.pojo.Department;
 9 import top.abcdit.mybatis.util.MyBatisUtil;
10
11 public class One2ManyMapperTest {
12
13     @Test
14     public void testSelectByPrimaryKey() {
15
16         SqlSession session = MyBatisUtil.openSession();
17         One2ManyMapper mapper = session.getMapper(One2ManyMapper.class);
18
19         Department dept = mapper.selectByPrimaryKey(2);
20         System.out.println(dept);
21
22     }
23
24 }

输出结果:

DEBUG [main] - ==>  Preparing: select * from department where id = ?
DEBUG [main] - ==> Parameters: 2(Integer)
TRACE [main] - <==    Columns: id, name
TRACE [main] - <==        Row: 2, 研发部
DEBUG [main] - ====>  Preparing: select * from employee where dept_id = ?
DEBUG [main] - ====> Parameters: 2(Integer)
TRACE [main] - <====    Columns: id, name, dept_id
TRACE [main] - <====        Row: 2, 虚竹, 2
DEBUG [main] - <====      Total: 1
DEBUG [main] - <==      Total: 1
Department [id=2, name=研发部, employees=[Employee [id=2, name=虚竹]]]

原文地址:https://www.cnblogs.com/abcdjava/p/11192439.html

时间: 2024-10-24 10:27:50

MyBatis的对象关系映射---一对多N+1策略★★★★★的相关文章

MyBatis的对象关系映射---一对多等值连接策略★★★★★

在实际开发中,一个业务可能涉及到多个数据表的查询,那么多表查询就涉及连接查询(等值连接), 等值连接 表与表之间有一个外键关键,但是程序中最终获取的表封装的对象, 对象与对象之间是没有外键关系的,对象和对象之间只有依赖关系: 对象之间关系主要是四种: 一对一 关系一个人对应身份证id,一个QQ号对应一个QQ空间 一对多 关系 一个部门对应多个员工 多对一 关系 多个员工对应一个部门 多对多 关系 多个学生对应多个老师,多个学生对应多个课程 什么关系应该从哪个对象作为中心点来看 一对多, 以one

Hibernate (开放源代码的对象关系映射框架)

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久

Hibernate之配置文件以及对象关系映射文件了解

声明:CSDN不知道怎么了,有时候就是发表不了博文.本来就是一天一篇博文,最近搞的我很郁闷.有时候一天,有时候两三天都不能发.这就属于不可抗力.没办法的,啥时能发,我就发了. 一.学习案例:关于hibernate的配置文件以及对象关系映射文件的了解. 二.案例分析: a)hibernate配置文件(hibernate.cfg.xml) 1.hibernate.dialect:数据库使用的SQL方言 2.hiebrnate.connection.driver_class:数据库的驱动程序 3.hi

Hibernate (开放源代码的对象关系映射框架)介绍

Hibernate (开放源代码的对象关系映射框架) 编辑 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hiberna

死去活来,而不变质:Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?

写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?>博文中,探讨的是如何聚焦领域模型(抛开一些干扰因素,才能把精力集中在领域模型的设计上)?需要注意的是,上一篇我讲的并不是如何设计领域模型(本篇也是)?而是如何聚焦领域模型,领域模型的设计是个迭代过程,不能一概而论,还在路上. 当有一个简单的领域模型用例,完成一个从上而下过程的时候,就需要对领域模型和数据库进行对象关系

Flask-SQLAlchemy 配置,处理对象-关系,一对多,多对多

ORM(Object Relational Mapper) 对象关系映射.指将面对对象得方法映射到数据库中的关系对象中. Flask-SQLAlchemy是一个Flask扩展,能够支持多种数据库后台,我们可以不需要关心SQL的处理细节,操作数据库,一个基本关系对应一个类,而一个实体对应类的实例对象,通过调用方法操作数据库.Flask-SQLAlchemy有很完善的文档. Flask-SQLAlchemy是通过URL指定数据库的连接信息的. 初始化的两种方法如下(以连接Mysql数据库为例): f

解析大型.NET ERP系统数据访问 对象关系映射框架LLBL Gen Pro

LLBL Gen Pro是一个为.NET开发人员设计的的对象关系映射(ORM)框架,与NHibernate,Entity Framework等框架一样,通过实体与数据表的映射,实现关系数据库持久化. 1  LLBL Gen Pro 入门  LLBL Gen Pro Basic 打开LLBL Gen Pro程序,在右边的数据库浏览器(Catelog Explorer)中根结点右键选择从关系数据库创建关系模型( Add Relational Model Data from a Database),然

Hibernate (开源对象关系映射框架)

一.基本介绍1.它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm(对象关系映射)框架,hibernate可以自动生成SQL语句,自动执行: Hibernate可以应用在任何使用JDBC的场合. 2.持久化层:处理关系型数据库(数据存储层)和模型对象(object,业务逻辑模型)的映射关系的代码方法(ORM)3.Hibernate是一个基于JDBC的主流持久化框架,对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码,是一个优秀的

对象关系映射(ORM)

对象-关系映射(Object Relational Mapping,简称ORM,对象关系映射)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中.本质上就是将数据从一种形式转换到另外一种形式. 对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的.面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数