Mybatis双向关联

一、双向关联,以多对多为例,假定一个父母只有一个孩子,那父母和孩子对应关系为1对1,既可以通过父母查询到孩子,也可以通过孩子查询到父母。

二、

1、添加依赖包,参考上篇文章 Mybatis+mysql入门使用

2、初始化数据库和初始数据,以mysql为例

DROP DATABASE IF EXISTS moy_mybatis;
CREATE DATABASE moy_mybatis CHARACTER SET UTF8;
USE moy_mybatis;

DROP TABLE  IF EXISTS t_children;
CREATE TABLE t_children(
  children_id INT(11),
  children_name VARCHAR(50) DEFAULT NULL,
  children_birthday DATE DEFAULT NULL,
  parent_id INT(11) NOT NULL,
  PRIMARY KEY (`children_id`)
);

DROP TABLE  IF EXISTS t_parent;
CREATE TABLE t_parent(
  id INT(11)  ,
  name VARCHAR(50) DEFAULT NULL,
  birthday DATE DEFAULT NULL,
  PRIMARY KEY (id)
);

INSERT INTO t_children(children_id,children_name,children_birthday,parent_id)
VALUES (1,‘一号熊孩子‘,now(),1);
INSERT INTO t_children(children_id,children_name,children_birthday,parent_id)
VALUES (2,‘二号熊孩子‘,now(),1);
INSERT INTO t_children(children_id,children_name,children_birthday,parent_id)
VALUES (3,‘三号熊孩子‘,now(),2);

INSERT INTO t_parent(id,name,birthday)
VALUES (1,‘一号父母‘,now());
INSERT INTO t_parent(id,name,birthday)
VALUES (2,‘二号父母‘,now());

3、新建实体类Children和Parent

package com.moy.mybatis3.entity;

import java.util.Date;
import java.util.List;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/19  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public class Parent {

    private int id;
    private String name;
    private Date birthday;
    private List<Children> children;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public List<Children> getChildren() {
        return children;
    }

    public void setChildren(List<Children> children) {
        this.children = children;
    }

    @Override
    public String toString() {
        return "Parent{" +
                "id=" + id +
                ", name=‘" + name + ‘\‘‘ +
                ", birthday=" + birthday +
                ", children=" + children +
                ‘}‘;
    }
}

package com.moy.mybatis3.entity;

import java.util.Date;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/19  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public class Children {

    private int childrenId;
    private String childrenName;
    private Parent parent;
    private Date childrenBirthday;

    public int getChildrenId() {
        return childrenId;
    }

    public void setChildrenId(int childrenId) {
        this.childrenId = childrenId;
    }

    public String getChildrenName() {
        return childrenName;
    }

    public void setChildrenName(String childrenName) {
        this.childrenName = childrenName;
    }

    public Date getChildrenBirthday() {
        return childrenBirthday;
    }

    public void setChildrenBirthday(Date childrenBirthday) {
        this.childrenBirthday = childrenBirthday;
    }

    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }

    @Override
    public String toString() {
        return "Children{" +
                "childrenId=" + childrenId +
                ", childrenName=‘" + childrenName + ‘\‘‘ +
                ", parent=" + parent +
                ", childrenBirthday=" + childrenBirthday +
                ‘}‘;
    }
}

4、新建实体对应配置文件Children.xml和Parent.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.moy.mybatis3.mapper.ChildrenMapper">
    <!--双向多对1 配置方法一 开始-->
    <!--<resultMap id="ChildrenResultMap" type="Children">-->
        <!--<id property="childrenId" column="children_id"/>-->
        <!--<result property="childrenName" column="children_name"/>-->
        <!--<result property="childrenBirthday" column="children_birthday"/>-->
    <!--</resultMap>-->

    <!--<resultMap id="ChildrenExtResultMap" type="Children" extends="ChildrenResultMap">-->
        <!--<association property="parent" column="parent_id"-->
                     <!--resultMap="com.moy.mybatis3.mapper.ParentMapper.ParentResultMap"/>-->
    <!--</resultMap>-->
    <!--双向多对1 配置方法一 结束-->

    <!--双向多对1 配置方法二 开始-->
    <resultMap id="ChildrenExtResultMap" type="Children" >
        <id property="childrenId" column="children_id"/>
        <result property="childrenName" column="children_name"/>
        <result property="childrenBirthday" column="children_birthday"/>
        <association property="parent" column="parent_id" javaType="Parent">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="birthday" column="birthday"/>
        </association>
    </resultMap>
    <!--双向多对1 配置方法二 结束-->

    <select id="queryChildrenAndParent" parameterType="int" resultMap="ChildrenExtResultMap">
        SELECT p.*,c.* FROM t_Parent p , t_Children c WHERE p.id = c.parent_id and c.children_Id = #{id}
    </select>
</mapper>

