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

2.对象关系映射

程序员文章站 2022-04-22 08:21:49
...

一.对象关系映射

  1. 关联关系:A对象依赖B对象,并且把B对象作为A对象的一个属性,则A和B是关联关系.
    1. 按照多重性分:
      1. 一对一:一个A对象属于一个B对象,一个B对象属于一个A对象.
        QQNumber和QQZone
      2. 一对多:一个A对象包含多个B对象.Department和Employee
      3. 多对一:多个A对象属于一个B对象,并且每个A对象只能属于一个B对象. Employee和Department
      4. 多对多:一个A对象属于多个B对象,一个B对象属于多个A对象.
    2. 按照导航性分:如果通过A对象中的某一个属性可以访问该属性对应的B对象,则说A可以导航到B. Student和Teacher
      1. 单向:只能从A通过属性导航到B,B不能导航到A.
      2. 双向:A可以通过属性导航到B,B也可以通过属性导航到A.
        关系是单向还是双向的并没有明确的要求,需要取决公司业务需求.

二.many2one

表结构

department

CREATE TABLE `department` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

employee

CREATE TABLE `employee` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `dept_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;


实体类Department

@[email protected]
public class Department {
    private Long id;
    private String name;
}

接口DepartmentMapper

public interface DepartmentMapper {
    void save(Department entity);
    Department get(Long id);
}

实体类Employee

//many方,many有外键
@Setter
@Getter
public class Employee {
    private Long id;
    private String name;
    private Department dept;

    @Override
    public String  toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

接口EmployeeMapper

public interface EmployeeMapper {
    void save(Employee entity);
    Employee get(Long id);
}

DepartmentMapper.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.dusk.many2one.DepartmentMapper">
    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into department(name) values(#{name})
    </insert>
    <select id="get" resultType="com.dusk.many2one.Department">
        select * from department where id=#{id}
    </select>
</mapper>

EmployeeMapper.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.dusk.many2one.EmployeeMapper">
    <resultMap id="baseMap" type="com.dusk.many2one.Employee">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <association property="dept"
                     javaType="com.dusk.many2one.Department">
            <!--
                association:映射关联关系
                property:封装好的对象,设置给对象中的哪个属性
                javaType:把关联对象封装成类型
             -->
            <id column="id" property="id"/>
            <result column="name" property="name"/>
        </association>
    </resultMap>
    <select id="get" resultMap="baseMap">
      select e.id, e.name, d.id did, d.name dname from employee e
      left join department d on e.dept_id = d.id
      where e.id = #{id}
    </select>
    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into employee (name,dept_id) VALUES (#{name},#{dept.id})
    </insert>
</mapper>

测试类App

public class App {
    @Test
    public void testSave() throws Exception{
        SqlSession session = MyBatisUtil.getSqlSession();
        DepartmentMapper deptMapper = session.getMapper(DepartmentMapper.class);
        EmployeeMapper empMapper = session.getMapper(EmployeeMapper.class);
        //建立对象之间的关系
        Department d = new Department();
        d.setName("开发部");

        Employee e = new Employee();
        e.setName("Dusk");
        e.setDept(d);//建立关系
        //保存对象
        //先保存one方,在保存many方
        deptMapper.save(d);
        empMapper.save(e);
        session.commit();
        session.close();
    }

    @Test
    public void testGet() throws Exception{
        SqlSession session = MyBatisUtil.getSqlSession();
        EmployeeMapper empMapper = session.getMapper(EmployeeMapper.class);
        Employee emp = empMapper.get(1L);
        System.out.println(emp);
        System.out.println(emp.getDept());
        session.close();
    }
}

三.单向one2many

DepartmentMapper.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.dusk.one2many.DepartmentMapper">
    <resultMap id="baseMap" type="com.dusk.one2many.Department">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <!-- ofType:集合中对象的类型 -->
        <collection property="emps"
                    columnPrefix="e_"
                    ofType="com.dusk.one2many.Employee">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
        </collection>
    </resultMap>
    <select id="list" resultMap="baseMap">
        select d.id, d.name, e.id e_id,e.name e_name
        from department d
        left employee e
        join department d
        on d.id = e.dept_id
    </select>
    <select id="get" resultMap="baseMap">
        select id, name from department where id = #{id}
    </select>
    <update id="updateRelation">
        update employee set dept_id =#{deptId} where id = #{eid}
    </update>

    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into department(name) values(#{name})
    </insert>
</mapper>

EmployeeMapper.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.dusk.one2many.EmployeeMapper">
    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into employee (name) values(#{name})
    </insert>
    <select id="getEmpsByDeptId" resultType="com.dusk.one2many.Employee">
        select * from employee where dept_id = #{id}
    </select>
</mapper>

实体类Department

//one方
@[email protected]
public class Department {
    private Long id;
    private String name;
    //one2many
    private List<Employee> emps = new ArrayList<>();

    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

接口DepartmentMapper

public interface DepartmentMapper {
    void save(Department entity);
    Department get(Long id);
    void updateRelation(@Param("deptId")Long deptId,@Param("eid")Long eid);
}

实体类Employee

//many方
@[email protected]
public class Employee {
    private Long id;
    private String name;

    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

接口EmployeeMapper

public interface EmployeeMapper {
    void save(Employee entity);
    Employee getEmpsByDeptId(Long id);
}

测试类App

public class App {
    @Test
    public void testSave(){
        SqlSession session = MyBatisUtil.getSqlSession();
        DepartmentMapper deptMapper = session.getMapper(DepartmentMapper.class);
        EmployeeMapper empMapper = session.getMapper(EmployeeMapper.class);

        //创建对象
        Department d = new Department();
        d.setName("开发部");

        Employee e1 = new Employee();
        e1.setName("bunny");
        Employee e2 = new Employee();
        e2.setName("Dusk");
        //建立one2many关系
        List<Employee> emps = d.getEmps();
        emps.add(e1);
        emps.add(e2);

        //保存对象
        deptMapper.save(d);
        empMapper.save(e1);
        empMapper.save(e2);
        for (Employee emp : emps) {
            deptMapper.updateRelation(d.getId(), emp.getId());
        }
        session.commit();
        session.close();
    }

    @Test
    public void testGet() {
        SqlSession session = MyBatisUtil.getSqlSession();
        DepartmentMapper deptMapper = session.getMapper(DepartmentMapper.class);
        Department d = deptMapper.get(2L);
        for (Employee employee : d.getEmps()) {
            System.out.println(employee);
        }
    }
}

四.双向one2many

DepartmentMapper.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.dusk.doubleone2many.DepartmentMapper">
    <resultMap id="baseMap" type="com.dusk.doubleone2many.Department">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <collection property="emps"
                    column="id"
                    ofType="com.dusk.doubleone2many.Employee"
                    select="com.dusk.doubleone2many.EmployeeMapper.getEmpsByDeptId"/>
    </resultMap>
    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into department(name) VALUES (#{name})
    </insert>

    <select id="get" resultMap="baseMap">
        select * from department where id = #{id}
    </select>
</mapper>

EmployeeMapper.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.dusk.doubleone2many.EmployeeMapper">
    <resultMap id="baseMap" type="com.dusk.doubleone2many.Employee">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <association property="dept"
                     column="dept_id"
                     javaType="com.dusk.doubleone2many.Department"
                     select="com.dusk.doubleone2many.DepartmentMapper.get"/>
    </resultMap>

    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into employee(name,dept_id) values(#{name},#{dept.id})
    </insert>

    <select id="getEmpsByDeptId" resultType="com.dusk.doubleone2many.Employee">
        select * from employee where dept_id = #{id}
    </select>

    <select id="get" resultMap="baseMap">
        select * from employee where id = #{id}
    </select>
</mapper>

实体类Department

@[email protected]
public class Department {
    private Long id;
    private String name;

    private List<Employee> emps = new ArrayList<>();

    public String toString() {
        return "Department{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}

接口DepartmentMapper

public interface DepartmentMapper {
    void save(Department d);
    Department get(Long id);
}

实体类Employee

@[email protected]
public class Employee {
    private Long id;
    private String name;
    private Department dept;

    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}

接口EmployeeMapper

public interface EmployeeMapper {
    void save(Employee e);
    Employee getEmpsByDeptId(Long id);
    Employee get(Long id);
}

测试类App

public class App {
    @Test
    public void save(){
        SqlSession session = MyBatisUtil.getSqlSession();
        DepartmentMapper depMapper = session.getMapper(DepartmentMapper.class);
        EmployeeMapper empMapper = session.getMapper(EmployeeMapper.class);

        Employee e = new Employee();
        e.setName("栗子球");

        Employee e1 = new Employee();
        e1.setName("彩翼栗子球");


        Department d = new Department();
        d.setName("开发部");


        e.setDept(d);
        e1.setDept(d);

        depMapper.save(d);
        empMapper.save(e);
        empMapper.save(e1);

        session.commit();
        session.close();
    }

    @Test
    public void oneGetMany(){
        SqlSession session = MyBatisUtil.getSqlSession();
        DepartmentMapper depMapper = session.getMapper(DepartmentMapper.class);
        EmployeeMapper empMapper = session.getMapper(EmployeeMapper.class);

        Department d = depMapper.get(2L);
        List<Employee> list = d.getEmps();
        for (Employee employee : list) {
            System.out.println(employee);
        }
        session.commit();
        session.close();
    }

    @Test
    public void manyGetOne(){
        SqlSession session = MyBatisUtil.getSqlSession();
        DepartmentMapper depMapper = session.getMapper(DepartmentMapper.class);
        EmployeeMapper empMapper = session.getMapper(EmployeeMapper.class);

        Employee e = empMapper.get(3L);
        Department d = e.getDept();

        System.out.println(e);
        System.out.println(d);

        session.commit();
        session.close();
    }

}

五.单向Many2Many

StudentMapper.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.dusk.many2many.StudentMapper">
    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into student(name) values(#{name})
    </insert>
    <select id="getStuByTeacher" resultType="com.dusk.many2many.Student">
        select * from student where id in (
          select s_id from teacher_student where t_id = #{id}
        )
    </select>
</mapper>

TeacherMapper.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.dusk.many2many.TeacherMapper">
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
    <resultMap id="baseMap" type="com.dusk.many2many.Teacher">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <collection property="stus"
                    column="id"
                    ofType="com.dusk.many2many.Student"
                    select="com.dusk.many2many.StudentMapper.getStuByTeacher"/>
    </resultMap>
    <select id="get" resultMap="baseMap">
        select id,name from teacher where id = #{id}
    </select>
    <insert id="save" useGeneratedKeys="true" keyProperty="id">
        insert into teacher(name) values(#{name})
    </insert>

    <insert id="saveRelation">
        insert into teacher_student(t_id,s_id) values(#{tId},#{sId})
    </insert>

    <resultMap id="baseMap1" type="com.dusk.many2many.Teacher">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <collection property="stus"
                    ofType="com.dusk.many2many.Student">
            <id property="id" column="sId"/>
            <result column="sName" property="name"/>
        </collection>
    </resultMap>
    <select id="getList" resultMap="baseMap1">
        select
          t.id, t.name, s.id sId,s.name sName
        from
          teacher t
        left join
          teacher_student ts
        on
          t.id = ts.t_Id
        left join
          student s
        on
          ts.s_id = s.id
        where
          t.id = #{id}
    </select>

    <delete id="deleteRelation">
        delete from teacher_student where t_id=#{tId}
    </delete>
    <delete id="delete">
        delete from teacher where id = #{id}
    </delete>
</mapper>

实体类Student

@[email protected]@ToString
public class Student {
    private Long id;
    private String name;
}

接口StudentMapper

public interface StudentMapper {
    void save(Student s);

    Student getStuByTeacher(Long id);
}

实体类Teacher

@[email protected]
public class Teacher {
    private Long id;
    private String name;

    private List<Student> stus = new ArrayList<>();

    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}

接口TeacherMapper

public interface TeacherMapper {
    void save(Teacher t);

    void saveRelation(@Param("tId")Long tId,@Param("sId")Long sId);

    Teacher get(Long id);

    Teacher getList(Long id);

    void deleteRelation(Long id);

    void delete(Long id);
}

测试类App

public class App {
    @Test
    public void delete(){
        SqlSession session = MyBatisUtil.getSqlSession();
        TeacherMapper tMapper = session.getMapper(TeacherMapper.class);
        tMapper.deleteRelation(2L);
        tMapper.delete(2L);
        session.commit();
        session.close();
    }

    @Test
    public void getList(){
        SqlSession session = MyBatisUtil.getSqlSession();
        TeacherMapper tMapper = session.getMapper(TeacherMapper.class);
        Teacher t = tMapper.getList(2L);
        System.out.println("老湿" + t);
        for (Student s : t.getStus()) {
            System.out.println("学生" + s);
        }
        session.commit();
        session.close();
    }

    @Test
    public void get(){
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentMapper stuMapper = session.getMapper(StudentMapper.class);
        TeacherMapper teaMapper = session.getMapper(TeacherMapper.class);
        Teacher t = teaMapper.get(2L);
        System.out.println("老湿"+t);
        for (Student s : t.getStus()) {
            System.out.println("学生" + s);
        }
        session.commit();
        session.close();
    }
    @Test
    public void save(){
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentMapper stuMapper = session.getMapper(StudentMapper.class);
        TeacherMapper teaMapper = session.getMapper(TeacherMapper.class);
        //老湿
        Teacher t = new Teacher();
        t.setName("舱老湿");
        //学生
        Student s = new Student();
        s.setName("小黑");

        Student s1 = new Student();
        s1.setName("小白");
        //添加关系
        t.getStus().add(s);
        t.getStus().add(s1);
        //保存老湿,学生
        teaMapper.save(t);
        stuMapper.save(s);
        stuMapper.save(s1);
        //保存关系
        for (Student student : t.getStus()) {
            teaMapper.saveRelation(t.getId(),student.getId());
        }
        session.commit();
        session.close();
    }
}