Mybatis第五讲——关联一对多

Mybatis第四讲——关联一对一(2)

 目录结构:

数据表:

t_grade:

t_student:

t_address:

主外键关联关系:

Grade 实体类:

package com.java1234.model;

import java.util.List;

public class Grade {

	private Integer id;
	private String gradeName;
	private List<Student> students;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getGradeName() {
		return gradeName;
	}
	public void setGradeName(String gradeName) {
		this.gradeName = gradeName;
	}
	public List<Student> getStudents() {
		return students;
	}
	public void setStudents(List<Student> students) {
		this.students = students;
	}
	@Override
	public String toString() {
		return "Grade [id=" + id + ", gradeName=" + gradeName + ", students=" + students + "]";
	}
	
	
}

GradeMapper.java:

package com.java1234.mappers;

import com.java1234.model.Grade;

public interface GradeMapper {
	public Grade findGradeById(Integer id);
}

GradeMapper.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.java1234.mappers.GradeMapper">
	
	<resultMap type="Grade" id="gradeResult">
	 	<result property="id" column="id"/>
		<result property="gradeName" column="gradeName"/>
		<collection property="students" column="id" select="com.java1234.mappers.StudentMapper.getStudentByGradeId"></collection>
	</resultMap>
	
<select id="findGradeById" resultMap="gradeResult">
select * from t_grade where id=#{id}
</select>
</mapper> 

 StudentMapper.java:

与上一讲相比,添加了getStudentByGradeId()函数接口。

StudentMapper.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.java1234.mappers.StudentMapper">

	<insert id="add" parameterType="Student"  >
		insert into t_student values(null,#{name},#{age})
	</insert>
	
	<delete id="delete" parameterType="Integer">
	 delete from t_student where id=#{id}
	</delete>
	
	<update id="update" parameterType="Student">
	update t_student set name=#{name},age=#{age} where id=#{id}
	</update>
	
	<select id="getStudentById" parameterType="Integer" resultType="Student">
	select * from t_student where id=#{id}
	</select>

    <select id="getStudentByGradeId" parameterType="Integer" resultType="Student">
	select * from t_student where gradeId=#{gradeId}
	</select>
	
	<resultMap type="Student" id="StudentResult">
		<id property="id" column="id"/>
		<result property="name" column="name"/>
		<result property="age" column="age"/>
		
		<association property="address" column="addressId" select="com.java1234.mappers.AddressMapper.findAddressById"/>
	</resultMap> 
	
	<select id="getAllStudents" resultMap="StudentResult">
	select * from t_student 
	</select>
	
	<select id="findStudentWithAddress" resultMap="StudentResult" parameterType="Integer">
	select * from t_student t1,t_address t2 where t1.addressId=t2.id and t1.id=#{id} 
	</select>
</mapper> 

主要是添加了getStudentByGradeId函数的SQL实现:

 

测试类:

package com.java1234.service;

import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.java1234.mappers.GradeMapper;
import com.java1234.model.Grade;
import com.java1234.util.SqlSessionFactoryUtil;

public class GradeTest {
	private SqlSession sqlSession=null;
	private GradeMapper gradeMapper=null;
	@BeforeEach
	void setUp() throws Exception {
		sqlSession=SqlSessionFactoryUtil.openSession();
		gradeMapper=sqlSession.getMapper(GradeMapper.class);
	}

	@AfterEach
	void tearDown() throws Exception {
		sqlSession.close();
	}
	

	/**
	 * 通过gradeId获取学生信息
	 */
	@Test
	void getStudentByGradeId() {
		Grade grade=gradeMapper.findGradeById(1);
		System.out.println(grade);
	}
}

输出:

Grade [id=1, gradeName=大学一年级, students=[Student [id=1, name=张三, age=22, address=null], Student [id=4, name=王五, age=33, address=null]]]

这里address为空,有点问题,不过和我们这讲的一对多无关,暂且放下,后续再解决。

 

### 后台管理系统中的关联设计与实现 #### 1. 数据库设计原则 在后台管理系统中,关联的设计至关重要。为了确保数据库结构合理并支持高效的查询和更新操作,通常遵循第三范式(3NF),即消除冗余存储的数据,使每个非主属性完全依赖于候选键[^1]。 #### 2. 关联关系类型 常见的关联分为三种主要类型: - **一对关联** 这种情况下两个实体之间存在唯一对应的关系。例如,用户与其个人资料之间的联系。可以在任意一张表内设置外键字段指向另一张表的主键来表示这种关系[^2]。 - **一对/对一关联** 当一方可以拥有个对方实例时形成此类关联。比如部门与员工间的映射——一个部门可容纳名雇员;反之亦然,则为对一。一般通过在外侧加入外键完成建模[^3]。 - **关联** 如果双方都能与其他方建立重连接,则需引入中间件作为桥梁。以课程选修为例,每位同学可以选择若干门课目而每门科目也可能被位学员选取。此时应创建额外的一张表格保存两者间具体的配对情况[^4]。 ```sql CREATE TABLE students_courses ( student_id INT NOT NULL, course_id INT NOT NULL, PRIMARY KEY (student_id, course_id), FOREIGN KEY (student_id) REFERENCES students(id), FOREIGN KEY (course_id) REFERENCES courses(id) ); ``` #### 3. ORM 映射配置 当采用对象关系映射(ORM)工具如 Hibernate 或 MyBatis 来简化 Java 应用程序同 SQL Server 的交互过程时,需要正确设定实体类及其相互作用模式。针对上述提到的不同种类的关联形式,相应调整 `@OneToOne`、`@OneToMany` 和 `@ManyToMany` 注解参数即可达成目的[^5]。 ```java @Entity public class Department { @Id private Long id; @OneToMany(mappedBy="department") private Set<Employee> employees; } ``` #### 4. 查询优化策略 随着应用规模扩大以及并发请求增,性能瓶颈往往出现在频繁读取大量关联数据上。为此建议采取如下措施提升响应速度: - 使用懒加载机制延迟获取不必要的子集; - 对常用组合条件建立索引加速检索流程; - 尽量减少嵌套层次过的级联操作次数; - 利用缓存技术减轻服务器负担等手段改善整体表现[^6]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员资料站

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值