MyBatis之配置映射关系

配置映射关系前需先了解:
IDEA搭建mybatis框架DEMO

Mybatis注解和配置SQL操作定义

Mybatis映射关系主要有以下三种:

  • 一对多
  • 多对一
  • 多对多

一、配置一对多

这里以商品(goods)和商品类型(type)为代表,产品类型和产品就是典型的一对多关系;

1.1 环境准备

  • 创建数据表

产品表

create table goods(
	id int primary key auto_increment comment '商品编号',
	name varchar(255) not null default '' comment '商品名称',
	price int not null default 0 comment '价格',
	tid int not null comment '类别编号'
);

商品类型表

create table type (
	id int primary key auto_increment comment '商品类型编号',
	name varchar(255) not null default '' comment '类型名称'
);
  • 初始化数据
insert into type(name)
values('家电');
insert into type(name)
values('文具');

insert into goods(name, price, tid)
values('电视机', 3999, 1);
insert into goods(name, price, tid)
values('吸尘器', 1999, 1);
insert into goods(name, price, tid)
values('铅笔', 1, 2);

  • 定义实体类

商品:

//商品表
public class Goods {
    private Integer id;
    private String name;
    private Integer price;
    private Integer tid;
// 省略了setters和getters方法...
}

商品类型:

//商品类型
public class Type {
    private Integer id;
    private String name;
    private Set<Goods> GoodsSet= new HashSet<>();
// 省略了setters和getters方法...
}
  • 定义别名

在mybatis-config中定义类的别名

<typeAliases>
	<typeAlias type="com.tung.bean.Goods" alias="goodsAlias"/>
	<typeAlias type="com.tung.bean.Type" alias="typeAlias"/>
</typeAliases>

1.2 配置文件中配置关系

在一方(商品类型)中的ResultMap的collection节点指定要执行关联查询的sql语句
1.2.1 定义映射接口
TypeMapper接口

public interface TypeMapper {
    Type selectTypeById(Integer id);
}

GoodsMapper接口

public interface GoodsMapper {
    List<Goods> selectGoodsByTid(Integer tid);
}

1.2.2 商品类型映射文件
在映射接口TypeMapper对应的配置文件TypeMapper.xml中定义映射结果

<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.tung.mapper.TypeMapper">
    <!--  映射结果集  -->
    <resultMap id="typeResultMap" type="typeAlias">
        <id property="id" column="id"/>
        <id property="name" column="name"/>
        <!-- 配置一对多的关系 
				property:集合的属性名
				ofType:集合元素的类型
				column:当前实体对应表的主键名
				select:指定关联查询的SQL语句
				fetchType: 指定是否延迟加载,lazy代表延迟加载,eager代表不延迟加载
		-->
        <collection property="GoodsSet" ofType="goodsAlias" column="id" select="com.tung.mapper.GoodsMapper.selectGoodsByTid"/>

    </resultMap>

    <select id="selectTypeById" resultMap="typeResultMap">
            select * from type where id=#{id}
        </select>

</mapper>

因为Type实体中包含goods集合属性,该集合用于存储该类别下的商品。所以,在ResultMap中使用collection节点映射集合属性。

1.2.3 商品映射文件

<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.tung.mapper.GoodsMapper">
    <select id="selectGoodsByTid" parameterType="int" resultType="goodsAlias">
        select * from goods where tid=#{tid}
    </select>
</mapper>

1.2.4 配置映射文件
在mybatis-config中配置映射文件

<mappers>
    <mapper resource="TypeMapper.xml"/>
    <mapper resource="GoodsMapper.xml"/>
</mappers>

1.2.5 测试