<?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.moy.mybatis3.mapper.ParentMapper">
    <!--双向多对1 配置方法一 开始-->
    <!--<resultMap id="ParentResultMap" type="Parent">-->
        <!--<id property="id" column="id"/>-->
        <!--<result property="name" column="name"/>-->
        <!--<result property="birthday" column="birthday"/>-->
    <!--</resultMap>-->

    <!--<resultMap id="ParentExtResultMap" type="Parent" extends="ParentResultMap">-->
        <!--<collection property="children" resultMap="com.moy.mybatis3.mapper.ChildrenMapper.ChildrenResultMap"/>-->
    <!--</resultMap>-->
    <!--双向多对1 配置方法一 结束-->

    <!--双向多对1 配置方法二 开始-->
    <resultMap id="ParentExtResultMap" type="Parent">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="birthday" column="birthday"/>
        <collection property="children" ofType="Children">
            <id property="childrenId" column="children_id"/>
            <result property="childrenName" column="children_name"/>
            <result property="childrenBirthday" column="children_birthday"/>
        </collection>
    </resultMap>
    <!--双向多对1 配置方法二 结束-->

    <select id="queryParentAndChildren" parameterType="int" resultMap="ParentExtResultMap">
          SELECT * FROM t_Parent p LEFT JOIN t_Children c  ON  p.id = c.parent_id WHERE 1=1 AND p.id  = #{id}
    </select>
</mapper>

5、编写接口ChildrenMapper和ParentMapper

package com.moy.mybatis3.mapper;

import com.moy.mybatis3.entity.Children;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/19  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public interface ChildrenMapper extends BaseMapper<Children> {

    Children queryChildrenAndParent(int id);
}

package com.moy.mybatis3.mapper;

import com.moy.mybatis3.entity.Parent;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/19  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public interface ParentMapper extends BaseMapper<Parent> {

    Parent queryParentAndChildren(int id);
}

6、为了方便测试,编写一个获取SqlSession的工具类Mybatis3Utils

