MyBatis的关联关系 一对一 一对多 多对多
程序员文章站
2022-04-22 08:01:00
...
一个妻子对应一个丈夫
数据库表设计时 在妻子表中添加一个丈夫主键的作为外键
1 对应的JavaBean代码
虽然在数据库里只有一方配置的外键,但是这个一对一是双向的关系。
1数据库表的设计 手机表 作为 子表 有人 表 里的主键 作为外键
2.一对多查询功能的实现
数据库表设计时 在妻子表中添加一个丈夫主键的作为外键
1 对应的JavaBean代码
虽然在数据库里只有一方配置的外键,但是这个一对一是双向的关系。
Husband实体类
public class Husband implements Serializable{
private int hid;
private String hname;
private Wife wife;
setter/getter...
}
wife 实体类
public class Wife implements Serializable{
private int wid;
private String wname;
private Husband husband;
setter/getter...
}
Dao 接口
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>
一对多
示例 : 一个人有 多个手机1数据库表的设计 手机表 作为 子表 有人 表 里的主键 作为外键
2 实体类的设计
Person 类
public class Person {
private int pid;
private String pname;
private List<Phone> pList;
setter/getter...
}
Phone 类
public class Phone {
private int tid;
private String tname;
private Person person;
setter/getter...
}
一对多 演示两个操作 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>
批量插入操作功能实现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.一对多查询功能的实现
定义 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建立一对一的关系