当前位置: 首页 > news >正文

MyBatis的关联关系 一对一 一对多 多对多

一对一示例

 

一个妻子对应一个丈夫
数据库表设计时 在妻子表中添加一个丈夫主键的作为外键

1 对应的JavaBean代码
虽然在数据库里只有一方配置的外键,但是这个一对一是双向的关系。
Husband实体类

public class Husband implements Serializable{
private int hid;
private String hname;
private Wife wife;
public int getHid() {
return hid;
}
public void setHid(int hid) {
this.hid = hid;
}
public String getHname() {
return hname;
}
public void setHname(String hname) {
this.hname = hname;
}
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}

Wife 实体类

public class Wife implements Serializable{
private int wid;
private String wname;
private Husband husband;
public int getWid() {
return wid;
}
public void setWid(int wid) {
this.wid = wid;
}
public String getWname() {
return wname;
}
public void setWname(String wname) {
this.wname = wname;
}
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
public Wife(int wid, String wname, Husband husband) {
super();
this.wid = wid;
this.wname = wname;
this.husband = husband;
}
}
2 编写接口 ,定义方法
public interface HusbandMapper {
//根据id查询丈夫
public Husband queryHusbandById(int id);
//根据id查询丈夫和妻子
public Husband queryHusbandAndWife(int id);
}
3 编写实体类的映射文件 XXXMapper.xml

注意点 :双向一对一关联 有两种配置文件的写法
方式1:嵌套结果 使用嵌套结果映射来处理重复的联合结果的子集  封装联表查询的数据(去除重复的数据)
方式2:嵌套查询 通过执行另外一个SQL映射语句来返回预期的复杂类型

<?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.szjx.mapper.HusbandMapper">
<select id="queryHusbandById" resultType="Husband" parameterType="int">
select * from husband where hid=#{hid}
</select>


<!-- 查询丈夫和妻子    双向一对一的关系映射-->
<!-- 两种方式  
   1、 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
           封装联表查询的数据(去除重复的数据)-->
<select id="queryHusbandAndWife" resultMap="husbandAndWife" parameterType="int">
select * from husband h left outer join wife w
on h.wid=w.wid where h.hid=#{hid}
</select>
<!-- 一对一双向关联   两种自定义返回集结果 -->
 <resultMap type="Husband" id="husbandAndWife">
<id property="hid" column="hid"/>
<result property="hname" column="hname"/>
<!--多表联合查询  必须要映射   不映射会报错-->
<association property="wife" javaType="Wife">
<id property="wid" column="wid"/>
<result property="wname" column="wname"/>
</association>
</resultMap> 

<!-- 方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
           SELECT   * FROM class WHERE c_id=1;
           SELECT   * FROM teacher WHERE t_id=1   //1 是上一个查询得到的teacher_id的值 -->
     <select id="queryHusbandAndWife2" resultMap="husbandAndWife2" parameterType="int">
      select * from husband where hid=#{hid}
     </select>
     <resultMap type="Husband" id="husbandAndWife2">
      <id property="hid" column="hid"/>
      <result property="hname" column="hname"/>
      <association property="wife" javaType="Wife" select="getWife" column="wid"></association>
     </resultMap>
     <select id="getWife" resultType="Wife" parameterType="int">
      select * from wife where wid=#{wid}
     </select>
  
</mapper> 
4编写测试
public class One2OneTest {
private SqlSession sqlSession;
private HusbandMapper mapper;
@Before
public void before(){
//获取session
sqlSession=DBTools.getSession();
mapper=sqlSession.getMapper(HusbandMapper.class);
}
@After
public void after(){
//提交事务
sqlSession.commit();
}
@Test
public void queryHusband(){
Husband h=mapper.queryHusbandById(1);//根据id查询丈夫
System.out.println(h);
}
@Test
public void queryHusbandAndWife(){
Husband h=mapper.queryHusbandAndWife(1);//嵌套结果    
System.out.println(h);
}
@Test
public void queryHusbandAndWife2(){
Husband h=mapper.queryHusbandAndWife2(1);//嵌套查询
System.out.println(h);
}
}

 

一对多

示例 : 一个人有 多个手机
1数据库表的设计 手机表 作为 子表 有人 表 里的主键 作为外键



2 实体类的设计
Person

 

public class Person {
private int pid;
private String pname;
private List<Phone> pList;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public List<Phone> getpList() {
return pList;
}
public void setpList(List<Phone> pList) {
this.pList = pList;
}
}

 

Phone 类

public class Phone {
private int tid;
private String tname;
private Person person;
public int getTid() {
return tid;
}
public void setTid(int tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}

一对多 演示两个操作   1批量操作 2查询操作

1批量操作

定义 mapper接口 方法 和 xxxMapper.xml 映射文件

public interface PhoneMapper {
//批量保存手机
public int batchSavePhone(@Param("phones") List<Phone> phones);
}

   PhoneMapper.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.szjx.mapper.PhoneMapper">
<insert id="batchSavePhone">
insert into phone values
<!-- 注意点  collection 的集合 是mapper接口中定义的@Param("phones")的值   ,两个必须映射对应,否则就会报错 -->
<foreach collection="phones" item="phone" separator=",">
<!--collection 为用于遍历的元素(必选),支持数组、List、Set  -->
      <!-- item 表示集合中每一个元素进行迭代时的别名. -->
      <!--separator表示在每次进行迭代之间以什么符号作为分隔 符.  -->
(null,#{phone.tname},#{phone.person.pid})
</foreach>
</insert>
</mapper> 

 

4批量插入操作功能实现

public class One2ManyTest {
    private SqlSession sqlSession;
    private PhoneMapper mapper;
    @Before
    public void before(){
        //获取session
        sqlSession=DBTools.getSession();
        mapper=sqlSession.getMapper(PhoneMapper.class);
    }
    @After
    public void after(){
        //提交事务
        sqlSession.commit();
    }
    @Test
    public void batchSavePhone(){//批量保存数据
        //在进行批量插入操作时 ,需要到 主表的主键 ,这时候可以将主表的数据从数据库中查询出来 在进行批量插入的操作 。
        Person person=new Person();//这里就new一个对象作为主表对象 并设置主键的id
        person.setPid(1);
        List<Phone> phones=new ArrayList<>();
        for(int i=0;i<10;i++){
            Phone phone=new Phone(i,"ipone"+i,person);
            phones.add(phone);
        }
        System.out.println(phones);
        mapper.batchSavePhone(phones);
    }
}

2一对多查询功能的实现

3 定义 mapper接口 方法 和 xxxMapper.xml 映射文件
PersonMapper

public interface PersonMapper {
//添加人
public int savePerson(Person person);
//根据id查询人的资料
public Person findPersonById(int id);
//根据id查询人与手机的资料
public Person findPersonAndPhone(int id);

PersonMapper.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.szjx.mapper.PersonMapper">
<!-- 保存操作 -->
<insert id="savePerson" parameterType="Person">
insert into person values(null,#{pname})
</insert>
<!-- 根据ID查询人员信息   返回值 类型是 Person类  -->
<select id="findPersonById" parameterType="int" resultType="Person">
select * from person where pid=#{pid}
</select>
<!-- 根据id查询人员和手机号   自定义返回结果集   -->
<select id="findPersonAndPhone" parameterType="int" resultMap="personAndPhone">
select * from person p left outer join phone t
on p.pid= t.pid where p.pid=#{pid}
</select>
<!-- 自定义返回结果集  方式1:嵌套结果   -->
<resultMap type="Person" id="personAndPhone">
<id property="pid" column="pid"/>
<result property="pname" column="pname"/>
<!-- 注意点  集合的属性值  :必须是实体类中 集合的成员变量名 -->
<collection property="pList" ofType="Phone">
<id property="tid" column="tid"/>
<result property="tname" column="tname"/>
</collection>
</resultMap>
</mapper> 

 

一对多查询功能实现

public class One2ManyTest2 {
private SqlSession sqlSession;
private PersonMapper mapper;
@Before
public void before(){
//获取session
sqlSession=DBTools.getSession();
mapper=sqlSession.getMapper(PersonMapper.class);
}

@After
public void after(){
//提交事务
sqlSession.commit();
}
@Test
public void findPersonById(){
//根据id查询人员信息
Person person=mapper.findPersonById(1);
System.out.println(person.getPname());
}
@Test
public void findPersonAndPhoneById(){
//根据id查询人员和手机信息
Person person=mapper.findPersonAndPhone(1);
System.out.println(person);
}
}

 














































转载于:https://www.cnblogs.com/aima1013/p/6144861.html

相关文章:

  • iOS—仿微信单击放大图片
  • 内核优化参数
  • webpack搭建前端一条龙服务
  • 敏捷开发Scrum
  • 1.ASP.NET MVC使用EPPlus,导出数据到Excel中
  • redis学习笔记
  • 设计师必看的8个TED 演讲
  • [ solr入门 ] - 利用solrJ进行检索
  • hudson运行出现java.io.IOException Cannot run program的错误分析
  • shell之变量和引用
  • GIT教程
  • ios UIApplocation 中APP启动方式
  • 推送知识点2
  • 各种数据库连接字符串
  • Java程序,JDK的安装、环境的配置
  • JS 中的深拷贝与浅拷贝
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • Angular 响应式表单 基础例子
  • Gradle 5.0 正式版发布
  • interface和setter,getter
  • Java到底能干嘛?
  • java多线程
  • Odoo domain写法及运用
  • python学习笔记 - ThreadLocal
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Spark RDD学习: aggregate函数
  • Terraform入门 - 1. 安装Terraform
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 浮现式设计
  • - 概述 - 《设计模式(极简c++版)》
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 小程序button引导用户授权
  • 移动端解决方案学习记录
  • ​Python 3 新特性:类型注解
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (C语言)fgets与fputs函数详解
  • (java)关于Thread的挂起和恢复
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (正则)提取页面里的img标签
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • .Mobi域名介绍
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .Net各种迷惑命名解释
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择
  • [BZOJ] 2427: [HAOI2010]软件安装
  • [CF]Codeforces Round #551 (Div. 2)
  • [LeetCode]—Anagrams 回文构词法
  • [Linux_IMX6ULL应用开发]-Makefile
  • [NOI2005]月下柠檬树[计算几何(simpson)]
  • [ssh]如何设计ARM板上多用户key登录系统
  • [UDS] --- RoutineCommunicationControl 0x31