写在前面:时间过得真快
数据库的sql懒得传了
关系型数据库中,表与表之间的联系可以分为:
- 一对一(1:1)
- 一对多(1:n 或 n:1)
- 多对多(n:m )
那么如何进行一对多的查询呢?
-
分析数据
观察 student 表和 department 表,两个表之间的关系是一对多联系,即一个系里有多位学生。
department表:
student表:
-
创建两个表的实体类
可以通过 IDEA 自动地创建 student 表和 department 表的实体类,注意一下_下划线创建出来后面跟的字母是大写… -
修改Department 实体类
由于department到student是一对多,因此添加一个 List<Student> students 属性,为该属性生成相应的 get/set 方法,举一反三一下,如果是多对一的关系,就不用创建List了,创建多对一关系中一的实体就行了。 -
在 DepartmentMapper.xml 中定义 resultMap 标签
<!--配置 1 对多 结果集映射-->
<resultMap id="departmentMap" type="com.yyz.bean.Department">
<!--主键-->
<id property="dept_name" column="dept_name"/>
<result property="building" column="building"/>
<result property="budget" column="budget"/>
<!--配置一对多关系 “一个系包含多个学生 -->
<collection property="students" ofType="com.yyz.bean.Student">
<id property="id" column="ID"/>
<result property="name" column="name"/>
<result property="deptName" column="dept_name"/>
<result property="totCred" column="tot_cred"/>
</collection>
</resultMap>
好嘞,resultMap这个地方就有的讲了,
- resultMap标签,是进行多表查询的查询结果集说明
- resultMap中id属性:给结果集命名,要唯一,这个命名是用在具体sql语句标签的resultMap中的,如resultMap=“departmentMap”
- resultMap中type属性,对应相应的实体类,一对多关系中一的那个实体类
resultMap标签下又有三类标签,分别是
- id 定义该实体类的主键,属性有property和column,property定义在实体类中的主键的属性名,column定义在关系表中的主键的字段名
- result定义实体类的普通属性,属性说明和id的属性一致
- collection 定义一对多关系中多方的数据集合,property多方集合在实体类中对应属性名字,ofType定义对应的实体类。
collection下的标签同样是id和result,与resultMap下的id和result说明一致,与collection标签类似地,还有association标签,不过定义的是定义一对一关系,ofType也改叫javaType。
- 写具体查询语句
关联表的查询
<select id="getAllDept_Studs" resultMap="departmentMap">
SELECT S.*,D.*
FROM student S ,department D
WHERE S.dept_name=D.dept_name
</select>
- 创建接口
命名与xml一致,DepartmentMapper.java,注意接口方法与select标签与id一致
List<Department> getAllDept_Studs();
- 主配置文件关联局部SQL映射配置文件
为了方便,使用package标签,将mapper.xml所在的包进行自动扫描,不用再手动添加很多行mapper resource了,还能优化的地方就是给指定包下的类名取别名,简写成类名即可,不用再写包名了。
<mappers>
<!--<mapper resource="com/yyz/mapper/DepartmentMapper.xml"/>-->
<package name="com.yyz.mapper"/>
</mappers>
同样是在主配置文件中,properties标签下添加typeAliases标签
<properties resource="database.properties"/>
<typeAliases>
<package name="cn.java.bean"/>
</typeAliases>
- 测试
使用SqlSession的getMapper反射实例化接口的实现类departmentMapper,调用方法,打印输出。
public class DepartmentService {
SqlSession session;
DepartmentMapper departmentMapper;
@Before
public void init() throws IOException {
session = MybatisUtil.getSession();
departmentMapper = session.getMapper(DepartmentMapper.class);
}
@Test
public void getAllDept_Studs() throws IOException {
List<Department> departments = departmentMapper.getAllDept_Studs();
for (Department department : departments){
System.out.println(department);
}
}
}
测试出现 Invalid bound statement错误,进行检测:
-
检查Mapper.java文件和Mapper.xml文件名是否一致
-
检查xml文件的namespace是否正确
-
Mapper.java的方法与Mapper.xml中的是否一致
-
xxxMapper.java的方法返回值是List,而select元素没有正确配置ResultMap,或者只配置ResultType
-
如果你确认没有以上问题,请任意修改下对应的xml文件,比如删除一个空行,保存.问题解决
-
看下mapper的XML配置路径是否正确
输出结果: