Mybatis 基础进阶 一对多 多对多关系

本文介绍了如何使用Mybatis在Mapper XML文件中实现一对多和多对多的关系配置,包括person表和orders表的实体类、接口设置,以及配置文件中的别名添加。此外,还讲解了多对多关系中群组表和中间表的创建过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mapper XML 文件

使用xml文件实现 一些常用的查询操作

  1. 准备工作 一张person 表
create table person
(
  id      int auto_increment
    primary key,
  name    varchar(100) null,
  address varchar(100) null,
  sex     varchar(10)  null,
  age     int          null
)

2.实体类
3.接口 PersonDao.java
4. PersonDao.xml
5.在configuration.xml配置文件中添加一行别名 方便我们下面的配置

<typeAliases>
        <!--扫描该目录下的包 该包下的所有实体类 都可以使用别称 类名 类名大小写不敏感
            或者使用 注解形式 @Alias("person")
-->
        <package name="com/james/bean"></package>
    </typeAliases>

<select>

// 根据用户id 查询 用户
 public Person SelectPersonById(int id);
 // parameterType 传入参数类型 一般我们可以不写 mybatis内部会进行类型推断
 // resultType 是返回值类型 一般是全限定类名 但是上面我们起了别称 这里只需要使用类名就行
 <select id="SelectPersonById"  parameterType="int" resultType="Person">
        <include refid="selectPerson"/> where id = #{id}
    </select>

Test.java

@Test
    public void testMain() throws Exception {
        // 构造器
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 读取配置文件
        InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 获取会话工厂
        SqlSessionFactory factory = builder.build(input);
        // 获取会话
        SqlSession session = factory.openSession();

        PersonDao dao = session.getMapper(PersonDao.class);
        System.out.println(dao.SelectPersonById(8));
    }

<select>

 // 根据多个id 查询person
    public List<Person> selectPersonByIds(List<Integer> list);

// resultType 虽然返回值是List类型 但是这里使用类名 因为mybatis已经帮我们处理好了集合类型
// 因此直接添加集合中的类型即可
// foreach 标签被遍历的集合
         collection 指定的类型
         item 每一次遍历得到的对象
         separator 分隔符
         open 开始
         close 结束
<select id="selectPersonByIds" parameterType="java.util.List" resultType="Person">
        select * from person where id in
        <foreach collection="list" item="i" separator="," open="(" close=")">
            #{i}
        </foreach>

    </select>

Test.java

 @Test
    public void testMain3() throws Exception {
        // 构造器
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 读取配置文件
        InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 获取会话工厂
        SqlSessionFactory factory = builder.build(input);
        // 获取会话
        SqlSession session = factory.openSession();
        PersonDao dao = session.getMapper(PersonDao.class);
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(6);
        List<Person> lists = dao.selectPersonByIds(list);
        System.out.println(lists);
    }
// 根据姓名和性别同时查询
    public List<Person> getPerson(Person person);
    <!-- 动态sql
        where 标签作用 执行内部逻辑并拼接到外部sql中 会自动删除第一个and
    -->
    <select id="getPerson" parameterType="Person" resultType="Person">
        select * from person
        <where>
        <if test="name != null and name != '' ">
            and name = #{name}
        </if>
        <if test="sex != null and sex != '' ">
            and sex = #{sex}
        </if>
    </where>
    </select>
    // test 方法不在演示

mybatis 实现 一对多 与 多对一关系

准备一张orders 表

create table orders
(
  id       int auto_increment
    primary key,
  name     varchar(100) null,
  price    double       null,
  date     date         null,
  personid int          null,
  constraint orders_person_id_fk
  foreign key (personid) references person (id)
    on update cascade
    on delete cascade
)

创建orders的实体类

 // 获取所有订单
    public List<Orders> getAllOrder();

 // 获取所有人
 public List<Person> getAllPerson();

<?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.lanou.dao.OrdersDao">
    <!-- 当数据库列名 与 属性列名 不对应时 就使用resultMap 来手动映射
            id 要映射命名空间中的一个唯一标识,用于标识一个result map
            type 类的完全限定名, 或者一个类型别名
            autoMapping 如果设置这个属性,MyBatis将会为这个ResultMap开启或者关闭自动映射
