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);
}
}
MyBatis的关联关系 一对一 一对多 多对多的更多相关文章
- mybatis 一对一 一对多 多对多
一对一 一对多 多对多
- JPA级联(一对一 一对多 多对多)注解【实际项目中摘取的】并非自己实际应用
下面把项目中的用户类中有个:一对一 一对多 多对多的注解对应关系列取出来用于学习 说明:项目运行正常 问题类:一对多.一对一.多对多 ============一对多 一方的设置 @One ...
- Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作
Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作,单表查询,多表查询 一丶表与表之间的关系 背景: 由于如果只使用一张表存储所有的数据,就会操作数 ...
- JPA 一对一 一对多 多对一 多对多配置
1 JPA概述 1.1 JPA是什么 JPA (Java Persistence API) Java持久化API.是一套Sun公司 Java官方制定的ORM 方案,是规范,是标准 ,sun公司自己并没 ...
- 使用NHibernate(7)-- 一对一 && 一对多 && 多对多
1, 一对一. 对于数据量比较大的时候,考虑查询的性能,肯能会把一个对象的属性分到两个表中存放:比如用户和用户资料,经常使用的一般是Id和用户名,用户资料(学校,籍贯等)是不经常被查询的,所以就会分成 ...
- day 69-70 一对一 一对多 多对一联表查询
day 69 orm操作之表关系,多对多,多对一 多对一/一对多, 多对多{类中的定义方法} day69 1. 昨日内容回顾 1. 单表增删改查 2. 单表查询API 返回QuerySet对象的: 1 ...
- Mybatis之关联关系(一对多、多对多)
目的: Mybatis关系映射之一对多 Mybatis关系映射之多对多 Mybatis关系映射之一对多 一对多 (订单对应多个订单项) 多对一 (订单项对应一个订单) 其是映射关系的基层思维是一样的 ...
- 初学者易上手的SSH-hibernate04 一对一 一对多 多对多
这章我们就来学习下hibernate的关系关联,即一对一(one-to-one),一对多(one-to-many),多对多(many-to-many).这章也将是hibernate的最后一章了,用于初 ...
- JAVA日记之mybatis-3一对一,一对多,多对多xml与注解配置
1.Mybatis多表查询1.1 一对一查询1.1.1 一对一查询的模型用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的 ...
随机推荐
- xjoi 2082: 小明的序列
本文为博主原创文章,未均允许…… 反正我也没法管对吧 www点cnblogs点com/AwD-/ 维护一个序列,初始全为\(1\) 支持两种操作: 1.对于所有的位置\(i\),将它的值乘上\(i + ...
- canvas——路径搜索
在前一篇博客中随机生成迷宫,现在就以随机生成的迷宫为地图,开始寻找路径. 迷宫寻路也可以使用DFS,BFS,但常见的是A*算法,它是启发式搜索算法的一种,效率相比前两者也更高.接下来以A*算法为例,迷 ...
- 咦,好像可以自己做个webapi框架了-IRouteHandler的使用
当我们学习到一定程度的时候,我们会想要去深入了解代码底层的东西,也更想拥有一个属于自己的框架,当然,博主也正是如此.本文可能成为编写一个webapi框架的开端.有研究MVC框架的朋友会发现,mvc框架 ...
- JavaMail API
JavaMail API的核心类:会话.消息.地址.验证程序.传输,存储和文件夹.所有这些类都可以在JavaMail API即javax.mail的顶层包中找到,尽管你将频繁地发现你自己使用的子类是在 ...
- SVN·最新使用教程总结
SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...
- 在WIN SERVER 2016上安装DOCKER(带过坑)
目录 1 概要 1 1.1 主要优势 1 2 在Windows Server上部署Docker 2 概要 博客使用Word发博,发布后,排版会出现很多问题,敬请谅解 ...
- asp.net core 教程(六)-中间件
Asp.Net Core-中间件 在这一章,我们将了解如何设置中间件.中间件技术在 ASP.NET Core中控制我们的应用程序如何响应 HTTP 请求.它还可以控制应用程序的异常错误,这是一个在如何 ...
- centos5.5下mangodb启动报错glibc
mangodb启动报错glibc找不到(centos5.5) 报错形式 [root@test-172-16-0-139-ip mongodb-server]# /data/mongodb-server ...
- string services
string通用字符串操作: re,正则表达式 difflib,比较序列 stringIO:以文件的方式来读和写字符串 CstringIO:更快捷的stringIO版本 textwrap:文本包装和填 ...
- C# 模拟浏览器请求
public string getHtml(string Url, string type = "UTF-8") { try ...