@Test
    public void test(){
        System.out.println("测试开始");
        try {
            //使用MyBatis提供的Resources类加载mybatis的配置文件
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            //构建sqlSession的工厂
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //通过SqlSessionFactory对象获取SqlSession对象。
            SqlSession session= sessionFactory.openSession();
            TypeMapper mapper=session.getMapper(TypeMapper.class);
            Type type = mapper.selectTypeById(1);
            System.out.println(type.getName());
            for(Goods goods:type.getGoodsSet()){
                System.out.println(goods.getName());

            }



            //提交事务
            session.commit();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

执行结果:
在这里插入图片描述

1.3 使用注解配置关系

1.3.1 映射接口上使用注解商品映射接口

public interface GoodsMapper {
    @Select("select * from goods where tid = #{tid}")
    @Results(value ={
            @Result(property = "id",column = "id"),
            @Result(property = "name",column = "name"),
            @Result(property = "price",column = "price")
    }
    )
    List<Goods> selectGoodsByTid(Integer tid);
}

商品类映射接口

public interface TypeMapper {
    @Select("select * from type where id=#{id}")
    @Results(value = {
            @Result(property = "id",column = "id"),
            @Result(property = "name",column = "name"),
            @Result(property = "GoodsSet",column = "id",many = @Many(select = "com.tung.mapper.GoodsMapper.selectGoodsByTid"))
    })
    Type selectTypeById(Integer id);
}

1.3.2 配置映射类
在mybatis-config中配置映射类

<mapper class="com.tung.mapper.GoodsMapper"/>
<mapper class="com.tung.mapper.TypeMapper"/>

二、配置多对一

商品类型和商品是一对多的关系,反过来商品和商品类型是多对一的关系

2.1 配置文件中配置关系

2.1.1 商品映射文件

<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.tung.mapper.GoodsMapper">
	<!--配置返回集-->
    <resultMap id="goodsResultMap" type="goodsAlias">
        <id property="id" column="id"/>
        <id property="name" column="name"/>
        <id property="price" column="price"/>
        <association property="type" javaType="typeAlias">
            <id property="id" column="tid"/>
            <id property="name" column="tname"/>
        </association>
    </resultMap>
    <!--查询所有商品-->
    <select id="selectGoods" resultMap="goodsResultMap">
        select g.*,t.name as tname from goods g,type t where t.id=g.id
    </select>
</mapper>

也可以在assocation节点中使用select属性指定查询关联实体的接口方法。

<association property="type" javaType="typeAlias" column="tid"
		select="com.tung.mapper.TypeMapper.selectTypeById"/>

association节点的属性说明:
property:关联实体的属性名
javaType:关联实体的属性类型
column:外建名
select:执行关联查询的接口方法

2.1.2 配置映射文件

<mapper resource="GoodsMapper.xml"/>

2.2 使用注解配置关系

2.2.1 映射接口使用注解
商品接口

public interface GoodsMapper {
    @Select("select * from goods")
    @Results(value = {
            @Result(property = "id",column = "id"),
            @Result(property = "name",column = "name"),
            @Result(property = "price",column = "price"),
            @Result(property = "type",column = "tid",one = @One(select = "com.tung.mapper.TypeMapper.selectTypeById"))
    })
    List<Goods> selectGoods();
}

商品类型接口

public interface TypeMapper {
    @Select("select * from type where id =#{tid}")
    Type selectTypeById(Integer id);
}

2.2.2 配置映射类

<mapper class="com.tung.mapper.GoodsMapper"/>
<mapper class="com.tung.mapper.TypeMapper"/>

三、配置多对多

以学生和课程为例。学生和课程就是典型的多对多关系。

在数据库设计中,多对多的关系是通过一个中间表来记录两边主键来实现的。

3.1 环境准备

  • 创建数据表

学生表

create table student (
	id int primary key auto_increment comment '学生编号',
	name varchar(255) not null default '' comment '学生名字',
	gender tinyint(1) not null default 1 comment '学生性别,1代表男,2代表女',
	phone varchar(11) default '' comment '手机号码'
);

课程表

create table course (
	id int primary key auto_increment comment '课程编号',
	name varchar(255) not null default '' comment '课程名称'
);

学生选修表

create table student_course (
	stu_id int,
	course_id  int,
	primary key(stu_id, course_id)
);
  • 初始化数据
insert into student(name, gender, phone)
values('jacky', 1, '13522237843');
insert into student(name, gender, phone)
values('mickey', 1, '13622237843');
insert into student(name, gender, phone)
values('judy', 2, '13322237843');

ALTER TABLE course CONVERT to CHARACTER set utf8mb4; 
insert into course(name) values('外语');
insert into course(name)
values('计算机');

insert into student_course
values(1, 1);
insert into student_course
values(1, 2);
insert into student_course
values(2, 1);
insert into student_course
values(2, 2);
insert into student_course
values(3, 1);
  • 定义实体类

学生

public class Student {
	private Integer id;
	private String name;
	private Boolean gender;
	private String phone;
	private Set<Course> courses = new HashSet<Course>(0);

	// 省略了setters和getters方法..
}

课程

public class Course {
	private Integer id;
	private String name;
	private Set<Student> students = new HashSet<Student>(0);
	
	// 省略了setters和getters方法..
}
  • 定义别名
<typeAlias type="com.tung.bean.Student" alias="studentAlias"/>
<typeAlias type="com.tung.bean.Course" alias="courseAlias"/>

3.2 配置文件中配置关系

3.2.1 定义映射接口

public interface StudentMapper {
    List<Student> selectAllStudents();
}

3.2.2 创建学生映射文件

<?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.tung.mapper.StudentMapper">
    <resultMap id="StudentResultMap" type="studentAlias">
        <id property="id" column="id" />
        <id property="name" column="name" />
        <id property="gender" column="gender" />
        <id property="phone" column="phone" />
        <!-- 多表关联映射 -->
        <collection property="courses" ofType="courseAlias">
            <id property="id" column="cid"/>
            <result property="name" column="cname"/>
        </collection>
    </resultMap>

    <!-- 查询所有学生  -->
    <select id="selectAllStudents" resultMap="StudentResultMap">
		select s.*, c.id as cid, c.name as cname from student s, course c, student_course sc
		where s.id = sc.stu_id and c.id = sc.course_id;
	</select>

</mapper>

3.2.3 配置映射文件
在mybatis_config中配置映射文件

<mappers>
    <mapper resource="StudentMapper.xml"/>
</mappers>

3.3 使用注解配置关系

3.3.1 在映射接口中使用注解
StudentMapper文件

@Select("select * from student")
@Results({ 
    @Result(property="id", column="id"),
    @Result(property="name", column="name"),
    @Result(property="gender", column="gender"),
    @Result(property="phone", column="phone"),
    @Result(property="courses", column="id", many=@Many(
    		select="com.tung.mapper.CourseMapper.selectStudentCourses"))
})
List<Student> selectAllStudents();

CourseMapper文件

public interface CourseMapper {	
@Select("select c.* from course c, student_course sc where c.id = sc.course_id and sc.stu_id = #{studentId}")
List<Course> selectStudentCourses(int studentId);	
}

3.3.2 配置映射接口
修改mybatis-config.xml文件,配置映射接口。

<mappers>
	<mapper class="com.tung.mapper.StudentMapper"/>
	<mapper class="com.tung.mapper.CourseMapper"/>
</mappers>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值