-->
    <resultMap id="OrdersNap" type="Orders" autoMapping="true">
        <!-- 把o_name 的值映射到name属性上
             当两张表的字段相同时 在查询的时候容易将字段混淆
             因此可以用result 字段手动将要显示的字段映射到查询中
             所有在建立表结构的时候尽量做到表名不重复
-->
        <result property="name" column="o_name"></result>
        <result property="id" column="o_id"></result>
        <!-- 多对一 关系 association 用来映射关联对象 将关联的对象映射到结果集中
                property 是多表方的属性名 javaType 是 泛型类名
-->
        <association property="person" autoMapping="true" javaType="Person"></association>
    </resultMap>
    <!-- resultMap 上面对应的id 这里resultType 可以省略 官方不建议写-->
    <select id="getAllOrder" resultType="Orders" resultMap="OrdersNap">
        select *,orders.name o_name,orders.id o_id from person right join orders on person.id = orders.personid
    </select>
<! -- 一对多关系 注意:autoMapping 一定不要忘记写-->
    <resultMap id="PersonMap" type="Person" autoMapping="true">
        <result property="name" column="p_name"></result>
        <result property="id" column="p_id"></result>
        // 一对多关系使用 collection 字段
        <collection property="orders" autoMapping="true" ofType="Orders">
            <result property="name" column="o_name"></result>
            <result property="id" column="o_id"></result>
        </collection>
    </resultMap>

    <select id="getAllPerson" resultMap="PersonMap" resultType="Person">
        select *,person.name p_name,person.id p_id,orders.name o_name,orders.id o_id
        from person left join orders on person.id =  orders.personid
    </select>
</mapper>

@Test
    public void testMain4() throws Exception {
        // 构造器
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 读取配置文件
        InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 获取会话工厂
        SqlSessionFactory factory = builder.build(input);
        // 获取会话
        SqlSession session = factory.openSession();

        OrdersDao dao = session.getMapper(OrdersDao.class);
        List<Orders> list = dao.getAllOrder();
        for (Orders od : list) {
            System.out.println(od);
        }

    }

多对多关系

1.创立一个群组表

create table groups
(
  g_id     int auto_increment
    primary key,
  g_name   varchar(100) null,
  g_msg    varchar(100) null,
  g_manage varchar(100) null
)

创立一个中间表

create table group_person
(
  g_id int null,
  p_id int null,
  constraint group_person_groups_g_id_fk
  foreign key (g_id) references groups (g_id)
    on update cascade
    on delete cascade,
  constraint group_person_person_id_fk
  foreign key (p_id) references person (id)
    on update cascade
    on delete cascade
)

<?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.lanou.dao.GroupsDao">
    <!-- 这里的标签属性和上面类似 -->
    <resultMap id="GroupsMap" type="Groups" autoMapping="true">
        <collection property="person" autoMapping="true" ofType="Person"></collection>
    </resultMap>

    <select id="selectAllGroups" resultType="Groups" resultMap="GroupsMap">
        select * from groups left join group_person on group_person.g_id = groups.g_id
          left join person on group_person.p_id = person.id;
    </select>

    <resultMap id="PersonMap" type="Person" autoMapping="true">

        <collection property="groups" autoMapping="true" ofType="Groups"></collection>
    </resultMap>

    <select id="selectAllPerson" resultType="person" resultMap="PersonMap">
          select * from person left join group_person g on person.id = g.p_id
  left join groups g2 on g.g_id = g2.g_id;

    </select>
</mapper>

 @Test
    public void test() throws IOException {
        // 构造器
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 读取配置文件
        InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 获取会话工厂
        SqlSessionFactory factory = builder.build(input);
        // 获取会话
        SqlSession session = factory.openSession();

        GroupsDao dao = session.getMapper(GroupsDao.class);
        List<Person> list = dao.selectAllPerson();
        for (Person person :list){
            System.out.println(person);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值