mybatis关联映射

1,MyBatis的关联映射

MyBatis的关联映射有两种实现方式:

    1. 嵌套查询:通过执行另一个SQL语来返回关联数据(查询两次)
    1. 嵌套结果查询:执行另一个表关联查询SQL,然后将查询结果映射成关联对象(查询一次)

1.1 主键映射

在插入操作时,返回自动递增的主键值

<id column="字段名" jdbcType="对应类型" property="实体类属性名" />
1.1.1 MySql数据库支持自动递增
<insert id="save" parameterType="Dept" useGeneratedKeys="true" keyProperty="deptno">
			insert into dept values(#{deptno},#{dname})
</insert>
  • 在<insert>标签指定自动递增属性设置后,MyBatis会在插入操作后将自动递增生成的主键值给KeyProperty。
1.1.2 Oracle数据库:

Oracle数据库不支持主键自增,需要采用序列(队列)生成主键值

	<insert id="save" parameterType="Dept">
	<!-- 先从虚表中查询到下一个值,然后插入表中 -->
		<selectKey keyProperty="deptno" resultType="java.lang.Integer"> 
			select dept_sequence.nextval from dual
		</selectKey>
			insert into dept values(#{deptno},#{dname})
	</insert>	
  • 在<insert>标签中指定设置,MyBatis会在插入操作前,先执行获取主键值的SQL语句,再去执行插入的sql语句。

1.2 一对一映射

主表中的记录在关联表中有且只有一条记录与之对应

  • 准备数据:
	//创建老师表
	create table teacher(
	t_id int(4) primary key auto_increment,
	t_name varchar(10) not null
	);
	//创建学生表
	create table class(
	c_id int(2) primary key auto_increment,
	c_name varchar(20),
	teacher_id int(4)
	);
	//外键约束
	alter table class add constraint fk_teacher_id
	foreign key(teacher_id) references teacher(t_id);
	//插入数据
	insert into teacher (t_name) values("凯莎");
	insert into teacher (t_name) values("卡尔");
	----------------------------------------------
	insert into class(c_name,teacher_id) values("天使军团",1);
	insert into class(c_name,teacher_id) values("饕餮军团",2);
1.2.1 嵌套查询
	<!-- 一对一嵌套查询 -->
	<select id="findClassByIdOne" parameterType="integer" resultMap="">
		select * from class where c_id=#{id}
	</select>
	<resultMap type="Class" id="classMapperOne">
		<id property="id" column="c_id" />
		<result property="name" column="c_name" />
		<result property="teacherId" column="teacher_id" />
		<association property="teacher" column="teacher_id"
			javaType="Teacher" select="findTeacher" />
	</resultMap>
	<select id="findTeacher" parameterType="integer" resultMap="teacherMapperOne">
		select * from teacher where t_id=#{id}
	</select>
	<resultMap type="Teacher" id="teacherMapperOne">
		<id property="id" column="t_id" />
		<result property="name" column="t_name" />
	</resultMap>
1.2.2 嵌套结果查询
	<!-- 一对一嵌套结果查询 -->
	<select id="findClassByIdTwo" parameterType="integer" resultMap="classMapperTwo">
		select c.*,t.* from class c join teacher t on c.teacher_id=t.t_id
		where
		c_id=#{id}
	</select>
	<resultMap type="Class" id="classMapperTwo">
		<id property="id" column="c_id" />
		<result property="name" column="c_name" />
		<result property="teacherId" column="teacher_id" />
		<association property="teacher" column="teacher_id"
			javaType="Teacher">
			<id property="id" column="t_id" />
			<result property="name" column="t_name" />
		</association>
	</resultMap>

1.3 一对多映射

主表中的一条记录在关联表中有多条记录(一对多);
例如:一个班级对应多个学生

1.3.1 嵌套查询
	<!-- 一对多嵌套查询 -->
	<select id="findDeptByDeptnoOne" parameterType="integer"
		resultMap="deptMapOne">
		select * from dept where deptno=#{deptno}
	</select>
	<resultMap type="Dept" id="deptMapOne">
		<id property="deptno" column="deptno" />
		<collection property="emps" column="deptno" javaType="java.util.ArrayList"
			ofType="Emp" select="findEmps" />
	</resultMap>
	<select id="findEmps" parameterType="integer" resultType="Emp">
		select
		* from emp where deptno=#{deptno}
	</select>
1.3.2 嵌套结果查询

在嵌套结果查询中,即使实体类属性名与字段名一致,也不会进行自动映射。

  • 解决:
  1. 增加autoMapping=“true”属性并设置值为true;
<collection property="emps" column="deptno" javaType="java.util.ArrayList" ofType="Emp" autoMapping="true"/>
  1. 自己手动去关联映射
	<id property="deptno" column="deptno"/>
	<result property="dname" column="dname"/>
	...

示例:

<!-- mapper.xml配置 -->
	<!-- 一对多嵌套结果查询 -->
	<select id="findDeptByDeptnoTwo" parameterType="integer" resultMap="deptMapperTwo">
		select d.* ,e.*
		from dept d join emp e on d.deptno=e.deptno where
		d.deptno=#{deptno}
	</select>
	<resultMap type="Dept" id="deptMapperTwo">
		<id property="deptno" column="deptno"/>
		<result property="dname" column="dname"/>
		<collection property="emps" column="deptno" javaType="java.util.ArrayList" ofType="Emp" autoMapping="true"/>
	</resultMap>

1.4 多对一映射

表中多条记录对应关联表中一条记录(相当于一对多的反过来),将一对多关联中的主表与关联表交换位置后,描述此时的关系即为多对一。

1.4.1 嵌套查询
<!-- 多对一嵌套查询 -->
	<select id="findEmpByEmpnoOne" parameterType="integer"
		resultMap="empMapOne">
		select * from emp where empno=#{empno}
	</select>
	<resultMap type="Emp" id="empMapOne">
		<result property="deptno" column="deptno" />
		<association property="dept" column="deptno" javaType="Dept"
			select="findDept" />
	</resultMap>
	<select id="findDept" parameterType="integer" resultType="Dept">
		select
		* from dept where deptno=#{deptno}
	</select>
1.4.2 嵌套结果查询
<!-- 多对一嵌套结果查询 -->
	<select id="findEmpByEmpnoTwo" parameterType="integer"
		resultMap="empMapTwo">
		select e.*,d.* from emp e  inner join dept d on e.deptno=d.deptno
		where e.empno=#{empno}
	</select>
	<resultMap type="Emp" id="empMapTwo" autoMapping="true">
		<result property="deptno" column="deptno" />
		<association property="dept" column="deptno" javaType="Dept"
			autoMapping="true"/>
	</resultMap>

1.5 多对多映射

  • 主表中的一条记录在关联表中有多条记录与之关联。
  • 关联表中的一条记录在主表中有多条记录与之关联。
  • 存在一张中间表来描述多对多的关联关系。
    例如:
    1. 一个学生可以选择多个课程
    2. 一门课程可以被多个学生选择
  • 准备数据:
	//学生表
	create table students(
	s_id int(4) primary key auto_increment,
	s_name varchar(20) not  null
	);
	//课程表
	create table course(
	c_id int(4) primary key auto_increment,
	c_name varchar(20) not null
	);
	//中间表描述学生与课程的关系
	create table  student_course(
	student_id int(4),
	course_id int(4)
	);
	//插入数据
	insert  into students(s_name) values("彦"),("炙心"),("葛小伦"),("赵信");
	insert into course(c_name) values("银河之力"),("天使审判"),("绝影神枪"),("银翼之刃"),("雄心"),("黑甲"),("太阳之力");
	insert into student_course values(1,4),(1,2),(2,1),(3,1),(3,5),(4,3),(1,7),(2,6),(3,6),(4,6);
1.5.1 嵌套查询
<!-- 多对多嵌套查询 -->
	<select id="findByStudentIdOne" parameterType="integer"
		resultMap="stuMapOne">
		select * from students where s_id=#{id}
	</select>
	<resultMap type="Student" id="stuMapOne">
		<id column="s_id" property="id" />
		<result column="s_name" property="name" />
		<collection property="courses" column="s_id" javaType="java.util.ArrayList"
			ofType="Course" select="findCourse" />
	</resultMap>
	<select id="findCourse" parameterType="integer" resultMap="courseMap">
		select c.*
		from student_course sc join course c
		on sc.course_id=c.c_id
		where sc.student_id=#{id}
	</select>
	<resultMap type="Course" id="courseMap">
		<id property="id" column="c_id" />
		<result property="name" column="c_name" />
	</resultMap>
1.5.2 嵌套结果查询
<!-- 嵌套结果查询 -->
	<select id="findByStudentIdTwo" parameterType="integer"
		resultMap="stuMapTwo">
		select st.* ,c.*
		from students st join student_course sc on
		st.s_id=sc.student_id join
		course c on sc.course_id=c.c_id where
		st.s_id=#{id}
	</select>
	<resultMap type="Student" id="stuMapTwo">
		<id property="id" column="s_id" />
		<result property="name" column="s_name" />
		<collection property="courses" column="s_id" javaType="java.util.ArrayList"
			ofType="Course">
			<id property="id" column="c_id" />
			<result property="name" column="c_name" />
		</collection>
	</resultMap>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值