配置映射关系前需先了解:
IDEA搭建mybatis框架DEMO
和
Mybatis注解和配置SQL操作定义
Mybatis映射关系主要有以下三种:
- 一对多
- 多对一
- 多对多
这里以商品(goods)和商品类型(type)为代表,产品类型和产品就是典型的一对多关系;
产品表
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>
在一方(商品类型)中的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中定义映射结果
<mapper namespace="com.tung.mapper.TypeMapper">
<resultMap id="typeResultMap" type="typeAlias">
<id property="id" column="id"/>
<id property="name" column="name"/>
<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 商品映射文件
<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 映射接口上使用注解商品映射接口
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.1 商品映射文件
<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.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"/>
以学生和课程为例。学生和课程就是典型的多对多关系。
在数据库设计中,多对多的关系是通过一个中间表来记录两边主键来实现的。
学生表
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.1 定义映射接口
public interface StudentMapper {
List<Student> selectAllStudents();
}
3.2.2 创建学生映射文件
<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.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>