package com.moy.mybatis3.utils;

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 java.io.IOException;
import java.io.Reader;
import java.util.Objects;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/19  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public abstract class Mybatis3Utils {

    public static final SqlSessionFactory sqlSessionFactory;
    public static final ThreadLocal<SqlSession> sessionThread = new ThreadLocal<>();

    static {
        try {
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession getCurrentSqlSession() {
        SqlSession sqlSession = sessionThread.get();
        if (Objects.isNull(sqlSession)) {
            sqlSession = sqlSessionFactory.openSession();
            sessionThread.set(sqlSession);
        }
        return sqlSession;
    }

    public static void closeCurrentSession() {
        SqlSession sqlSession = sessionThread.get();
        if (Objects.nonNull(sqlSession)) {
            sqlSession.close();
        }
        sessionThread.set(null);
    }
}

7、新建mybatis配置信息文件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">
<configuration>
    <typeAliases>
        <package name="com.moy.mybatis3.entity"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/moy_mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/Parent.xml"></mapper>
        <mapper resource="mapper/Children.xml"></mapper>
    </mappers>
</configuration>

8、 编写测试类ChildrenMapperTest和ParentMapperTest

package com.moy.mybatis3.mapper;

import com.moy.mybatis3.entity.Children;
import com.moy.mybatis3.utils.Mybatis3Utils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/20  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public class ChildrenMapperTest {

    SqlSession sqlSession;
    ChildrenMapper childrenMapper;

    @Before
    public void before() {
        sqlSession = Mybatis3Utils.getCurrentSqlSession();
        childrenMapper = sqlSession.getMapper(ChildrenMapper.class);
    }

    @After
    public void after() {
        Mybatis3Utils.closeCurrentSession();
    }
    @Test
    public void queryChildrenAndParent() {
        Children children = childrenMapper.queryChildrenAndParent(2);
        System.out.println(children);
    }
}

package com.moy.mybatis3.mapper;

import com.moy.mybatis3.entity.Children;
import com.moy.mybatis3.entity.Parent;
import com.moy.mybatis3.utils.Mybatis3Utils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

import static org.junit.Assert.*;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/20  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public class ParentMapperTest {

    SqlSession sqlSession;
    ParentMapper parentMapper;

    @Before
    public void before() {
        sqlSession = Mybatis3Utils.getCurrentSqlSession();
        parentMapper = sqlSession.getMapper(ParentMapper.class);
    }

    @After
    public void after() {
        Mybatis3Utils.closeCurrentSession();
    }

    @Test
    public void queryParentAndChildren() {
        Parent parent = parentMapper.queryParentAndChildren(1);
        System.out.println(parent);
    }
}

yexiangyang

[email protected]


原文地址:https://www.cnblogs.com/moy25/p/8455923.html

时间: 2024-10-12 20:24:10

Mybatis双向关联的相关文章

Mybatis配置文件双向关联出现的问题

今天在配置mybatis的双向关联的时候,遇到了一些问题,现在在这里总结一下: 现在有学生和老师两个实体: student(N): teacher (1) 数据库的关联: Supervisor_id表示的是老师的id:是外键 Sql语句: /* Navicat MySQL Data Transfer Source Server : test Source Server Version : 50528 Source Host : localhost:3306 Source Database : c

Hibernate 一对多双向关联Demo

以Classes[班级]和Student[学生]为例的Demo //Classes.java public class Classes implements Serializable { private long cid; private String cname; private String cdesc; private Set<Student> students; //get和set } //Student .java public class Student implements Se

【Hibernate步步为营】--(一对多映射)之双向关联

上篇文章讨论了单向关联的一对多映射,在一的一端维护双向的关系这样的做法尽管能实现可是存在非常多缺陷,首先生成非常多多余的SQL语句,由于多的一端不维护关系,仅仅有一的一端维护,在进行操作时一的一端会发出多余的update语句:其次,由于多的一端不知道一的一端存在,所以在保存多的一端时假设外键为null值,而且在设计数据库时关系字段设为非空,则将无法保存数据.由于单向关联一对多存在非常多缺点那就没有其他的办法了吗,能够採用双向关联来优化. 一.一对多双向关联 这里继续採用上篇文章的学生和班级作为演

Nhibernate中一对多映射——双向关联

上一篇博客中提到的是单向关联:Nhibernate一对多映射--单向关联.这篇说说双向关联. 双向关联和单向关联的区别是:两边都能维护关系,如我查询两边的任何一边,另外一边的信息也能查询出来,其他的修改删除只要设置了,也都可以.体现在代码中是:因为上篇单向关联是在DictionaryEntity上,所以变为双向关联要在DictionTypeEntity和他对应的xml文件中加上关联映射. DictionaryEntity修改为: #region 实体属性 /// <summary> /// 类

Hibernate5-一对多双向关联-左外连接-HQL

1.创建项目,项目名称hibernatedemo18,目录结构如图所示 2.在项目中创建lib目录存储jar文件,目录结构如图所示 3.在src目录中创建实体Bean Forum,包名(com.mycompany.demo.bean),如图所示 4.实体Bean Forum的内容如下 package com.mycompany.demo.bean; import java.util.Set; public class Forum { private int fid; private String

Hibernate5-一对多双向关联-迫切左外连接-HQL

1.创建项目,项目名称hibernatedemo19,目录结构如图所示 2.在项目中创建lib目录存储jar文件,目录结构如图所示 3.在src目录中创建实体Bean Forum,包名(com.mycompany.demo.bean),如图所示 4.实体Bean Forum的内容如下 package com.mycompany.demo.bean; import java.util.Set; public class Forum { private int fid; private String

hibernate一对多双向关联

14.一对多双向关联 1.在多的一方关联一的一方,多的一方直接维护了关系,所以多的一方没有inverse属性,多的一方在保存自己的时候直接保存了外键,效率高. 2.建立关系和保存对象,可以对应两个映射文件,保存多的一方自己对应自己的映射文件,建立关系可以使用一的一方表的inverse属性.这样发出update语句,效率低了.一对多,从多的一方建立关系,效率高. 例子 在student这边保存属性private Classess classess; 在student.hbm.xml文件在<clas

关于SSH 持久对象转Json双向关联解析过度的解决办法

小弟是一名被部分程序员所鄙视的培训狗,昨天做项目遇到一个问题,在SSH框架通过ajax向界面传递数据的时候,由于对象之间双向关联导致json解析过度,造成内存溢出,网上搜索了解决办法除了过滤某些关联对象之外就没有别的办法了,我的想法是通过设置解析深度来解决过度抓取的问题,开始也考虑性能问题,最好的解决办法就是做一个视图,单独写一个model .但是又不希望这样繁琐,后来发现换个观点一想,能解决这个过度解析的问题对系统的性能的提升其实也很大了,所以就自己动手准备写一个转换工具类,办法也很明了递归.

【Hibernate步步为营】--双向关联一对一映射详解(二)

很不好意思,有两天时间没有更新博客文章了,不写文章的日子还真是感觉很空洞啊,养成了写文章的恶习想改也改不掉啊.说点题外话,前两天收到一位朋友的私信,邀请笔者写一篇有关OWS的文章,用来研究图标工具的一种技术,很荣幸收到这位朋友的邀请,但是因为这几天开发的项目着急上线所以暂时没有时间去研究,只能等这周末了,利用周末的时间来研究然后更新类似的技术文章. 回到文章的正题,上篇文章讨论了双向主键关联,它其实是一对一主键关联的一种特殊情况,想要实现双向的关联就必须在映射文件的两端同时配置<one-to-o